Qt 4.8
qstringvaluefns.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 "qabstractfloat_p.h"
43 #include "qatomicstring_p.h"
44 #include "qcommonsequencetypes_p.h"
45 #include "qcommonvalues_p.h"
46 #include "qinteger_p.h"
47 #include "qliteral_p.h"
48 #include "qpatternistlocale_p.h"
49 #include "qschemanumeric_p.h"
50 
51 #include "qstringvaluefns_p.h"
52 
54 
55 using namespace QPatternist;
56 
58 {
61  QString result;
62 
63  for(; it != end; ++it)
64  {
65  Item item((*it)->evaluateSingleton(context));
66 
67  if(item)
68  result += item.stringValue();
69  }
70 
71  return AtomicString::fromValue(result);
72 }
73 
75 {
77  Q_ASSERT(it);
78  Item current(it->next());
79 
80  if(!current) /* Exit early, don't evaluate the separator. */
82 
83  QString result;
84  QString separator;
85  const Item isep(m_operands.at(1)->evaluateSingleton(context));
86 
87  if(isep)
88  separator = isep.stringValue();
89 
90  while(true)
91  {
92  result += current.stringValue();
93  current = it->next();
94 
95  if(!current)
96  break;
97 
98  result += separator;
99  }
100 
101  return result.isEmpty()
103  : toItem(AtomicString::fromValue(result));
104 }
105 
107 {
109  return FunctionCall::compress(context);
110  else
111  {
113  return wrapLiteral(CommonValues::EmptyString, context, this);
114  else
115  return m_operands.first()->compress(context);
116  }
117 }
118 
120 {
121  Item item(m_operands.first()->evaluateSingleton(context));
122 
123  if(!item)
125 
126  const QString str(item.stringValue());
127 
128  const xsDouble dblStart = m_operands.at(1)->evaluateSingleton(context).as<Numeric>()
129  ->round()->toDouble();
130  if(qIsNaN(dblStart))
132 
133  /* XPath starts from 1, but C++ starts from 0. */
134  xsInteger startingLoc = Double::fromValue(dblStart)->round()->toInteger() - 1;
135 
136  xsInteger length = 0;
137  if(m_operands.count() == 2)
138  length = str.length() - startingLoc;
139  else
140  {
141  const xsDouble dblLen = m_operands.at(2)->evaluateSingleton(context).as<Numeric>()
142  ->round()->toDouble();
143 
144  if(qIsNaN(dblLen))
146 
147  length = Double::fromValue(dblLen)->round()->toInteger();
148  if(startingLoc > startingLoc + length)
150  }
151 
152  if(startingLoc < 0)
153  {
154  length = length + startingLoc;
155  startingLoc = 0;
156  }
157 
158  return AtomicString::fromValue(str.mid(startingLoc, length));
159 }
160 
162 {
163  const Item item(m_operands.first()->evaluateSingleton(context));
164 
165  /* fn:string() is re-implemented "inline" here. */
166  if(item)
167  return Integer::fromValue(item.stringValue().length());
168  else
170 }
171 
172 NormalizeUnicodeFN::NormalizeUnicodeFN() : m_normForm(QString::NormalizationForm_C)
173 {
174 }
175 
177 {
178  const Item arg(m_operands.first()->evaluateSingleton(context));
179 
180  if(!arg)
182 
183  return toItem(AtomicString::fromValue(arg.stringValue().simplified()));
184 }
185 
187 {
188  const Item arg(m_operands.first()->evaluateSingleton(context));
189 
190  if(!arg)
192 
193  int normForm;
194 
195  /* The second argument has been removed, if we've already determined the form. */
196  if(m_operands.count() == 1)
197  normForm = m_normForm;
198  else
199  {
200  normForm = determineNormalizationForm(context);
201  if(normForm == -1)
202  return toItem(AtomicString::fromValue(arg.stringValue()));
203  }
204 
205  return AtomicString::fromValue(arg.stringValue().normalized(
206  static_cast<QString::NormalizationForm>(normForm)));
207 }
208 
210 {
211  const Expression::Ptr me(FunctionCall::compress(context));
212  if(me != this)
213  return me;
214 
215  Q_ASSERT(m_operands.count() == 1 || m_operands.count() == 2);
216 
217  if(m_operands.count() == 1)
219  else if(m_operands.last()->is(IDStringValue))
220  {
221  m_normForm = static_cast<QString::NormalizationForm>(
223 
224  if(m_normForm == -1)
225  return m_operands.first();
226 
227  /* Remove the operand since we don't need it anymore. */
229  }
230 
231  return me;
232 }
233 
235 {
236  const QString strRepr(m_operands.last()->evaluateSingleton(context).stringValue().trimmed().toUpper());
237 
238  /* TODO. Put these values in a QHash for faster lookup. Keep thread safety in mind. */
239  if(strRepr.isEmpty())
240  return -1;
241  else if(strRepr == QLatin1String("NFC"))
243  else if(strRepr == QLatin1String("NFD"))
245  else if(strRepr == QLatin1String("NFKC"))
247  else if(strRepr == QLatin1String("NFKD"))
249  else
250  {
251  /* What form is FULLY_NORMALIZED? Is a code path available for that somewhere? */
252  context->error(QtXmlPatterns::tr("The normalization form %1 is "
253  "unsupported. The supported forms are "
254  "%2, %3, %4, and %5, and none, i.e. "
255  "the empty string (no normalization).")
256  .arg(formatKeyword(strRepr))
257  .arg(formatKeyword("NFC"))
258  .arg(formatKeyword("NFD"))
259  .arg(formatKeyword("NFKC"))
260  .arg(formatKeyword("NFKD")),
262  this);
263  return QString::NormalizationForm_C; /* Silence compiler warning. */
264  }
265 }
266 
268 {
269  const Item item(m_operands.first()->evaluateSingleton(context));
270 
271  if(!item)
273 
274  return AtomicString::fromValue(item.stringValue().toUpper());
275 }
276 
278 {
279  const Item item(m_operands.first()->evaluateSingleton(context));
280 
281  if(!item)
283 
284  return AtomicString::fromValue(item.stringValue().toLower());
285 }
286 
288 {
289  const Item item(m_operands.first()->evaluateSingleton(context));
290 
291  if(!item)
293 
294  const QString mapString(m_operands.at(1)->evaluateSingleton(context).stringValue());
295  const QString arg(item.stringValue());
296 
297  if(mapString.isEmpty())
298  return AtomicString::fromValue(arg);
299 
300  const QString transString(m_operands.at(2)->evaluateSingleton(context).stringValue());
301  const int transLen = transString.length();
302  const int argLen = arg.length();
303 
304  QString result;
305  result.reserve(argLen);
306  int outI = 0;
307 
308  for(int i = 0; i < argLen; ++i)
309  {
310  const QChar argCh(arg.at(i));
311  const int mapPos = mapString.indexOf(argCh);
312 
313  if(mapPos == -1)
314  {
315  result[outI] = argCh;
316  ++outI;
317  continue;
318  }
319  else if(mapPos >= transLen)
320  continue;
321 
322  const QChar transCh(transString.at(mapPos));
323 
324  if(transCh.isNull())
325  continue;
326 
327  result[outI] = transCh;
328  ++outI;
329  }
330 
331  result.truncate(outI);
332  return AtomicString::fromValue(result);
333 }
334 
336  const QByteArray &includeChars) : m_excludeChars(excludeChars),
337  m_includeChars(includeChars)
338 {
339 }
340 
342 {
343  const Item item(m_operands.first()->evaluateSingleton(context));
344 
345  if(!item)
347 
350  m_includeChars).constData()));
351 }
352 
353 const char *const EncodeForURIFN::include = "#!*'()";
354 
356 {
357 }
358 
359 const char *const IriToURIFN::exclude = "#-_!~*'();?@&=+$,[]/:%";
360 
361 IriToURIFN::IriToURIFN() : EncodeString(QByteArray::fromRawData(exclude, 22), QByteArray())
362 {
363 }
364 
365 const char *const EscapeHtmlURIFN::include = "?&[]%";
366 const char *const EscapeHtmlURIFN::exclude = " :;=@!./+*()-,#$'";
367 
369  QByteArray::fromRawData(include, 6))
370 {
371 }
372 
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
static QByteArray toPercentEncoding(const QString &, const QByteArray &exclude=QByteArray(), const QByteArray &include=QByteArray())
Returns an encoded copy of input.
Definition: qurl.cpp:6009
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
static QString fromAscii(const char *, int size=-1)
Returns a QString initialized with the first size characters from the string str. ...
Definition: qstring.cpp:4276
NormalizationForm
This enum describes the various normalized forms of Unicode text.
Definition: qstring.h:309
QString formatKeyword(const QString &keyword)
#define it(className, varName)
const QByteArray m_includeChars
qint64 xsInteger
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
QString toUpper() const Q_REQUIRED_RESULT
Returns an uppercase copy of the string.
Definition: qstring.cpp:5483
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the list.
Definition: qlist.h:269
void removeLast()
Removes the last item in the list.
Definition: qlist.h:287
Item toItem(const QExplicitlySharedDataPointer< T > atomicValue)
Definition: qitem_p.h:431
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
static const char *const exclude
The QString class provides a Unicode character string.
Definition: qstring.h:83
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
static const Item IntegerZero
static const char *const include
static Item fromValue(const xsInteger num)
Definition: qinteger.cpp:52
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
static AtomicString::Ptr fromValue(const QString &value)
virtual Expression::Ptr compress(const StaticContext::Ptr &context)
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
void reserve(int size)
Attempts to allocate memory for at least size characters.
Definition: qstring.h:881
friend class const_iterator
Definition: qlist.h:264
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
void truncate(int pos)
Truncates the string at the given position index.
Definition: qstring.cpp:4603
QString trimmed() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end.
Definition: qstring.cpp:4506
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
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.
QString stringValue() const
Returns the string value of this Item.
Definition: qitem_p.h:302
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
virtual Cardinality cardinality() const =0
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
Q_CORE_EXPORT bool qIsNaN(double d)
Returns true if the double {d} is not a number (NaN).
Definition: qnumeric.cpp:55
T & first()
Returns a reference to the first item in the list.
Definition: qlist.h:282
Provides functionality for encoding strings. Sub-classed by various function implementations.
virtual SequenceType::Ptr staticType() const =0
QString::NormalizationForm m_normForm
Contains functions used for formatting arguments, such as keywords and paths, in translated strings...
int determineNormalizationForm(const DynamicContext::Ptr &context) const
Represents an item in the XPath 2.0 Data Model.
Definition: qitem_p.h:182
Base class for all numeric values.
static const char *const include
virtual QExplicitlySharedDataPointer< DynamicContext > dynamicContext() const =0
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
Contains class Numeric. This file was originally called qnumeric_p.h, but various build systems canno...
T & last()
Returns a reference to the last item in the list.
Definition: qlist.h:284
static const AtomicValue::Ptr EmptyString
virtual xsDouble toDouble() const =0
static Numeric::Ptr fromValue(const xsDouble num)
static const char *const exclude
const QByteArray m_excludeChars
TCastTarget * as() const
Definition: qitem_p.h:278
static const KeyPair *const end
virtual Expression::Ptr compress(const StaticContext::Ptr &context)
EncodeString(const QByteArray &excludeChars, const QByteArray &includeChars)
bool is(const ID id) const
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
virtual Expression::Ptr compress(const StaticContext::Ptr &context)
virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const
virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:272
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...