Qt 4.8
qsequencefns.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qbuiltintypes_p.h"
43 #include "qcommonsequencetypes_p.h"
44 #include "qcommonvalues_p.h"
45 #include "qdistinctiterator_p.h"
46 #include "qebvextractor_p.h"
47 #include "qemptysequence_p.h"
48 #include "qgenericsequencetype_p.h"
49 #include "qindexofiterator_p.h"
50 #include "qinsertioniterator_p.h"
51 #include "qinteger_p.h"
52 #include "qremovaliterator_p.h"
54 #include "qsubsequenceiterator_p.h"
55 
56 #include "qsequencefns_p.h"
57 
59 
60 using namespace QPatternist;
61 
62 bool BooleanFN::evaluateEBV(const DynamicContext::Ptr &context) const
63 {
64  return m_operands.first()->evaluateEBV(context);
65 }
66 
68  const SequenceType::Ptr &reqType)
69 {
70  return EBVExtractor::typeCheck<FunctionCall>(context, reqType, this);
71 }
72 
74 {
76  m_operands.at(1)->evaluateSingleton(context),
77  comparator(), context,
78  ConstPtr(this)));
79 }
80 
82  const SequenceType::Ptr &reqType)
83 {
84  const Expression::Ptr me(FunctionCall::typeCheck(context, reqType));
86  const ItemType::Ptr t2(m_operands.at(1)->staticType()->itemType());
87 
88  if(*CommonSequenceTypes::Empty == *t1 ||
90  {
91  return EmptySequence::create(this, context);
92  }
93  else
94  {
95  prepareComparison(fetchComparator(t1, t2, context));
96  return me;
97  }
98 }
99 
101 {
103  comparator(),
104  ConstPtr(this),
105  context));
106 }
107 
109  const SequenceType::Ptr &reqType)
110 {
111  const Expression::Ptr me(FunctionCall::typeCheck(context, reqType));
113 
114  if(*CommonSequenceTypes::Empty == *t1)
115  return EmptySequence::create(this, context);
116  else if(!m_operands.first()->staticType()->cardinality().allowsMany())
117  return m_operands.first();
118  else if(BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t1))
119  return me;
120  else
121  {
122  prepareComparison(fetchComparator(t1, t1, context));
123  return me;
124  }
125 }
126 
128 {
130  return makeGenericSequenceType(t->itemType(),
131  t->cardinality().allowsMany() ? Cardinality::oneOrMore()
133 }
134 
136 {
137  const Item::Iterator::Ptr target(m_operands.first()->evaluateSequence(context));
138  const Item::Iterator::Ptr inserts(m_operands.at(2)->evaluateSequence(context));
139 
140  xsInteger position = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()->toInteger();
141 
142  if(position < 1)
143  position = 1;
144 
145  return Item::Iterator::Ptr(new InsertionIterator(target, position, inserts));
146 }
147 
149 {
150  return evaluateSequence(context)->next();
151 }
152 
154 {
157 
158  return makeGenericSequenceType(t1->itemType() | t2->itemType(),
159  t1->cardinality() + t2->cardinality());
160 }
161 
163 {
164  const xsInteger pos = m_operands.last()->evaluateSingleton(context).as<Numeric>()->toInteger();
166 
167  if(pos < 1)
168  return it;
169 
170  return Item::Iterator::Ptr(new RemovalIterator(it, pos));
171 }
172 
174 {
175  const xsInteger pos = m_operands.last()->evaluateSingleton(context).as<Numeric>()->toInteger();
176  if(pos <= 1)
177  return Item();
178 
179  return m_operands.first()->evaluateSingleton(context);
180 }
181 
183 {
184  const SequenceType::Ptr opType(m_operands.first()->staticType());
185  const Cardinality c(opType->cardinality());
186 
187  if(c.minimum() == 0)
188  return makeGenericSequenceType(opType->itemType(), c);
189  else
190  {
191  return makeGenericSequenceType(opType->itemType(),
192  Cardinality::fromRange(c.minimum() - 1,
193  c.maximum()));
194  }
195 }
196 
198 {
199  return m_operands.first()->evaluateSequence(context)->toReversed();
200 }
201 
203  const SequenceType::Ptr &reqType)
204 {
206  return FunctionCall::typeCheck(context, reqType);
207  else
208  return m_operands.first()->typeCheck(context, reqType);
209 }
210 
212 {
213  return m_operands.first()->staticType();
214 }
215 
216 SubsequenceFN::SubsequenceFN() : m_hasTypeChecked(false)
217 {
218 }
219 
221  const SequenceType::Ptr &reqType)
222 {
223  m_hasTypeChecked = true;
224  return FunctionCall::typeCheck(context, reqType);
225 }
226 
228 {
230 
231  xsInteger startingLoc = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()->round()->toInteger();
232  xsInteger length = -1;
233 
234  if(m_operands.count() == 3)
235  {
236  length = m_operands.last()->evaluateSingleton(context).as<Numeric>()->toInteger();
237 
238  if(startingLoc + length < 1 || (startingLoc > (startingLoc + length)))
240  }
241 
242  /* F&O, 15.1.10, "If $startingLoc is zero or negative, the
243  * subsequence includes items from the beginning of the $sourceSeq." */
244  if(startingLoc < 1)
245  startingLoc = 1;
246 
247  if(length < 1 && length != -1)
249  return Item::Iterator::Ptr(new SubsequenceIterator(it, startingLoc, length));
250 }
251 
253 {
254  return evaluateSequence(context)->next();
255 }
256 
258 {
259  const Expression::Ptr me(FunctionCall::compress(context));
260  if(me != this)
261  return me;
262 
263  const Expression::Ptr lenArg(m_operands.value(2));
264  if(lenArg && lenArg->isEvaluated())
265  {
266  const xsInteger length = lenArg->as<Literal>()->item().as<Numeric>()->round()->toInteger();
267 
268  if(length <= 0)
269  return EmptySequence::create(this, context);
270  }
271 
272  return me;
273 }
274 
276 {
277  const SequenceType::Ptr opType(m_operands.first()->staticType());
278  const Cardinality opCard(opType->cardinality());
279 
280  /* Optimization: we can do much stronger inference here. If the length is a
281  * constant, we can constrain the range at least upwards of the
282  * cardinality, for instance. */
283 
284  /* The subsequence(expr, 1, 1), add empty-sequence() to the static type.
285  *
286  * Note that we cannot do all these inferences before we've typechecked our
287  * operands. The only known case of where our staticType() is called before
288  * typeCheck() is through xmlpatternsview, although it wouldn't be
289  * surprising if the more exotic paths can achieve that too.
290  */
291  if(m_hasTypeChecked &&
292  m_operands.at(1)->isEvaluated() &&
293  m_operands.count() == 3 &&
294  m_operands.at(2)->isEvaluated() &&
295  m_operands.at(1)->as<Literal>()->item().as<Numeric>()->round()->toInteger() == 1 &&
296  m_operands.at(2)->as<Literal>()->item().as<Numeric>()->round()->toInteger() == 1)
297  {
298  return makeGenericSequenceType(opType->itemType(),
299  opCard.toWithoutMany());
300  }
301  else
302  {
303  return makeGenericSequenceType(opType->itemType(),
304  opCard | Cardinality::zeroOrOne());
305  }
306 }
307 
309  const SequenceType::Ptr &reqType)
310 {
311  /* See the doxygen documentation for this function for the explanation
312  * to why this implementation is here, as opposed to in
313  * qsequencegeneratingfns.cpp. */
314 
315  Q_ASSERT(context);
316 
317  prepareStaticBaseURI(context);
318 
319  const Expression::Ptr uriOp(m_operands.first());
320 
321  if(!uriOp->isEvaluated())
322  return Expression::Ptr(FunctionCall::typeCheck(context, reqType));
323 
324  const Item uriItem(uriOp->evaluateSingleton(context->dynamicContext()));
325 
326  if(!uriItem)
327  return EmptySequence::create(this, context)->typeCheck(context, reqType); // TODO test this
328 
329  /* These two lines were previously in a separate function but are now duplicated
330  * in DocFN::evaluateSingleton(), as part of a workaround for solaris-cc-64. */
331  const QUrl mayRela(AnyURI::toQUrl<ReportContext::FODC0005>(uriItem.stringValue(), context, this));
332  const QUrl uri(context->resolveURI(mayRela, staticBaseURI()));
333 
334  /* The URI is supplied statically, so, let's try to be clever. */
336  "No resource loader is set in the StaticContext.");
337  m_type = context->resourceLoader()->announceDocument(uri, ResourceLoader::MayUse);
338 
339  if(m_type)
340  {
342  return Expression::Ptr(FunctionCall::typeCheck(context, reqType));
343  }
344  else
345  {
346  context->error(QtXmlPatterns::tr("It will not be possible to retrieve %1.").arg(formatURI(uri)),
348  return Expression::Ptr();
349  }
350 }
351 
virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType)
unsigned char c[8]
Definition: qnumeric_p.h:62
virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
#define it(className, varName)
virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType)
QUrl resolveURI(const QUrl &relative, const QUrl &baseURI) const
Filters another sequence by removing duplicates such that the items are unique.
qint64 xsInteger
virtual bool evaluateEBV(const DynamicContext::Ptr &context) const
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
QExplicitlySharedDataPointer< const Expression > ConstPtr
A smart pointer wrapping const Expression instances.
virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType)
Definition: qexpression.cpp:70
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
virtual Expression::Ptr compress(const StaticContext::Ptr &context)
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
static Expression::Ptr create(const Expression *const replacementFor, const StaticContext::Ptr &context)
Creates an EmptySequence that is a replacement for replacementFor.
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
static const EmptyIterator< Item >::Ptr emptyIterator
Forms an QAbstractXmlForwardIterator over a sequence of integers, which each is the position of where...
Picks out a slice from another QAbstractXmlForwardIterator, specified by a start and end position...
virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const
virtual Expression::Ptr compress(const StaticContext::Ptr &context)
virtual SequenceType::Ptr announceDocument(const QUrl &uri, const Usage usageHint)
May be called by the compilation framework at compile time to report that an XML document referenced ...
QExplicitlySharedDataPointer< QAbstractXmlForwardIterator< Item > > Ptr
A smart pointer wrapping an instance of a QAbstractXmlForwardIterator subclass.
virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType)
virtual SequenceType::Ptr staticType() const
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
const TCastTarget * as() const
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
virtual SequenceType::Ptr staticType() const
static Cardinality oneOrMore()
virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The namespace for the internal API of QtXmlPatterns.
virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const
QString stringValue() const
Returns the string value of this Item.
Definition: qitem_p.h:302
virtual Cardinality cardinality() const =0
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
virtual ResourceLoader::Ptr resourceLoader() const =0
T value(int i) const
Returns the value at index position i in the list.
Definition: qlist.h:661
virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType)
Contains classes implementing the functions found in XQuery 1.0 and XPath 2.0 Functions and Operators...
Houses an AtomicValue, making it available as an Expression.
Definition: qliteral_p.h:74
T & first()
Returns a reference to the first item in the list.
Definition: qlist.h:282
QExplicitlySharedDataPointer< Expression > Ptr
A smart pointer wrapping mutable Expression instances.
Conceptually inserts one QAbstractXmlForwardIterator into another, make two QAbstractXmlForwardIterat...
virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const
virtual SequenceType::Ptr staticType() const =0
static const EmptySequenceType::Ptr Empty
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
static const SequenceType::Ptr ZeroOrOneDocumentNode
static Cardinality zeroOrOne()
Represents an item in the XPath 2.0 Data Model.
Definition: qitem_p.h:182
virtual SequenceType::Ptr staticType() const
Base class for all numeric values.
virtual xsInteger toInteger() const =0
virtual QExplicitlySharedDataPointer< DynamicContext > dynamicContext() const =0
T & last()
Returns a reference to the last item in the list.
Definition: qlist.h:284
virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType)
static Cardinality exactlyOne()
virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const
virtual SequenceType::Ptr staticType() const
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
static const AtomicType::Ptr xsAnyAtomicType
Represents a cardinality, a possible , often represented by occurrence indicators.
virtual ItemType::Ptr itemType() const =0
static QString formatURI(const NamePool::Ptr &np, const QXmlName::NamespaceCode &uri)
Formats uri, that&#39;s considered to be a URI, for display.
Definition: qanyuri_p.h:202
TCastTarget * as() const
Definition: qitem_p.h:278
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
Removes one items at a specified position from an input QAbstractXmlForwardIterator.
virtual bool evaluateEBV(const DynamicContext::Ptr &context) const
static Cardinality fromRange(const Count minimum, const Count maximum)
virtual SequenceType::Ptr staticType() const
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
Contains classes implementing the functions found in XQuery 1.0 and XPath 2.0 Functions and Operators...
virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType)
virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType)
virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const
#define Q_FUNC_INFO
Definition: qglobal.h:1871