6c556cdda72287de43d6d95130b3a8003407e8e1
[profile/ivi/qtxmlpatterns.git] / src / xmlpatterns / data / qatomiccasters_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 //
43 //  W A R N I N G
44 //  -------------
45 //
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.
49 //
50 // We mean it.
51
52 #ifndef Patternist_AtomicCasters_H
53 #define Patternist_AtomicCasters_H
54
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>
61
62 /**
63  * @file
64  * @short Contains classes sub-classing AtomicCaster and which
65  * are responsible of casting an atomic value to another type.
66  */
67
68 QT_BEGIN_HEADER
69
70 QT_BEGIN_NAMESPACE
71
72 namespace QPatternist
73 {
74
75     /**
76      * @short Casts any atomic value to @c xs:string.
77      *
78      * This class uses Item::stringValue() for retrieving a string
79      * representation, and thus supports casting from atomic values
80      * of any type.
81      *
82      * @ingroup Patternist_xdm
83      * @author Frans Englich <frans.englich@nokia.com>
84      */
85     template<TypeOfDerivedString DerivedType>
86     class ToStringCaster : public AtomicCaster
87     {
88     public:
89         virtual Item castFrom(const Item &from,
90                               const QExplicitlySharedDataPointer<DynamicContext> &context) const
91         {
92             Q_ASSERT(from);
93             return DerivedString<DerivedType>::fromLexical(context->namePool(), from.stringValue());
94         }
95     };
96
97     /**
98      * @short Casts any atomic value to @c xs:untypedAtomic.
99      *
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.
103      *
104      * @ingroup Patternist_xdm
105      * @author Frans Englich <frans.englich@nokia.com>
106      */
107     class ToUntypedAtomicCaster : public AtomicCaster
108     {
109     public:
110         virtual Item castFrom(const Item &from,
111                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
112     };
113
114     /**
115      * @short Casts a string value to @c xs:anyURI.
116      *
117      * @ingroup Patternist_xdm
118      * @author Frans Englich <frans.englich@nokia.com>
119      */
120     class ToAnyURICaster : public AtomicCaster
121     {
122     public:
123         virtual Item castFrom(const Item &from,
124                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
125     };
126
127     /**
128      * @short Casts a @c xs:hexBinary atomic value to @c xs:base64Binary.
129      *
130      * @ingroup Patternist_xdm
131      * @author Frans Englich <frans.englich@nokia.com>
132      */
133     class HexBinaryToBase64BinaryCaster : public AtomicCaster
134     {
135     public:
136         virtual Item castFrom(const Item &from,
137                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
138     };
139
140     /**
141      * @short Casts a @c xs:base64Binary atomic value to @c xs:hexBinary.
142      *
143      * @ingroup Patternist_xdm
144      * @author Frans Englich <frans.englich@nokia.com>
145      */
146     class Base64BinaryToHexBinaryCaster : public AtomicCaster
147     {
148     public:
149         virtual Item castFrom(const Item &from,
150                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
151     };
152
153     /**
154      * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:base64Binary.
155      *
156      * @ingroup Patternist_xdm
157      * @author Frans Englich <frans.englich@nokia.com>
158      */
159     class StringToBase64BinaryCaster : public AtomicCaster
160     {
161     public:
162         virtual Item castFrom(const Item &from,
163                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
164     };
165
166     /**
167      * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:hexBinary.
168      *
169      * @ingroup Patternist_xdm
170      * @author Frans Englich <frans.englich@nokia.com>
171      */
172     class StringToHexBinaryCaster : public AtomicCaster
173     {
174     public:
175         virtual Item castFrom(const Item &from,
176                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
177     };
178
179     /**
180      * @short Casts any @c numeric value to @c xs:boolean.
181      *
182      * @ingroup Patternist_xdm
183      * @author Frans Englich <frans.englich@nokia.com>
184      */
185     class NumericToBooleanCaster : public AtomicCaster
186     {
187     public:
188         virtual Item castFrom(const Item &from,
189                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
190     };
191
192     /**
193      * @short Casts any string value, @c xs:string or @c xs:untypedAtomic, to @c xs:boolean.
194      *
195      * @ingroup Patternist_xdm
196      * @author Frans Englich <frans.englich@nokia.com>
197      */
198     class StringToBooleanCaster : public AtomicCaster
199     {
200     public:
201         virtual Item castFrom(const Item &from,
202                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
203     };
204
205     /**
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.
208      *
209      * castFrom() uses Numeric::toInteger() for doing the actual casting.
210      *
211      * @ingroup Patternist_xdm
212      * @author Frans Englich <frans.englich@nokia.com>
213      */
214     template <const bool IsInteger>
215     class NumericToDecimalCaster : public AtomicCaster
216     {
217     public:
218         /**
219          * Used by NumericToDerivedIntegerCaster in addition to this class.
220          */
221         static inline QString errorMessage()
222         {
223             return QtXmlPatterns::tr("When casting to %1 from %2, the source value cannot be %3.");
224         }
225
226         virtual Item castFrom(const Item &from,
227                               const QExplicitlySharedDataPointer<DynamicContext> &context) const
228         {
229             const ItemType::Ptr t(from.type());
230             const Numeric *const num = from.template as<Numeric>();
231
232             if(BuiltinTypes::xsDouble->xdtTypeMatches(t) || BuiltinTypes::xsFloat->xdtTypeMatches(t))
233             {
234                 if(num->isInf() || num->isNaN())
235                 {
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);
241                 }
242             }
243
244             if(IsInteger)
245                 return Integer::fromValue(num->toInteger());
246             else
247                 return toItem(Decimal::fromValue(num->toDecimal()));
248         }
249     };
250
251     /**
252      * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:decimal.
253      *
254      * @ingroup Patternist_xdm
255      * @author Frans Englich <frans.englich@nokia.com>
256      */
257     class StringToDecimalCaster : public AtomicCaster
258     {
259     public:
260         virtual Item castFrom(const Item &from,
261                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
262     };
263
264     /**
265      * @short Casts a string value, @c xs:string or @c xs:untypedAtomic, to @c xs:integer.
266      *
267      * @ingroup Patternist_xdm
268      * @author Frans Englich <frans.englich@nokia.com>
269      */
270     class StringToIntegerCaster : public AtomicCaster
271     {
272     public:
273         virtual Item castFrom(const Item &from,
274                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
275     };
276
277     /**
278      * @short Casts a value of type @c xs:boolean to @c xs:decimal.
279      *
280      * @ingroup Patternist_xdm
281      * @author Frans Englich <frans.englich@nokia.com>
282      */
283     class BooleanToDecimalCaster : public AtomicCaster
284     {
285     public:
286         virtual Item castFrom(const Item &from,
287                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
288     };
289
290     /**
291      * @short Casts a value of type @c xs:boolean to @c xs:integer.
292      *
293      * @ingroup Patternist_xdm
294      * @author Frans Englich <frans.englich@nokia.com>
295      */
296     class BooleanToIntegerCaster : public AtomicCaster
297     {
298     public:
299         virtual Item castFrom(const Item &from,
300                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
301     };
302
303     /**
304      * @short Casts a value to itself. Essentially, this AtomicCaster does nothing.
305      *
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.
311      *
312      * @ingroup Patternist_xdm
313      * @author Frans Englich <frans.englich@nokia.com>
314      */
315     class SelfToSelfCaster : public AtomicCaster
316     {
317     public:
318
319         /**
320          * This function simply returns @p from.
321          */
322         virtual Item castFrom(const Item &from,
323                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
324     };
325
326     /**
327      * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gYear.
328      *
329      * @ingroup Patternist_xdm
330      * @author Frans Englich <frans.englich@nokia.com>
331      */
332     class StringToGYearCaster : public AtomicCaster
333     {
334     public:
335         virtual Item castFrom(const Item &from,
336                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
337     };
338
339     /**
340      * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gDay.
341      *
342      * @ingroup Patternist_xdm
343      * @author Frans Englich <frans.englich@nokia.com>
344      */
345     class StringToGDayCaster : public AtomicCaster
346     {
347     public:
348         virtual Item castFrom(const Item &from,
349                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
350     };
351
352     /**
353      * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gMonth.
354      *
355      * @ingroup Patternist_xdm
356      * @author Frans Englich <frans.englich@nokia.com>
357      */
358     class StringToGMonthCaster : public AtomicCaster
359     {
360     public:
361         virtual Item castFrom(const Item &from,
362                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
363     };
364
365     /**
366      * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gYearMonth.
367      *
368      * @ingroup Patternist_xdm
369      * @author Frans Englich <frans.englich@nokia.com>
370      */
371     class StringToGYearMonthCaster : public AtomicCaster
372     {
373     public:
374         virtual Item castFrom(const Item &from,
375                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
376     };
377
378     /**
379      * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:gYearMonth.
380      *
381      * @ingroup Patternist_xdm
382      * @author Frans Englich <frans.englich@nokia.com>
383      */
384     class StringToGMonthDayCaster : public AtomicCaster
385     {
386     public:
387         virtual Item castFrom(const Item &from,
388                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
389     };
390
391     /**
392      * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:dateTime.
393      *
394      * @ingroup Patternist_xdm
395      * @author Frans Englich <frans.englich@nokia.com>
396      */
397     class StringToDateTimeCaster : public AtomicCaster
398     {
399     public:
400         virtual Item castFrom(const Item &from,
401                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
402     };
403
404     /**
405      * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:time.
406      *
407      * @ingroup Patternist_xdm
408      * @author Frans Englich <frans.englich@nokia.com>
409      */
410     class StringToTimeCaster : public AtomicCaster
411     {
412     public:
413         virtual Item castFrom(const Item &from,
414                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
415     };
416
417     /**
418      * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:date.
419      *
420      * @ingroup Patternist_xdm
421      * @author Frans Englich <frans.englich@nokia.com>
422      */
423     class StringToDateCaster : public AtomicCaster
424     {
425     public:
426         virtual Item castFrom(const Item &from,
427                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
428     };
429
430     /**
431      * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:duration.
432      *
433      * @ingroup Patternist_xdm
434      * @author Frans Englich <frans.englich@nokia.com>
435      */
436     class StringToDurationCaster : public AtomicCaster
437     {
438     public:
439         virtual Item castFrom(const Item &from,
440                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
441     };
442
443     /**
444      * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:dayTimeDuration.
445      *
446      * @ingroup Patternist_xdm
447      * @author Frans Englich <frans.englich@nokia.com>
448      */
449     class StringToDayTimeDurationCaster : public AtomicCaster
450     {
451     public:
452         virtual Item castFrom(const Item &from,
453                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
454     };
455
456     /**
457      * @short Casts a @c xs:string or @c xs:untypedAtomic atomic value to @c xs:yearMonthDuration.
458      *
459      * @ingroup Patternist_xdm
460      * @author Frans Englich <frans.englich@nokia.com>
461      */
462     class StringToYearMonthDurationCaster : public AtomicCaster
463     {
464     public:
465         virtual Item castFrom(const Item &from,
466                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
467     };
468
469
470     /**
471      * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gYear.
472      *
473      * @ingroup Patternist_xdm
474      * @author Frans Englich <frans.englich@nokia.com>
475      */
476     class AbstractDateTimeToGYearCaster : public AtomicCaster
477     {
478     public:
479         virtual Item castFrom(const Item &from,
480                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
481     };
482
483     /**
484      * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gYearMonth.
485      *
486      * @ingroup Patternist_xdm
487      * @author Frans Englich <frans.englich@nokia.com>
488      */
489     class AbstractDateTimeToGYearMonthCaster : public AtomicCaster
490     {
491     public:
492         virtual Item castFrom(const Item &from,
493                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
494     };
495
496     /**
497      * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gMonth.
498      *
499      * @ingroup Patternist_xdm
500      * @author Frans Englich <frans.englich@nokia.com>
501      */
502     class AbstractDateTimeToGMonthCaster : public AtomicCaster
503     {
504     public:
505         virtual Item castFrom(const Item &from,
506                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
507     };
508
509     /**
510      * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gMonthDay.
511      *
512      * @ingroup Patternist_xdm
513      * @author Frans Englich <frans.englich@nokia.com>
514      */
515     class AbstractDateTimeToGMonthDayCaster : public AtomicCaster
516     {
517     public:
518         virtual Item castFrom(const Item &from,
519                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
520     };
521
522     /**
523      * @short Casts a @c xs:date or @c xs:dateTime atomic value to @c xs:gDay.
524      *
525      * @ingroup Patternist_xdm
526      * @author Frans Englich <frans.englich@nokia.com>
527      */
528     class AbstractDateTimeToGDayCaster : public AtomicCaster
529     {
530     public:
531         virtual Item castFrom(const Item &from,
532                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
533     };
534
535     /**
536      * @short Casts an AbstractDateTime instance to DateTime.
537      *
538      * @ingroup Patternist_xdm
539      * @author Frans Englich <frans.englich@nokia.com>
540      */
541     class AbstractDateTimeToDateTimeCaster : public AtomicCaster
542     {
543     public:
544         virtual Item castFrom(const Item &from,
545                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
546     };
547
548     /**
549      * @short Casts an AbstractDateTime instance to SchemaTime.
550      *
551      * @ingroup Patternist_xdm
552      * @author Frans Englich <frans.englich@nokia.com>
553      */
554     class AbstractDateTimeToDateCaster : public AtomicCaster
555     {
556     public:
557         virtual Item castFrom(const Item &from,
558                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
559     };
560
561     /**
562      * @short Casts an AbstractDateTime instance to SchemaTime.
563      *
564      * @ingroup Patternist_xdm
565      * @author Frans Englich <frans.englich@nokia.com>
566      */
567     class AbstractDateTimeToTimeCaster : public AtomicCaster
568     {
569     public:
570         virtual Item castFrom(const Item &from,
571                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
572     };
573
574     /**
575      * @short Casts an AbstractDuration instance to Duration.
576      *
577      * @ingroup Patternist_xdm
578      * @author Frans Englich <frans.englich@nokia.com>
579      */
580     class AbstractDurationToDurationCaster : public AtomicCaster
581     {
582     public:
583         virtual Item castFrom(const Item &from,
584                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
585     };
586
587     /**
588      * @short Casts an AbstractDuration instance to DayTimeDuration.
589      *
590      * @ingroup Patternist_xdm
591      * @author Frans Englich <frans.englich@nokia.com>
592      */
593     class AbstractDurationToDayTimeDurationCaster : public AtomicCaster
594     {
595     public:
596         virtual Item castFrom(const Item &from,
597                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
598     };
599
600     /**
601      * @short Casts an AbstractDuration instance to YearMonthDuration.
602      *
603      * @ingroup Patternist_xdm
604      * @author Frans Englich <frans.englich@nokia.com>
605      */
606     class AbstractDurationToYearMonthDurationCaster : public AtomicCaster
607     {
608     public:
609         virtual Item castFrom(const Item &from,
610                               const QExplicitlySharedDataPointer<DynamicContext> &context) const;
611     };
612
613     /**
614      * @short Casts an @c xs:string instance to a derived type of @c xs:integer.
615      *
616      * @ingroup Patternist_xdm
617      * @author Frans Englich <frans.englich@nokia.com>
618      */
619     template<TypeOfDerivedInteger type>
620     class StringToDerivedIntegerCaster : public AtomicCaster
621     {
622     public:
623         virtual Item
624         castFrom(const Item &from,
625                  const QExplicitlySharedDataPointer<DynamicContext> &context) const
626         {
627             return DerivedInteger<type>::fromLexical(context->namePool(), from.stringValue());
628         }
629     };
630
631     /**
632      * @short Casts an @c xs:boolean instance to a derived type of @c xs:integer.
633      *
634      * @ingroup Patternist_xdm
635      * @author Frans Englich <frans.englich@nokia.com>
636      */
637     template<TypeOfDerivedInteger type>
638     class BooleanToDerivedIntegerCaster : public AtomicCaster
639     {
640     public:
641         virtual Item
642         castFrom(const Item &from,
643                  const QExplicitlySharedDataPointer<DynamicContext> &context) const
644         {
645             return DerivedInteger<type>::fromValue(context->namePool(), from.template as<AtomicValue>()->evaluateEBV(context) ? 1 : 0);
646         }
647     };
648
649     /**
650      * @short Casts an @c xs:boolean instance to a derived type of @c xs:integer.
651      *
652      * @ingroup Patternist_xdm
653      * @author Frans Englich <frans.englich@nokia.com>
654      */
655     template<TypeOfDerivedString type>
656     class AnyToDerivedStringCaster : public AtomicCaster
657     {
658     public:
659         virtual Item
660         castFrom(const Item &from,
661                  const QExplicitlySharedDataPointer<DynamicContext> &context) const
662         {
663             return DerivedString<type>::fromLexical(context->namePool(), from.stringValue());
664         }
665     };
666
667     /**
668      * @short Casts any @c numeric instance to a derived type of @c xs:integer.
669      *
670      * @ingroup Patternist_xdm
671      * @author Frans Englich <frans.englich@nokia.com>
672      */
673     template<TypeOfDerivedInteger type>
674     class NumericToDerivedIntegerCaster : public AtomicCaster
675     {
676     public:
677         virtual Item
678         castFrom(const Item &from,
679                  const QExplicitlySharedDataPointer<DynamicContext> &context) const
680         {
681             const ItemType::Ptr t(from.type());
682             const Numeric *const num = from.template as<Numeric>();
683
684             if(BuiltinTypes::xsDouble->xdtTypeMatches(t) || BuiltinTypes::xsFloat->xdtTypeMatches(t))
685             {
686                 if(num->isInf() || num->isNaN())
687                 {
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);
693                 }
694             }
695
696             return toItem(DerivedInteger<type>::fromValue(context->namePool(), from.template as<Numeric>()->toInteger()));
697         }
698     };
699 }
700
701 QT_END_NAMESPACE
702
703 QT_END_HEADER
704
705 #endif