KHtml

dom3_xpathimpl.cpp
1 /*
2  * dom3_xpathimpl.cpp - Copyright 2005 Frerich Raabe <[email protected]>
3  * Copyright 2010 Maksim Orlovich <[email protected]>
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 #include <dom/dom_exception.h>
27 #include <dom/dom3_xpath.h>
28 #include <xml/dom3_xpathimpl.h>
29 #include <xml/dom_nodeimpl.h>
30 #include <xml/dom_nodelistimpl.h>
31 
32 #include "xpath/util.h"
33 
34 using namespace DOM;
35 using namespace khtml;
36 using namespace khtml::XPath;
37 using namespace DOM::XPath;
38 
39 XPathResultImpl::XPathResultImpl()
40 {
41 }
42 
43 XPathResultImpl::XPathResultImpl(const Value &value)
44  : m_value(value)
45 {
46  switch (m_value.type()) {
47  case Value::Boolean:
48  m_resultType = BOOLEAN_TYPE;
49  break;
50  case Value::Number:
51  m_resultType = NUMBER_TYPE;
52  break;
53  case Value::String:
54  m_resultType = STRING_TYPE;
55  break;
56  case Value::Nodeset:
57  m_resultType = UNORDERED_NODE_ITERATOR_TYPE;
58  m_nodeIterator = 0;
59  }
60 }
61 
62 void XPathResultImpl::convertTo(unsigned short type, int &exceptioncode)
63 {
64  switch (type) {
65  case ANY_TYPE:
66  break;
67  case NUMBER_TYPE:
68  m_resultType = type;
69  m_value = Value(m_value.toNumber());
70  break;
71  case STRING_TYPE:
72  m_resultType = type;
73  m_value = Value(m_value.toString());
74  break;
75  case BOOLEAN_TYPE:
76  m_resultType = type;
77  m_value = Value(m_value.toBoolean());
78  break;
79  case UNORDERED_NODE_ITERATOR_TYPE:
80  case ORDERED_NODE_ITERATOR_TYPE:
81  case UNORDERED_NODE_SNAPSHOT_TYPE:
82  case ORDERED_NODE_SNAPSHOT_TYPE:
83  case ANY_UNORDERED_NODE_TYPE:
84  case FIRST_ORDERED_NODE_TYPE:
85  if (!m_value.isNodeset()) {
86  exceptioncode = XPathException::toCode(XPathException::TYPE_ERR);
87  return;
88  }
89  m_resultType = type;
90  break;
91  default:
92  // qCDebug(KHTML_LOG) << "Cannot convert XPathResultImpl to unknown type" << type;
93  exceptioncode = XPathException::toCode(XPathException::TYPE_ERR);
94  }
95 }
96 
97 unsigned short XPathResultImpl::resultType() const
98 {
99  return m_resultType;
100 }
101 
102 double XPathResultImpl::numberValue(int &exceptioncode) const
103 {
104  if (resultType() != NUMBER_TYPE) {
105  exceptioncode = XPathException::toCode(XPathException::TYPE_ERR);
106  return 0.0;
107  }
108  return m_value.toNumber();
109 }
110 
111 DOM::DOMString XPathResultImpl::stringValue(int &exceptioncode) const
112 {
113  if (resultType() != STRING_TYPE) {
114  exceptioncode = XPathException::toCode(XPathException::TYPE_ERR);
115  return DOMString();
116  }
117  return m_value.toString();
118 }
119 
120 bool XPathResultImpl::booleanValue(int &exceptioncode) const
121 {
122  if (resultType() != BOOLEAN_TYPE) {
123  exceptioncode = XPathException::toCode(XPathException::TYPE_ERR);
124  return false;
125  }
126  return m_value.toBoolean();
127 }
128 
129 NodeImpl *XPathResultImpl::singleNodeValue(int &exceptioncode) const
130 {
131  if (resultType() != ANY_UNORDERED_NODE_TYPE &&
132  resultType() != FIRST_ORDERED_NODE_TYPE) {
133  exceptioncode = XPathException::toCode(XPathException::TYPE_ERR);
134  return nullptr;
135  }
136  DomNodeList nodes = m_value.toNodeset();
137 
138  if (nodes && nodes->length()) {
139  return nodes->item(0);
140  } else {
141  return nullptr;
142  }
143 }
144 
145 bool XPathResultImpl::invalidIteratorState() const
146 {
147  if (resultType() != UNORDERED_NODE_ITERATOR_TYPE &&
148  resultType() != ORDERED_NODE_ITERATOR_TYPE) {
149  return false;
150  }
151  // XXX How to tell whether the document was changed since this
152  // result was returned?
153  return true;
154 }
155 
156 unsigned long XPathResultImpl::snapshotLength(int &exceptioncode) const
157 {
158  if (resultType() != UNORDERED_NODE_SNAPSHOT_TYPE &&
159  resultType() != ORDERED_NODE_SNAPSHOT_TYPE) {
160  exceptioncode = XPathException::toCode(XPathException::TYPE_ERR);
161  return 0;
162  }
163 
164  SharedPtr<DOM::StaticNodeListImpl> nodes = m_value.toNodeset();
165  return nodes ? nodes->length() : 0;
166 }
167 
168 NodeImpl *XPathResultImpl::iterateNext(int &exceptioncode)
169 {
170  if (resultType() != UNORDERED_NODE_ITERATOR_TYPE &&
171  resultType() != ORDERED_NODE_ITERATOR_TYPE) {
172  exceptioncode = XPathException::toCode(XPathException::TYPE_ERR);
173  return nullptr;
174  }
175  // XXX How to tell whether the document was changed since this
176  // result was returned? We need to throw an INVALID_STATE_ERR if that
177  // is the case.
178  SharedPtr<DOM::StaticNodeListImpl> nodes = m_value.toNodeset();
179  if (!nodes || m_nodeIterator >= nodes->length()) {
180  return nullptr;
181  } else {
182  NodeImpl *n = nodes->item(m_nodeIterator);
183  ++m_nodeIterator;
184  return n;
185  }
186 }
187 
188 NodeImpl *XPathResultImpl::snapshotItem(unsigned long index, int &exceptioncode)
189 {
190  if (resultType() != UNORDERED_NODE_SNAPSHOT_TYPE &&
191  resultType() != ORDERED_NODE_SNAPSHOT_TYPE) {
192  exceptioncode = XPathException::toCode(XPathException::TYPE_ERR);
193  return nullptr;
194  }
195  DomNodeList nodes = m_value.toNodeset();
196  if (!nodes || index >= nodes->length()) {
197  return nullptr;
198  }
199  return nodes->item(index);
200 }
201 
202 // ---------------------------------------------------------------------------
203 
204 DefaultXPathNSResolverImpl::DefaultXPathNSResolverImpl(NodeImpl *node)
205  : m_node(node)
206 {
207 }
208 
209 DOMString DefaultXPathNSResolverImpl::lookupNamespaceURI(const DOMString &prefix)
210 {
211  // Apparently Node::lookupNamespaceURI doesn't do this.
212  // ### check
213  if (prefix.string() == "xml") {
214  return DOMString("http://www.w3.org/XML/1998/namespace");
215  }
216  return m_node->lookupNamespaceURI(prefix);
217 }
218 
219 // ---------------------------------------------------------------------------
220 XPathExpressionImpl::XPathExpressionImpl(const DOMString &expression, XPathNSResolverImpl *resolver): m_statement(expression, resolver)
221 {
222 }
223 
224 XPathResultImpl *XPathExpressionImpl::evaluate(NodeImpl *contextNode,
225  unsigned short type,
226  XPathResultImpl * /*result_*/,
227  int &exceptioncode)
228 {
229  if (!isValidContextNode(contextNode)) {
230  exceptioncode = DOMException::NOT_SUPPORTED_ERR;
231  return nullptr;
232  }
233 
234  // We are permitted, but not required, to re-use result_. We don't.
235  Value xpathRes = m_statement.evaluate(contextNode, exceptioncode);
236  XPathResultImpl *result = new XPathResultImpl(exceptioncode ? Value() : xpathRes);
237 
238  if (type != ANY_TYPE) {
239  result->convertTo(type, exceptioncode);
240  if (exceptioncode) {
241  // qCDebug(KHTML_LOG) << "couldn't convert XPathResult to" << type << "from" << xpathRes.type();
242  delete result;
243  return nullptr;
244  }
245  }
246 
247  return result;
248 }
249 
250 int XPathExpressionImpl::parseExceptionCode()
251 {
252  return m_statement.exceptionCode();
253 }
254 
This file is part of the HTML rendering engine for KDE.
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
This library provides a full-featured HTML parser and widget.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Oct 25 2021 22:48:13 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.