WebCore/xml/XPathResult.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
       
     3  * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
       
     4  *
       
     5  * Redistribution and use in source and binary forms, with or without
       
     6  * modification, are permitted provided that the following conditions
       
     7  * are met:
       
     8  * 
       
     9  * 1. Redistributions of source code must retain the above copyright
       
    10  *    notice, this list of conditions and the following disclaimer.
       
    11  * 2. Redistributions in binary form must reproduce the above copyright
       
    12  *    notice, this list of conditions and the following disclaimer in the
       
    13  *    documentation and/or other materials provided with the distribution.
       
    14  * 
       
    15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
       
    16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
       
    17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
       
    18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
       
    19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
       
    20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
       
    24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    25  */
       
    26 
       
    27 #include "config.h"
       
    28 #include "XPathResult.h"
       
    29 
       
    30 #if ENABLE(XPATH)
       
    31 
       
    32 #include "Document.h"
       
    33 #include "Node.h"
       
    34 #include "ExceptionCode.h"
       
    35 #include "XPathEvaluator.h"
       
    36 #include "XPathException.h"
       
    37 
       
    38 namespace WebCore {
       
    39 
       
    40 using namespace XPath;
       
    41 
       
    42 XPathResult::XPathResult(Document* document, const Value& value)
       
    43     : m_value(value)
       
    44 {
       
    45     switch (m_value.type()) {
       
    46         case Value::BooleanValue:
       
    47             m_resultType = BOOLEAN_TYPE;
       
    48             return;
       
    49         case Value::NumberValue:
       
    50             m_resultType = NUMBER_TYPE;
       
    51             return;
       
    52         case Value::StringValue:
       
    53             m_resultType = STRING_TYPE;
       
    54             return;
       
    55         case Value::NodeSetValue:
       
    56             m_resultType = UNORDERED_NODE_ITERATOR_TYPE;
       
    57             m_nodeSetPosition = 0;
       
    58             m_nodeSet = m_value.toNodeSet();
       
    59             m_document = document;
       
    60             m_domTreeVersion = document->domTreeVersion();
       
    61             return;
       
    62     }
       
    63     ASSERT_NOT_REACHED();
       
    64 }
       
    65 
       
    66 XPathResult::~XPathResult()
       
    67 {
       
    68 }
       
    69 
       
    70 void XPathResult::convertTo(unsigned short type, ExceptionCode& ec)
       
    71 {
       
    72     switch (type) {
       
    73         case ANY_TYPE:
       
    74             break;
       
    75         case NUMBER_TYPE:
       
    76             m_resultType = type;
       
    77             m_value = m_value.toNumber();
       
    78             break;
       
    79         case STRING_TYPE:
       
    80             m_resultType = type;
       
    81             m_value = m_value.toString();
       
    82             break;
       
    83         case BOOLEAN_TYPE:
       
    84             m_resultType = type;
       
    85             m_value = (unsigned long)(m_value.toBoolean());
       
    86             break;
       
    87         case UNORDERED_NODE_ITERATOR_TYPE:
       
    88         case UNORDERED_NODE_SNAPSHOT_TYPE:
       
    89         case ANY_UNORDERED_NODE_TYPE:
       
    90         case FIRST_ORDERED_NODE_TYPE: // This is correct - singleNodeValue() will take care of ordering.
       
    91             if (!m_value.isNodeSet()) {
       
    92                 ec = XPathException::TYPE_ERR;
       
    93                 return;
       
    94             }
       
    95             m_resultType = type;
       
    96             break;
       
    97         case ORDERED_NODE_ITERATOR_TYPE:
       
    98             if (!m_value.isNodeSet()) {
       
    99                 ec = XPathException::TYPE_ERR;
       
   100                 return;
       
   101             }
       
   102             m_nodeSet.sort();
       
   103             m_resultType = type;
       
   104             break;
       
   105         case ORDERED_NODE_SNAPSHOT_TYPE:
       
   106             if (!m_value.isNodeSet()) {
       
   107                 ec = XPathException::TYPE_ERR;
       
   108                 return;
       
   109             }
       
   110             m_value.toNodeSet().sort();
       
   111             m_resultType = type;
       
   112             break;
       
   113     }
       
   114 }
       
   115 
       
   116 unsigned short XPathResult::resultType() const
       
   117 {
       
   118     return m_resultType;
       
   119 }
       
   120 
       
   121 double XPathResult::numberValue(ExceptionCode& ec) const
       
   122 {
       
   123     if (resultType() != NUMBER_TYPE) {
       
   124         ec = XPathException::TYPE_ERR;
       
   125         return 0.0;
       
   126     }
       
   127     return m_value.toNumber();
       
   128 }
       
   129 
       
   130 String XPathResult::stringValue(ExceptionCode& ec) const
       
   131 {
       
   132     if (resultType() != STRING_TYPE) {
       
   133         ec = XPathException::TYPE_ERR;
       
   134         return String();
       
   135     }
       
   136     return m_value.toString();
       
   137 }
       
   138 
       
   139 bool XPathResult::booleanValue(ExceptionCode& ec) const
       
   140 {
       
   141     if (resultType() != BOOLEAN_TYPE) {
       
   142         ec = XPathException::TYPE_ERR;
       
   143         return false;
       
   144     }
       
   145     return m_value.toBoolean();
       
   146 }
       
   147 
       
   148 Node* XPathResult::singleNodeValue(ExceptionCode& ec) const
       
   149 {
       
   150     if (resultType() != ANY_UNORDERED_NODE_TYPE && resultType() != FIRST_ORDERED_NODE_TYPE) {
       
   151         ec = XPathException::TYPE_ERR;
       
   152         return 0;
       
   153     }
       
   154   
       
   155     const NodeSet& nodes = m_value.toNodeSet();
       
   156     if (resultType() == FIRST_ORDERED_NODE_TYPE)
       
   157         return nodes.firstNode();
       
   158     else
       
   159         return nodes.anyNode();
       
   160 }
       
   161 
       
   162 bool XPathResult::invalidIteratorState() const
       
   163 {
       
   164     if (resultType() != UNORDERED_NODE_ITERATOR_TYPE && resultType() != ORDERED_NODE_ITERATOR_TYPE)
       
   165         return false;
       
   166 
       
   167     ASSERT(m_document);
       
   168     return m_document->domTreeVersion() != m_domTreeVersion;
       
   169 }
       
   170 
       
   171 unsigned long XPathResult::snapshotLength(ExceptionCode& ec) const
       
   172 {
       
   173     if (resultType() != UNORDERED_NODE_SNAPSHOT_TYPE && resultType() != ORDERED_NODE_SNAPSHOT_TYPE) {
       
   174         ec = XPathException::TYPE_ERR;
       
   175         return 0;
       
   176     }
       
   177 
       
   178     return m_value.toNodeSet().size();
       
   179 }
       
   180 
       
   181 Node* XPathResult::iterateNext(ExceptionCode& ec)
       
   182 {
       
   183     if (resultType() != UNORDERED_NODE_ITERATOR_TYPE && resultType() != ORDERED_NODE_ITERATOR_TYPE) {
       
   184         ec = XPathException::TYPE_ERR;
       
   185         return 0;
       
   186     }
       
   187     
       
   188     if (invalidIteratorState()) {
       
   189         ec = INVALID_STATE_ERR;
       
   190         return 0;
       
   191     }
       
   192     
       
   193     if (m_nodeSetPosition + 1 > m_nodeSet.size())
       
   194         return 0;
       
   195 
       
   196     Node* node = m_nodeSet[m_nodeSetPosition];
       
   197     
       
   198     m_nodeSetPosition++;
       
   199 
       
   200     return node;
       
   201 }
       
   202 
       
   203 Node* XPathResult::snapshotItem(unsigned long index, ExceptionCode& ec)
       
   204 {
       
   205     if (resultType() != UNORDERED_NODE_SNAPSHOT_TYPE && resultType() != ORDERED_NODE_SNAPSHOT_TYPE) {
       
   206         ec = XPathException::TYPE_ERR;
       
   207         return 0;
       
   208     }
       
   209     
       
   210     const NodeSet& nodes = m_value.toNodeSet();
       
   211     if (index >= nodes.size())
       
   212         return 0;
       
   213     
       
   214     return nodes[index];
       
   215 }
       
   216 
       
   217 }
       
   218 
       
   219 #endif // ENABLE(XPATH)