2 * Copyright (C) 2005 Frerich Raabe <raabe@kde.org>
3 * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
28 #include "XPathResult.h"
34 #include "ExceptionCode.h"
35 #include "XPathEvaluator.h"
36 #include "XPathException.h"
40 using namespace XPath;
42 XPathResult::XPathResult(Document* document, const Value& value)
45 switch (m_value.type()) {
46 case Value::BooleanValue:
47 m_resultType = BOOLEAN_TYPE;
49 case Value::NumberValue:
50 m_resultType = NUMBER_TYPE;
52 case Value::StringValue:
53 m_resultType = STRING_TYPE;
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();
66 XPathResult::~XPathResult()
70 void XPathResult::convertTo(unsigned short type, ExceptionCode& ec)
77 m_value = m_value.toNumber();
81 m_value = m_value.toString();
85 m_value = m_value.toBoolean();
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;
97 case ORDERED_NODE_ITERATOR_TYPE:
98 if (!m_value.isNodeSet()) {
99 ec = XPathException::TYPE_ERR;
105 case ORDERED_NODE_SNAPSHOT_TYPE:
106 if (!m_value.isNodeSet()) {
107 ec = XPathException::TYPE_ERR;
110 m_value.toNodeSet().sort();
116 unsigned short XPathResult::resultType() const
121 double XPathResult::numberValue(ExceptionCode& ec) const
123 if (resultType() != NUMBER_TYPE) {
124 ec = XPathException::TYPE_ERR;
127 return m_value.toNumber();
130 String XPathResult::stringValue(ExceptionCode& ec) const
132 if (resultType() != STRING_TYPE) {
133 ec = XPathException::TYPE_ERR;
136 return m_value.toString();
139 bool XPathResult::booleanValue(ExceptionCode& ec) const
141 if (resultType() != BOOLEAN_TYPE) {
142 ec = XPathException::TYPE_ERR;
145 return m_value.toBoolean();
148 Node* XPathResult::singleNodeValue(ExceptionCode& ec) const
150 if (resultType() != ANY_UNORDERED_NODE_TYPE && resultType() != FIRST_ORDERED_NODE_TYPE) {
151 ec = XPathException::TYPE_ERR;
155 const NodeSet& nodes = m_value.toNodeSet();
156 if (resultType() == FIRST_ORDERED_NODE_TYPE)
157 return nodes.firstNode();
159 return nodes.anyNode();
162 bool XPathResult::invalidIteratorState() const
164 if (resultType() != UNORDERED_NODE_ITERATOR_TYPE && resultType() != ORDERED_NODE_ITERATOR_TYPE)
168 return m_document->domTreeVersion() != m_domTreeVersion;
171 unsigned long XPathResult::snapshotLength(ExceptionCode& ec) const
173 if (resultType() != UNORDERED_NODE_SNAPSHOT_TYPE && resultType() != ORDERED_NODE_SNAPSHOT_TYPE) {
174 ec = XPathException::TYPE_ERR;
178 return m_value.toNodeSet().size();
181 Node* XPathResult::iterateNext(ExceptionCode& ec)
183 if (resultType() != UNORDERED_NODE_ITERATOR_TYPE && resultType() != ORDERED_NODE_ITERATOR_TYPE) {
184 ec = XPathException::TYPE_ERR;
188 if (invalidIteratorState()) {
189 ec = INVALID_STATE_ERR;
193 if (m_nodeSetPosition + 1 > m_nodeSet.size())
196 Node* node = m_nodeSet[m_nodeSetPosition];
203 Node* XPathResult::snapshotItem(unsigned long index, ExceptionCode& ec)
205 if (resultType() != UNORDERED_NODE_SNAPSHOT_TYPE && resultType() != ORDERED_NODE_SNAPSHOT_TYPE) {
206 ec = XPathException::TYPE_ERR;
210 const NodeSet& nodes = m_value.toNodeSet();
211 if (index >= nodes.size())
219 #endif // ENABLE(XPATH)