1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
46 // This file is not part of the Qt API. It exists purely as an
47 // implementation detail. This header file may change from version to
48 // version without notice, or even be removed.
52 #ifndef Patternist_AtomicCasters_H
53 #define Patternist_AtomicCasters_H
55 #include <private/qatomiccaster_p.h>
56 #include <private/qdecimal_p.h>
57 #include <private/qderivedinteger_p.h>
58 #include <private/qderivedstring_p.h>
59 #include <private/qinteger_p.h>
60 #include <private/qvalidationerror_p.h>
64 * @short Contains classes sub-classing AtomicCaster and which
65 * are responsible of casting an atomic value to another type.
76 * @short Casts any atomic value to @c xs:string.
78 * This class uses Item::stringValue() for retrieving a string
79 * representation, and thus supports casting from atomic values
82 * @ingroup Patternist_xdm
83 * @author Frans Englich <frans.englich@nokia.com>
85 template<TypeOfDerivedString DerivedType>
86 class ToStringCaster : public AtomicCaster
89 virtual Item castFrom(const Item &from,
90 const QExplicitlySharedDataPointer<DynamicContext> &context) const
93 return DerivedString<DerivedType>::fromLexical(context->namePool(), from.stringValue());
98 * @short Casts any atomic value to @c xs:untypedAtomic.
100 * This class uses Item::stringValue() for retrieving a string
101 * representation, and thus supports casting from atomic values
102 * of any type. The implementation is similar to ToStringCaster.
104 * @ingroup Patternist_xdm
105 * @author Frans Englich <frans.englich@nokia.com>
107 class ToUntypedAtomicCaster : public AtomicCaster
110 virtual Item castFrom(const Item &from,
111 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
115 * @short Casts a string value to @c xs:anyURI.
117 * @ingroup Patternist_xdm
118 * @author Frans Englich <frans.englich@nokia.com>
120 class ToAnyURICaster : public AtomicCaster
123 virtual Item castFrom(const Item &from,
124 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
128 * @short Casts a @c xs:hexBinary atomic value to @c xs:base64Binary.
130 * @ingroup Patternist_xdm
131 * @author Frans Englich <frans.englich@nokia.com>
133 class HexBinaryToBase64BinaryCaster : public AtomicCaster
136 virtual Item castFrom(const Item &from,
137 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
141 * @short Casts a @c xs:base64Binary atomic value to @c xs:hexBinary.
143 * @ingroup Patternist_xdm
144 * @author Frans Englich <frans.englich@nokia.com>
146 class Base64BinaryToHexBinaryCaster : public AtomicCaster
149 virtual Item castFrom(const Item &from,
150 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
154 * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:base64Binary.
156 * @ingroup Patternist_xdm
157 * @author Frans Englich <frans.englich@nokia.com>
159 class StringToBase64BinaryCaster : public AtomicCaster
162 virtual Item castFrom(const Item &from,
163 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
167 * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:hexBinary.
169 * @ingroup Patternist_xdm
170 * @author Frans Englich <frans.englich@nokia.com>
172 class StringToHexBinaryCaster : public AtomicCaster
175 virtual Item castFrom(const Item &from,
176 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
180 * @short Casts any @c numeric value to @c xs:boolean.
182 * @ingroup Patternist_xdm
183 * @author Frans Englich <frans.englich@nokia.com>
185 class NumericToBooleanCaster : public AtomicCaster
188 virtual Item castFrom(const Item &from,
189 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
193 * @short Casts any string value, @c xs:string or @c xs:untypedAtomic, to @c xs:boolean.
195 * @ingroup Patternist_xdm
196 * @author Frans Englich <frans.englich@nokia.com>
198 class StringToBooleanCaster : public AtomicCaster
201 virtual Item castFrom(const Item &from,
202 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
206 * @short Casts a @c numeric value, such as @c xs:double or @c xs:decimal, to @c xs:integer or
207 * @c xs:decimal, depending on IsInteger.
209 * castFrom() uses Numeric::toInteger() for doing the actual casting.
211 * @ingroup Patternist_xdm
212 * @author Frans Englich <frans.englich@nokia.com>
214 template <const bool IsInteger>
215 class NumericToDecimalCaster : public AtomicCaster
219 * Used by NumericToDerivedIntegerCaster in addition to this class.
221 static inline QString errorMessage()
223 return QtXmlPatterns::tr("When casting to %1 from %2, the source value cannot be %3.");
226 virtual Item castFrom(const Item &from,
227 const QExplicitlySharedDataPointer<DynamicContext> &context) const
229 const ItemType::Ptr t(from.type());
230 const Numeric *const num = from.template as<Numeric>();
232 if(BuiltinTypes::xsDouble->xdtTypeMatches(t) || BuiltinTypes::xsFloat->xdtTypeMatches(t))
234 if(num->isInf() || num->isNaN())
236 return ValidationError::createError(errorMessage()
237 .arg(formatType(context->namePool(), IsInteger ? BuiltinTypes::xsInteger : BuiltinTypes::xsDecimal))
238 .arg(formatType(context->namePool(), t))
239 .arg(formatData(num->stringValue())),
240 ReportContext::FOCA0002);
245 return Integer::fromValue(num->toInteger());
247 return toItem(Decimal::fromValue(num->toDecimal()));
252 * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:decimal.
254 * @ingroup Patternist_xdm
255 * @author Frans Englich <frans.englich@nokia.com>
257 class StringToDecimalCaster : public AtomicCaster
260 virtual Item castFrom(const Item &from,
261 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
265 * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:integer.
267 * @ingroup Patternist_xdm
268 * @author Frans Englich <frans.englich@nokia.com>
270 class StringToIntegerCaster : public AtomicCaster
273 virtual Item castFrom(const Item &from,
274 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
278 * @short Casts a value of type @c xs:boolean to @c xs:decimal.
280 * @ingroup Patternist_xdm
281 * @author Frans Englich <frans.englich@nokia.com>
283 class BooleanToDecimalCaster : public AtomicCaster
286 virtual Item castFrom(const Item &from,
287 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
291 * @short Casts a value of type @c xs:boolean to @c xs:integer.
293 * @ingroup Patternist_xdm
294 * @author Frans Englich <frans.englich@nokia.com>
296 class BooleanToIntegerCaster : public AtomicCaster
299 virtual Item castFrom(const Item &from,
300 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
304 * @short Casts a value to itself. Essentially, this AtomicCaster does nothing.
306 * Casting a value to the type of itself is defined to be a noop,
307 * no operation. When it can be statically detected that will be done,
308 * CastAs rewrites itself appropriately during compilation, but
309 * in some cases insufficent data is available at compile time and then
310 * is this class need on a case-per-case base at evaluation time.
312 * @ingroup Patternist_xdm
313 * @author Frans Englich <frans.englich@nokia.com>
315 class SelfToSelfCaster : public AtomicCaster
320 * This function simply returns @p from.
322 virtual Item castFrom(const Item &from,
323 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
327 * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gYear.
329 * @ingroup Patternist_xdm
330 * @author Frans Englich <frans.englich@nokia.com>
332 class StringToGYearCaster : public AtomicCaster
335 virtual Item castFrom(const Item &from,
336 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
340 * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gDay.
342 * @ingroup Patternist_xdm
343 * @author Frans Englich <frans.englich@nokia.com>
345 class StringToGDayCaster : public AtomicCaster
348 virtual Item castFrom(const Item &from,
349 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
353 * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gMonth.
355 * @ingroup Patternist_xdm
356 * @author Frans Englich <frans.englich@nokia.com>
358 class StringToGMonthCaster : public AtomicCaster
361 virtual Item castFrom(const Item &from,
362 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
366 * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gYearMonth.
368 * @ingroup Patternist_xdm
369 * @author Frans Englich <frans.englich@nokia.com>
371 class StringToGYearMonthCaster : public AtomicCaster
374 virtual Item castFrom(const Item &from,
375 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
379 * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gYearMonth.
381 * @ingroup Patternist_xdm
382 * @author Frans Englich <frans.englich@nokia.com>
384 class StringToGMonthDayCaster : public AtomicCaster
387 virtual Item castFrom(const Item &from,
388 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
392 * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:dateTime.
394 * @ingroup Patternist_xdm
395 * @author Frans Englich <frans.englich@nokia.com>
397 class StringToDateTimeCaster : public AtomicCaster
400 virtual Item castFrom(const Item &from,
401 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
405 * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:time.
407 * @ingroup Patternist_xdm
408 * @author Frans Englich <frans.englich@nokia.com>
410 class StringToTimeCaster : public AtomicCaster
413 virtual Item castFrom(const Item &from,
414 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
418 * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:date.
420 * @ingroup Patternist_xdm
421 * @author Frans Englich <frans.englich@nokia.com>
423 class StringToDateCaster : public AtomicCaster
426 virtual Item castFrom(const Item &from,
427 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
431 * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:duration.
433 * @ingroup Patternist_xdm
434 * @author Frans Englich <frans.englich@nokia.com>
436 class StringToDurationCaster : public AtomicCaster
439 virtual Item castFrom(const Item &from,
440 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
444 * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:dayTimeDuration.
446 * @ingroup Patternist_xdm
447 * @author Frans Englich <frans.englich@nokia.com>
449 class StringToDayTimeDurationCaster : public AtomicCaster
452 virtual Item castFrom(const Item &from,
453 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
457 * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:yearMonthDuration.
459 * @ingroup Patternist_xdm
460 * @author Frans Englich <frans.englich@nokia.com>
462 class StringToYearMonthDurationCaster : public AtomicCaster
465 virtual Item castFrom(const Item &from,
466 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
471 * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gYear.
473 * @ingroup Patternist_xdm
474 * @author Frans Englich <frans.englich@nokia.com>
476 class AbstractDateTimeToGYearCaster : public AtomicCaster
479 virtual Item castFrom(const Item &from,
480 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
484 * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gYearMonth.
486 * @ingroup Patternist_xdm
487 * @author Frans Englich <frans.englich@nokia.com>
489 class AbstractDateTimeToGYearMonthCaster : public AtomicCaster
492 virtual Item castFrom(const Item &from,
493 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
497 * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gMonth.
499 * @ingroup Patternist_xdm
500 * @author Frans Englich <frans.englich@nokia.com>
502 class AbstractDateTimeToGMonthCaster : public AtomicCaster
505 virtual Item castFrom(const Item &from,
506 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
510 * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gMonthDay.
512 * @ingroup Patternist_xdm
513 * @author Frans Englich <frans.englich@nokia.com>
515 class AbstractDateTimeToGMonthDayCaster : public AtomicCaster
518 virtual Item castFrom(const Item &from,
519 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
523 * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gDay.
525 * @ingroup Patternist_xdm
526 * @author Frans Englich <frans.englich@nokia.com>
528 class AbstractDateTimeToGDayCaster : public AtomicCaster
531 virtual Item castFrom(const Item &from,
532 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
536 * @short Casts an AbstractDateTime instance to DateTime.
538 * @ingroup Patternist_xdm
539 * @author Frans Englich <frans.englich@nokia.com>
541 class AbstractDateTimeToDateTimeCaster : public AtomicCaster
544 virtual Item castFrom(const Item &from,
545 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
549 * @short Casts an AbstractDateTime instance to SchemaTime.
551 * @ingroup Patternist_xdm
552 * @author Frans Englich <frans.englich@nokia.com>
554 class AbstractDateTimeToDateCaster : public AtomicCaster
557 virtual Item castFrom(const Item &from,
558 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
562 * @short Casts an AbstractDateTime instance to SchemaTime.
564 * @ingroup Patternist_xdm
565 * @author Frans Englich <frans.englich@nokia.com>
567 class AbstractDateTimeToTimeCaster : public AtomicCaster
570 virtual Item castFrom(const Item &from,
571 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
575 * @short Casts an AbstractDuration instance to Duration.
577 * @ingroup Patternist_xdm
578 * @author Frans Englich <frans.englich@nokia.com>
580 class AbstractDurationToDurationCaster : public AtomicCaster
583 virtual Item castFrom(const Item &from,
584 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
588 * @short Casts an AbstractDuration instance to DayTimeDuration.
590 * @ingroup Patternist_xdm
591 * @author Frans Englich <frans.englich@nokia.com>
593 class AbstractDurationToDayTimeDurationCaster : public AtomicCaster
596 virtual Item castFrom(const Item &from,
597 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
601 * @short Casts an AbstractDuration instance to YearMonthDuration.
603 * @ingroup Patternist_xdm
604 * @author Frans Englich <frans.englich@nokia.com>
606 class AbstractDurationToYearMonthDurationCaster : public AtomicCaster
609 virtual Item castFrom(const Item &from,
610 const QExplicitlySharedDataPointer<DynamicContext> &context) const;
614 * @short Casts an @c xs:string instance to a derived type of @c xs:integer.
616 * @ingroup Patternist_xdm
617 * @author Frans Englich <frans.englich@nokia.com>
619 template<TypeOfDerivedInteger type>
620 class StringToDerivedIntegerCaster : public AtomicCaster
624 castFrom(const Item &from,
625 const QExplicitlySharedDataPointer<DynamicContext> &context) const
627 return DerivedInteger<type>::fromLexical(context->namePool(), from.stringValue());
632 * @short Casts an @c xs:boolean instance to a derived type of @c xs:integer.
634 * @ingroup Patternist_xdm
635 * @author Frans Englich <frans.englich@nokia.com>
637 template<TypeOfDerivedInteger type>
638 class BooleanToDerivedIntegerCaster : public AtomicCaster
642 castFrom(const Item &from,
643 const QExplicitlySharedDataPointer<DynamicContext> &context) const
645 return DerivedInteger<type>::fromValue(context->namePool(), from.template as<AtomicValue>()->evaluateEBV(context) ? 1 : 0);
650 * @short Casts an @c xs:boolean instance to a derived type of @c xs:integer.
652 * @ingroup Patternist_xdm
653 * @author Frans Englich <frans.englich@nokia.com>
655 template<TypeOfDerivedString type>
656 class AnyToDerivedStringCaster : public AtomicCaster
660 castFrom(const Item &from,
661 const QExplicitlySharedDataPointer<DynamicContext> &context) const
663 return DerivedString<type>::fromLexical(context->namePool(), from.stringValue());
668 * @short Casts any @c numeric instance to a derived type of @c xs:integer.
670 * @ingroup Patternist_xdm
671 * @author Frans Englich <frans.englich@nokia.com>
673 template<TypeOfDerivedInteger type>
674 class NumericToDerivedIntegerCaster : public AtomicCaster
678 castFrom(const Item &from,
679 const QExplicitlySharedDataPointer<DynamicContext> &context) const
681 const ItemType::Ptr t(from.type());
682 const Numeric *const num = from.template as<Numeric>();
684 if(BuiltinTypes::xsDouble->xdtTypeMatches(t) || BuiltinTypes::xsFloat->xdtTypeMatches(t))
686 if(num->isInf() || num->isNaN())
688 return ValidationError::createError(NumericToDecimalCaster<false>::errorMessage()
689 .arg(formatType(context->namePool(), DerivedInteger<type>::itemType()))
690 .arg(formatType(context->namePool(), t))
691 .arg(formatData(num->stringValue())),
692 ReportContext::FOCA0002);
696 return toItem(DerivedInteger<type>::fromValue(context->namePool(), from.template as<Numeric>()->toInteger()));