1 /*
2  * Copyright 2006-2008 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "stdafx.h"
17 
18 #include <vector>
19 
20 #include "zorbatypes/numconversions.h"
21 #include "zorbatypes/datetime.h"
22 #include "zorbatypes/duration.h"
23 #include "zorbatypes/chartype.h"
24 #include "zorbatypes/URI.h"
25 
26 #include "diagnostics/xquery_diagnostics.h"
27 #include "diagnostics/assert.h"
28 #include "diagnostics/util_macros.h"
29 
30 #include "context/namespace_context.h"
31 
32 #include "system/globalenv.h"
33 
34 #include "store/api/item_factory.h"
35 #include "store/api/item.h"
36 #include "store/api/store.h"
37 #include <zorba/store_consts.h>
38 
39 #include "types/typeops.h"
40 #include "types/typemanagerimpl.h"
41 #include "types/schema/schema.h"
42 #include "types/casting.h"
43 
44 #include "context/static_context.h"
45 
46 #include "compiler/parser/query_loc.h"
47 
48 
49 namespace zorba
50 {
51 
52 void castToUserDefinedType(
53     store::Item_t& result,
54     const store::Item_t& aItem,
55     const XQType* aSourceType,
56     const XQType* aTargetType,
57     const QueryLoc& loc);
58 
59 
60 #define ATOMIC_TYPE(type) \
61   GENV_TYPESYSTEM.create_atomic_type(store::XS_##type, TypeConstants::QUANT_ONE)
62 
63 #define ATOMIC_CODE_T \
64   store::SchemaTypeCode
65 
66 
67 struct ErrorInfo
68 {
69   const XQType          * theSourceType;
70   const XQType          * theTargetType;
71   store::SchemaTypeCode   theSourceTypeCode;
72   store::SchemaTypeCode   theTargetTypeCode;
73   const QueryLoc        & theLoc;
74 
ErrorInfozorba::ErrorInfo75   ErrorInfo(
76       const XQType* source,
77       const XQType* target,
78       const QueryLoc& loc)
79     :
80     theSourceType(source),
81     theTargetType(target),
82     theLoc(loc)
83   {
84     assert(source != NULL && target != NULL);
85   }
86 
ErrorInfozorba::ErrorInfo87   ErrorInfo(
88       store::SchemaTypeCode source,
89       store::SchemaTypeCode target,
90       const QueryLoc& loc)
91     :
92     theSourceType(NULL),
93     theTargetType(NULL),
94     theSourceTypeCode(source),
95     theTargetTypeCode(target),
96     theLoc(loc)
97   {
98   }
99 };
100 
101 
throwTypeException(const Diagnostic & errcode,const ErrorInfo & info)102 void throwTypeException(const Diagnostic& errcode, const ErrorInfo& info)
103 {
104   if (info.theSourceType)
105   {
106     throw XQUERY_EXCEPTION_VAR(errcode,
107     ERROR_PARAMS(*info.theSourceType, ZED(NoCastTo_34o), *info.theTargetType),
108     ERROR_LOC(info.theLoc));
109   }
110   else
111   {
112     TypeManager& tm = GENV_TYPESYSTEM;
113 
114     xqtref_t sourceType =
115     tm.create_builtin_atomic_type(info.theSourceTypeCode,
116                                   TypeConstants::QUANT_ONE);
117 
118     xqtref_t targetType =
119     tm.create_builtin_atomic_type(info.theTargetTypeCode,
120                                   TypeConstants::QUANT_ONE);
121 
122     throw XQUERY_EXCEPTION_VAR(errcode,
123     ERROR_PARAMS(*sourceType, ZED(NoCastTo_34o), *targetType),
124     ERROR_LOC(info.theLoc));
125   }
126 }
127 
128 
129 /*******************************************************************************
130   Identity casting functions: target type is the same as the source one, so no
131   casting is actually done.
132 ********************************************************************************/
133 #define SAME_S_AND_T(type)          \
134 inline bool type##_##type(          \
135     store::Item_t& result,          \
136     const store::Item* aItem,       \
137     zstring& strval,                \
138     store::ItemFactory*,            \
139     namespace_context *nsCtx,       \
140     const ErrorInfo& aErrorInfo)    \
141 {                                   \
142   result = (aItem);                 \
143   return true;                      \
144 }                                   \
145 
146 SAME_S_AND_T(uA)
SAME_S_AND_T(str)147 SAME_S_AND_T(str)
148 SAME_S_AND_T(flt)
149 SAME_S_AND_T(dbl)
150 SAME_S_AND_T(dec)
151 SAME_S_AND_T(int)
152 SAME_S_AND_T(dur)
153 SAME_S_AND_T(yMD)
154 SAME_S_AND_T(dTD)
155 SAME_S_AND_T(dT)
156 SAME_S_AND_T(tim)
157 SAME_S_AND_T(dat)
158 SAME_S_AND_T(gYM)
159 SAME_S_AND_T(gYr)
160 SAME_S_AND_T(gMD)
161 SAME_S_AND_T(gDay)
162 SAME_S_AND_T(gMon)
163 SAME_S_AND_T(bool)
164 SAME_S_AND_T(b64)
165 SAME_S_AND_T(hxB)
166 SAME_S_AND_T(aURI)
167 SAME_S_AND_T(QN)
168 SAME_S_AND_T(NOT)
169 SAME_S_AND_T(NUL)
170 SAME_S_AND_T(uint)
171 
172 #undef SAME_S_AND_T
173 
174 
175 #define T1_TO_T2(type1, type2)      \
176 inline bool type1##_##type2(        \
177     store::Item_t& result,          \
178     const store::Item* aItem,       \
179     zstring& strval,                \
180     store::ItemFactory* aFactory,   \
181     namespace_context* nsCtx,       \
182     const ErrorInfo& aErrorInfo)    \
183 
184 
185 
186 T1_TO_T2(str, uA)
187 {
188   return aFactory->createUntypedAtomic(result, strval);
189 }
190 
191 
T1_TO_T2(str,flt)192 T1_TO_T2(str, flt)
193 {
194   try
195   {
196     xs_float const n(strval.c_str());
197     return aFactory->createFloat(result, n);
198   }
199   catch (std::invalid_argument const&)
200   {
201     throwTypeException(err::FORG0001, aErrorInfo);
202     return false;
203   }
204   catch ( std::range_error const& )
205   {
206     throw XQUERY_EXCEPTION(err::FOAR0002, ERROR_PARAMS(strval));
207   }
208 }
209 
210 
T1_TO_T2(str,dbl)211 T1_TO_T2(str, dbl)
212 {
213   try
214   {
215     xs_double const n(strval.c_str());
216     return aFactory->createDouble(result, n);
217   }
218   catch (std::invalid_argument const& )
219   {
220     throwTypeException(err::FORG0001, aErrorInfo);
221     return false;
222   }
223   catch (std::range_error const& )
224   {
225     throw XQUERY_EXCEPTION(err::FOAR0002, ERROR_PARAMS(strval));
226   }
227 }
228 
229 
T1_TO_T2(str,dec)230 T1_TO_T2(str, dec)
231 {
232   try
233   {
234     xs_decimal const n(strval.c_str());
235     return aFactory->createDecimal(result, n);
236   }
237   catch ( std::exception const& )
238   {
239     throwTypeException( err::FORG0001, aErrorInfo );
240     return false;
241   }
242 }
243 
244 
T1_TO_T2(str,int)245 T1_TO_T2(str, int)
246 {
247   try
248   {
249     xs_integer const n(strval.c_str());
250     return aFactory->createInteger(result, n);
251   }
252   catch ( std::invalid_argument const& )
253   {
254     throwTypeException( err::FORG0001, aErrorInfo );
255     return false;
256   }
257   catch ( std::range_error const& )
258   {
259     throwTypeException( err::FOAR0002, aErrorInfo );
260     return false;
261   }
262 }
263 
264 
T1_TO_T2(str,dur)265 T1_TO_T2(str, dur)
266 {
267   Duration d;
268   int err;
269 
270   if (0 == (err = Duration::parseDuration(strval.c_str(), strval.size(), d)))
271     return aFactory->createDuration(result, &d);
272 
273   throwTypeException(err::FORG0001, aErrorInfo);
274   return false;
275 }
276 
277 
T1_TO_T2(str,yMD)278 T1_TO_T2(str, yMD)
279 {
280   Duration d;
281   int err;
282 
283   if (0 == (err = Duration::parseYearMonthDuration(strval.c_str(), strval.size(), d)))
284     return aFactory->createYearMonthDuration(result, &d);
285 
286   throwTypeException( err::FORG0001, aErrorInfo );
287   return false;
288 }
289 
290 
T1_TO_T2(str,dTD)291 T1_TO_T2(str, dTD)
292 {
293   Duration d;
294   int err;
295 
296   if (0 == (err = Duration::parseDayTimeDuration(strval.c_str(), strval.size(), d)))
297     return aFactory->createDayTimeDuration(result, &d);
298 
299   throwTypeException( err::FORG0001, aErrorInfo );
300   return false;
301 }
302 
303 
T1_TO_T2(str,dT)304 T1_TO_T2(str, dT)
305 {
306   xs_dateTime dt;
307   if (0 == DateTime::parseDateTime(strval.c_str(), strval.size(), dt))
308     return aFactory->createDateTime(result, &dt);
309 
310   throwTypeException( err::FORG0001, aErrorInfo );
311   return false;
312 }
313 
314 
T1_TO_T2(str,tim)315 T1_TO_T2(str, tim)
316 {
317   xs_time t;
318   if (0 == DateTime::parseTime(strval.c_str(), strval.size(), t))
319     return aFactory->createTime(result, &t);
320 
321   throwTypeException( err::FORG0001, aErrorInfo );
322   return false;
323 }
324 
325 
T1_TO_T2(str,dat)326 T1_TO_T2(str, dat)
327 {
328   xs_date d;
329   if (0 == DateTime::parseDate(strval.c_str(), strval.size(), d))
330     return aFactory->createDate(result, &d);
331 
332   throwTypeException( err::FORG0001, aErrorInfo );
333   return false;
334 }
335 
336 
T1_TO_T2(str,gYM)337 T1_TO_T2(str, gYM)
338 {
339   xs_gYearMonth ym;
340   if (0 == DateTime::parseGYearMonth(strval.c_str(), strval.size(), ym))
341     return aFactory->createGYearMonth(result, &ym);
342 
343   throwTypeException( err::FORG0001, aErrorInfo );
344   return false;
345 }
346 
347 
T1_TO_T2(str,gYr)348 T1_TO_T2(str, gYr)
349 {
350   xs_gYear y;
351   if (0 == DateTime::parseGYear(strval.c_str(), strval.size(), y))
352     return aFactory->createGYear(result, &y);
353 
354   throwTypeException( err::FORG0001, aErrorInfo );
355   return false;
356 }
357 
358 
T1_TO_T2(str,gMD)359 T1_TO_T2(str, gMD)
360 {
361   xs_gMonthDay md;
362   if (0 == DateTime::parseGMonthDay(strval.c_str(), strval.size(), md))
363     return aFactory->createGMonthDay(result, &md);
364 
365   throwTypeException( err::FORG0001, aErrorInfo );
366   return false;
367 }
368 
369 
T1_TO_T2(str,gDay)370 T1_TO_T2(str, gDay)
371 {
372   xs_gDay d;
373   if (0 == DateTime::parseGDay(strval.c_str(), strval.size(), d))
374     return aFactory->createGDay(result, &d);
375 
376   throwTypeException( err::FORG0001, aErrorInfo );
377   return false;
378 }
379 
380 
T1_TO_T2(str,gMon)381 T1_TO_T2(str, gMon)
382 {
383   xs_gMonth m;
384   if (0 == DateTime::parseGMonth(strval.c_str(), strval.size(), m))
385     return aFactory->createGMonth(result, &m);
386 
387   throwTypeException( err::FORG0001, aErrorInfo );
388   return false;
389 }
390 
391 
T1_TO_T2(str,bool)392 T1_TO_T2(str, bool)
393 {
394   bool lRetValue = true;
395   const char* str = strval.c_str();
396   zstring::size_type len = strval.size();
397   zstring::size_type pos = 0;
398 
399   ascii::skip_whitespace(str, len, &pos);
400 
401   str += pos;
402 
403   if (strncmp(str, "false", 5) == 0)
404   {
405     lRetValue = false;
406     str += 5;
407   }
408   else if (strncmp(str, "0", 1) == 0)
409   {
410     lRetValue = false;
411     str += 1;
412   }
413   else if (strncmp(str, "true", 4) == 0)
414   {
415     lRetValue = true;
416     str += 4;
417   }
418   else if (strncmp(str, "1", 1) == 0)
419   {
420     lRetValue = true;
421     str += 1;
422   }
423   else
424   {
425     throwTypeException( err::FORG0001, aErrorInfo );
426     return false;
427   }
428 
429   pos = str - strval.c_str();
430   ascii::skip_whitespace(strval.c_str(), len, &pos);
431 
432   if (pos != len)
433     throwTypeException( err::FORG0001, aErrorInfo );
434 
435   return aFactory->createBoolean(result, lRetValue);
436 }
437 
438 
T1_TO_T2(str,b64)439 T1_TO_T2(str, b64)
440 {
441   xs_base64Binary n;
442   if (xs_base64Binary::parseString(strval, n))
443     return aFactory->createBase64Binary(result, n);
444 
445   throwTypeException( err::FORG0001, aErrorInfo );
446   return false;
447 }
448 
449 
T1_TO_T2(str,hxB)450 T1_TO_T2(str, hxB)
451 {
452   xs_hexBinary n;
453   if (xs_hexBinary::parseString(strval, n))
454     return aFactory->createHexBinary(result, n);
455 
456   throwTypeException( err::FORG0001, aErrorInfo );
457   return false;
458 }
459 
460 
T1_TO_T2(str,aURI)461 T1_TO_T2(str, aURI)
462 {
463   try
464   {
465     URI uriVal(strval);
466     zstring resolvedUri = uriVal.toString();
467     return aFactory->createAnyURI(result, resolvedUri);
468   }
469   catch (ZorbaException& e)
470   {
471     e.set_diagnostic( err::FORG0001 );
472     throw;
473   }
474 }
475 
476 
T1_TO_T2(str,QN)477 T1_TO_T2(str, QN)
478 {
479   ascii::trim_whitespace(strval);
480 
481   zstring::size_type idx = strval.find(":");
482   zstring::size_type lidx = strval.rfind(":", strval.size(), 1);
483 
484   if (idx != lidx)
485     throwTypeException( err::FORG0001, aErrorInfo );
486 
487   zstring nsuri;
488   zstring prefix;
489   zstring local;
490 
491   if (idx == zstring::npos)
492   {
493     if (nsCtx)
494     {
495       nsCtx->findBinding(prefix, nsuri);
496     }
497 
498     local = strval;
499   }
500   else
501   {
502     prefix = strval.substr(0, idx);
503 
504     if (!GenericCast::instance()->castableToNCName(prefix))
505       throwTypeException( err::FORG0001, aErrorInfo );
506 
507     if (nsCtx)
508     {
509       if (!nsCtx->findBinding(prefix, nsuri))
510         throw XQUERY_EXCEPTION( err::FONS0004, ERROR_PARAMS( prefix ) );
511     }
512 
513     local = strval.substr(idx + 1);
514   }
515 
516   if (!GenericCast::instance()->castableToNCName(local))
517     throwTypeException( err::FORG0001, aErrorInfo );
518 
519   return aFactory->createQName(result, nsuri, prefix, local);
520 }
521 
522 
T1_TO_T2(str,NOT)523 T1_TO_T2(str, NOT)
524 {
525   ascii::trim_whitespace(strval);
526 
527   zstring uri;
528   zstring prefix;
529   zstring local;
530 
531   zstring::size_type pos = strval.rfind(":", strval.size(), 1);
532   if (pos != zstring::npos)
533   {
534     prefix = strval.substr(0, pos);
535     local = strval.substr(pos+1, strval.size());
536   }
537   else
538     local = strval;
539 
540   if (!nsCtx->findBinding(prefix, uri))
541     ZORBA_ERROR_DESC_OSS(err::FORG0001, "Prefix '" << prefix << "' not found in current namespace context.");
542 
543   store::Item_t qname;
544   aFactory->createQName(qname, uri, prefix, local);
545   return aFactory->createNOTATION(result, qname);
546 }
547 
548 
T1_TO_T2(uA,str)549 T1_TO_T2(uA, str)
550 {
551   zstring strval2;
552   aItem->getStringValue2(strval2);
553   return aFactory->createString(result, strval2);
554 }
555 
556 
T1_TO_T2(uA,flt)557 T1_TO_T2(uA, flt)
558 {
559   zstring strval2;
560   aItem->getStringValue2(strval2);
561   return str_flt(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
562 }
563 
564 
T1_TO_T2(uA,dbl)565 T1_TO_T2(uA, dbl)
566 {
567   zstring strval2;
568   aItem->getStringValue2(strval2);
569   return str_dbl(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
570 }
571 
572 
T1_TO_T2(uA,dec)573 T1_TO_T2(uA, dec)
574 {
575   zstring strval2;
576   aItem->getStringValue2(strval2);
577   return str_dec(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
578 }
579 
580 
T1_TO_T2(uA,int)581 T1_TO_T2(uA, int)
582 {
583   zstring strval2;
584   aItem->getStringValue2(strval2);
585   return str_int(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
586 }
587 
588 
T1_TO_T2(uA,dur)589 T1_TO_T2(uA, dur)
590 {
591   zstring strval2;
592   aItem->getStringValue2(strval2);
593   return str_dur(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
594 }
595 
596 
T1_TO_T2(uA,yMD)597 T1_TO_T2(uA, yMD)
598 {
599   zstring strval2;
600   aItem->getStringValue2(strval2);
601   return str_yMD(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
602 }
603 
604 
T1_TO_T2(uA,dTD)605 T1_TO_T2(uA, dTD)
606 {
607   zstring strval2;
608   aItem->getStringValue2(strval2);
609   return str_dTD(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
610 }
611 
612 
T1_TO_T2(uA,dT)613 T1_TO_T2(uA, dT)
614 {
615   zstring strval2;
616   aItem->getStringValue2(strval2);
617   return str_dT(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
618 }
619 
620 
T1_TO_T2(uA,tim)621 T1_TO_T2(uA, tim)
622 {
623   zstring strval2;
624   aItem->getStringValue2(strval2);
625   return str_tim(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
626 }
627 
628 
T1_TO_T2(uA,dat)629 T1_TO_T2(uA, dat)
630 {
631   zstring strval2;
632   aItem->getStringValue2(strval2);
633   return str_dat(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
634 }
635 
636 
T1_TO_T2(uA,gYM)637 T1_TO_T2(uA, gYM)
638 {
639   zstring strval2;
640   aItem->getStringValue2(strval2);
641   return str_gYM(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
642 }
643 
644 
T1_TO_T2(uA,gYr)645 T1_TO_T2(uA, gYr)
646 {
647   zstring strval2;
648   aItem->getStringValue2(strval2);
649   return str_gYr(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
650 }
651 
652 
T1_TO_T2(uA,gMD)653 T1_TO_T2(uA, gMD)
654 {
655   zstring strval2;
656   aItem->getStringValue2(strval2);
657   return str_gMD(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
658 }
659 
660 
T1_TO_T2(uA,gDay)661 T1_TO_T2(uA, gDay)
662 {
663   zstring strval2;
664   aItem->getStringValue2(strval2);
665   return str_gDay(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
666 }
667 
668 
T1_TO_T2(uA,gMon)669 T1_TO_T2(uA, gMon)
670 {
671   zstring strval2;
672   aItem->getStringValue2(strval2);
673   return str_gMon(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
674 }
675 
676 
T1_TO_T2(uA,bool)677 T1_TO_T2(uA, bool)
678 {
679   zstring strval2;
680   aItem->getStringValue2(strval2);
681   return str_bool(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
682 }
683 
684 
T1_TO_T2(uA,b64)685 T1_TO_T2(uA, b64)
686 {
687   zstring strval2;
688   aItem->getStringValue2(strval2);
689   return str_b64(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
690 }
691 
692 
T1_TO_T2(uA,hxB)693 T1_TO_T2(uA, hxB)
694 {
695   zstring strval2;
696   aItem->getStringValue2(strval2);
697   return str_hxB(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
698 }
699 
700 
T1_TO_T2(uA,aURI)701 T1_TO_T2(uA, aURI)
702 {
703   zstring strval2;
704   aItem->getStringValue2(strval2);
705   return str_aURI(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
706 }
707 
708 
T1_TO_T2(flt,uA)709 T1_TO_T2(flt, uA)
710 {
711   zstring strval2;
712   aItem->getStringValue2(strval2);
713   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
714 }
715 
716 
T1_TO_T2(flt,str)717 T1_TO_T2(flt, str)
718 {
719   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
720 }
721 
722 
T1_TO_T2(flt,dbl)723 T1_TO_T2(flt, dbl)
724 {
725   return aFactory->createDouble(result, xs_double(aItem->getFloatValue()));
726 }
727 
728 
T1_TO_T2(flt,dec)729 T1_TO_T2(flt, dec)
730 {
731   try
732   {
733     xs_decimal const n( aItem->getFloatValue() );
734     return aFactory->createDecimal(result, n);
735   }
736   catch ( std::exception const& /*e*/ )
737   {
738     throwTypeException( err::FOCA0002, aErrorInfo );
739     return false;
740   }
741 }
742 
743 
T1_TO_T2(flt,int)744 T1_TO_T2(flt, int)
745 {
746   try
747   {
748     return aFactory->createInteger(result, xs_integer(aItem->getFloatValue()));
749   }
750   catch ( std::exception const& )
751   {
752     throwTypeException( err::FOCA0002, aErrorInfo );
753     return false;
754   }
755 }
756 
757 
T1_TO_T2(flt,bool)758 T1_TO_T2(flt, bool)
759 {
760   aFactory->createBoolean(result, aItem->getEBV());
761   return true;
762 }
763 
764 
T1_TO_T2(dbl,uA)765 T1_TO_T2(dbl, uA)
766 {
767   zstring strval2;
768   aItem->getStringValue2(strval2);
769   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
770 }
771 
772 
T1_TO_T2(dbl,str)773 T1_TO_T2(dbl, str)
774 {
775   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
776 }
777 
778 
T1_TO_T2(dbl,flt)779 T1_TO_T2(dbl, flt)
780 {
781   return aFactory->createFloat(result, xs_float(aItem->getDoubleValue()));
782 }
783 
784 
T1_TO_T2(dbl,dec)785 T1_TO_T2(dbl, dec)
786 {
787   try
788   {
789     xs_decimal const n( aItem->getDoubleValue() );
790     return aFactory->createDecimal(result, n);
791   }
792   catch ( std::exception const& )
793   {
794     throwTypeException(err::FOCA0002, aErrorInfo);
795     return false;
796   }
797 }
798 
799 
T1_TO_T2(dbl,int)800 T1_TO_T2(dbl, int)
801 {
802   try
803   {
804     return aFactory->createInteger(result, xs_integer(aItem->getDoubleValue()));
805   }
806   catch ( std::exception const& )
807   {
808     throwTypeException( err::FOCA0002, aErrorInfo );
809     return false;
810   }
811 }
812 
813 
T1_TO_T2(dbl,bool)814 T1_TO_T2(dbl, bool)
815 {
816   aFactory->createBoolean(result, aItem->getEBV());
817   return true;
818 }
819 
820 
T1_TO_T2(dec,uA)821 T1_TO_T2(dec, uA)
822 {
823   zstring strval2;
824   aItem->getStringValue2(strval2);
825   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
826 }
827 
828 
T1_TO_T2(dec,str)829 T1_TO_T2(dec, str)
830 {
831   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
832 }
833 
834 
T1_TO_T2(dec,flt)835 T1_TO_T2(dec, flt)
836 {
837   return aFactory->createFloat(result, xs_float(aItem->getDecimalValue()));
838 }
839 
840 
T1_TO_T2(dec,dbl)841 T1_TO_T2(dec, dbl)
842 {
843   return aFactory->createDouble(result, xs_double(aItem->getDecimalValue()));
844 }
845 
846 
T1_TO_T2(dec,int)847 T1_TO_T2(dec, int)
848 {
849   return aFactory->createInteger(result, xs_integer(aItem->getDecimalValue()));
850 }
851 
852 
T1_TO_T2(dec,bool)853 T1_TO_T2(dec, bool)
854 {
855   aFactory->createBoolean(result, aItem->getEBV());
856   return true;
857 }
858 
859 
T1_TO_T2(int,uA)860 T1_TO_T2(int, uA)
861 {
862   zstring strval2;
863   aItem->getStringValue2(strval2);
864   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
865 }
866 
867 
T1_TO_T2(int,str)868 T1_TO_T2(int, str)
869 {
870   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
871 }
872 
873 
T1_TO_T2(int,flt)874 T1_TO_T2(int, flt)
875 {
876   return aFactory->createFloat(result, xs_float(aItem->getIntegerValue()));
877 }
878 
879 
T1_TO_T2(int,dbl)880 T1_TO_T2(int, dbl)
881 {
882   return aFactory->createDouble(result, xs_double(aItem->getIntegerValue()));
883 }
884 
885 
T1_TO_T2(int,dec)886 T1_TO_T2(int, dec)
887 {
888   return aFactory->createDecimal(result,
889                                  xs_decimal(aItem->getIntegerValue()));
890 }
891 
892 
T1_TO_T2(int,bool)893 T1_TO_T2(int, bool)
894 {
895   aFactory->createBoolean(result, aItem->getEBV());
896   return true;
897 }
898 
899 
T1_TO_T2(dur,uA)900 T1_TO_T2(dur, uA)
901 {
902   zstring strval2;
903   aItem->getStringValue2(strval2);
904   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
905 }
906 
907 
T1_TO_T2(dur,str)908 T1_TO_T2(dur, str)
909 {
910   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
911 }
912 
913 
T1_TO_T2(dur,yMD)914 T1_TO_T2(dur, yMD)
915 {
916   std::auto_ptr<Duration> dur =
917   std::auto_ptr<Duration>(aItem->getDurationValue().toYearMonthDuration());
918   return aFactory->createYearMonthDuration(result, dur.get());
919 }
920 
921 
T1_TO_T2(dur,dTD)922 T1_TO_T2(dur, dTD)
923 {
924   std::auto_ptr<Duration> dur =
925   std::auto_ptr<Duration>(aItem->getDurationValue().toDayTimeDuration());
926   return aFactory->createDayTimeDuration(result, dur.get());
927 }
928 
929 
T1_TO_T2(yMD,uA)930 T1_TO_T2(yMD, uA)
931 {
932   zstring strval2;
933   aItem->getStringValue2(strval2);
934   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
935 }
936 
937 
T1_TO_T2(yMD,str)938 T1_TO_T2(yMD, str)
939 {
940   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
941 }
942 
943 
T1_TO_T2(yMD,dur)944 T1_TO_T2(yMD, dur)
945 {
946   std::auto_ptr<Duration> dur =
947   std::auto_ptr<Duration>(aItem->getYearMonthDurationValue().toDuration());
948   return aFactory->createDuration(result, dur.get());
949 }
950 
951 
T1_TO_T2(yMD,dTD)952 T1_TO_T2(yMD, dTD)
953 {
954   std::auto_ptr<Duration> dur =
955   std::auto_ptr<Duration>(aItem->getYearMonthDurationValue().toDayTimeDuration());
956   return aFactory->createDayTimeDuration(result, dur.get());
957 }
958 
959 
T1_TO_T2(dTD,uA)960 T1_TO_T2(dTD, uA)
961 {
962   zstring strval2;
963   aItem->getStringValue2(strval2);
964   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
965 }
966 
967 
T1_TO_T2(dTD,str)968 T1_TO_T2(dTD, str)
969 {
970   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
971 }
972 
973 
T1_TO_T2(dTD,dur)974 T1_TO_T2(dTD, dur)
975 {
976   std::auto_ptr<Duration> dur =
977   std::auto_ptr<Duration>(aItem->getDayTimeDurationValue().toDuration());
978   return aFactory->createDuration(result, dur.get());
979 }
980 
981 
T1_TO_T2(dTD,yMD)982 T1_TO_T2(dTD, yMD)
983 {
984   std::auto_ptr<Duration> dur =
985   std::auto_ptr<Duration>(aItem->getDayTimeDurationValue().toYearMonthDuration());
986   return aFactory->createYearMonthDuration(result, dur.get());
987 }
988 
989 
T1_TO_T2(dT,uA)990 T1_TO_T2(dT, uA)
991 {
992   zstring strval2;
993   aItem->getStringValue2(strval2);
994   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
995 }
996 
997 
T1_TO_T2(dT,str)998 T1_TO_T2(dT, str)
999 {
1000   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1001 }
1002 
1003 
T1_TO_T2(dT,tim)1004 T1_TO_T2(dT, tim)
1005 {
1006   DateTime dt;
1007   aItem->getDateTimeValue().createWithNewFacet(DateTime::TIME_FACET, dt);
1008   return aFactory->createTime(result, &dt);
1009 }
1010 
1011 
T1_TO_T2(dT,dat)1012 T1_TO_T2(dT, dat)
1013 {
1014   DateTime dt;
1015   aItem->getDateTimeValue().createWithNewFacet(DateTime::DATE_FACET, dt);
1016   return aFactory->createTime(result, &dt);
1017 }
1018 
1019 
T1_TO_T2(dT,gYM)1020 T1_TO_T2(dT, gYM)
1021 {
1022   DateTime dt;
1023   aItem->getDateTimeValue().createWithNewFacet(DateTime::GYEARMONTH_FACET, dt);
1024   return aFactory->createTime(result, &dt);
1025 }
1026 
1027 
T1_TO_T2(dT,gYr)1028 T1_TO_T2(dT, gYr)
1029 {
1030   DateTime dt;
1031   aItem->getDateTimeValue().createWithNewFacet(DateTime::GYEAR_FACET, dt);
1032   return aFactory->createTime(result, &dt);
1033 }
1034 
1035 
T1_TO_T2(dT,gMD)1036 T1_TO_T2(dT, gMD)
1037 {
1038   DateTime dt;
1039   aItem->getDateTimeValue().createWithNewFacet(DateTime::GMONTHDAY_FACET, dt);
1040   return aFactory->createTime(result, &dt);
1041 }
1042 
1043 
T1_TO_T2(dT,gDay)1044 T1_TO_T2(dT, gDay)
1045 {
1046   DateTime dt;
1047   aItem->getDateTimeValue().createWithNewFacet(DateTime::GDAY_FACET, dt);
1048   return aFactory->createTime(result, &dt);
1049 }
1050 
1051 
T1_TO_T2(dT,gMon)1052 T1_TO_T2(dT, gMon)
1053 {
1054   DateTime dt;
1055   aItem->getDateTimeValue().createWithNewFacet(DateTime::GMONTH_FACET, dt);
1056   return aFactory->createTime(result, &dt);
1057 }
1058 
1059 
T1_TO_T2(tim,uA)1060 T1_TO_T2(tim, uA)
1061 {
1062   zstring strval2;
1063   aItem->getStringValue2(strval2);
1064   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1065 }
1066 
1067 
T1_TO_T2(tim,str)1068 T1_TO_T2(tim, str)
1069 {
1070   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1071 }
1072 
1073 
T1_TO_T2(dat,uA)1074 T1_TO_T2(dat, uA)
1075 {
1076   zstring strval2;
1077   aItem->getStringValue2(strval2);
1078   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1079 }
1080 
1081 
T1_TO_T2(dat,str)1082 T1_TO_T2(dat, str)
1083 {
1084   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1085 }
1086 
1087 
T1_TO_T2(dat,dT)1088 T1_TO_T2(dat, dT)
1089 {
1090   DateTime dt;
1091   aItem->getDateValue().createWithNewFacet(DateTime::DATETIME_FACET, dt);
1092   return aFactory->createTime(result, &dt);
1093 }
1094 
1095 
T1_TO_T2(dat,gYM)1096 T1_TO_T2(dat, gYM)
1097 {
1098   DateTime dt;
1099   aItem->getDateValue().createWithNewFacet(DateTime::GYEARMONTH_FACET, dt);
1100   return aFactory->createTime(result, &dt);
1101 }
1102 
1103 
T1_TO_T2(dat,gYr)1104 T1_TO_T2(dat, gYr)
1105 {
1106   DateTime dt;
1107   aItem->getDateValue().createWithNewFacet(DateTime::GYEAR_FACET, dt);
1108   return aFactory->createTime(result, &dt);
1109 }
1110 
1111 
T1_TO_T2(dat,gMD)1112 T1_TO_T2(dat, gMD)
1113 {
1114   DateTime dt;
1115   aItem->getDateValue().createWithNewFacet(DateTime::GMONTHDAY_FACET, dt);
1116   return aFactory->createTime(result, &dt);
1117 }
1118 
1119 
T1_TO_T2(dat,gDay)1120 T1_TO_T2(dat, gDay)
1121 {
1122   DateTime dt;
1123   aItem->getDateValue().createWithNewFacet(DateTime::GDAY_FACET, dt);
1124   return aFactory->createTime(result, &dt);
1125 }
1126 
1127 
T1_TO_T2(dat,gMon)1128 T1_TO_T2(dat, gMon)
1129 {
1130   DateTime dt;
1131   aItem->getDateValue().createWithNewFacet(DateTime::GMONTH_FACET, dt);
1132   return aFactory->createTime(result, &dt);
1133 }
1134 
1135 
T1_TO_T2(gYM,uA)1136 T1_TO_T2(gYM, uA)
1137 {
1138   zstring strval2;
1139   aItem->getStringValue2(strval2);
1140   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1141 }
1142 
1143 
T1_TO_T2(gYM,str)1144 T1_TO_T2(gYM, str)
1145 {
1146   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1147 }
1148 
1149 
T1_TO_T2(gYr,uA)1150 T1_TO_T2(gYr, uA)
1151 {
1152   zstring strval2;
1153   aItem->getStringValue2(strval2);
1154   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1155 }
1156 
1157 
T1_TO_T2(gYr,str)1158 T1_TO_T2(gYr, str)
1159 {
1160   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1161 }
1162 
1163 
T1_TO_T2(gMD,uA)1164 T1_TO_T2(gMD, uA)
1165 {
1166   zstring strval2;
1167   aItem->getStringValue2(strval2);
1168   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1169 }
1170 
1171 
T1_TO_T2(gMD,str)1172 T1_TO_T2(gMD, str)
1173 {
1174   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1175 }
1176 
1177 
T1_TO_T2(gDay,uA)1178 T1_TO_T2(gDay, uA)
1179 {
1180   zstring strval2;
1181   aItem->getStringValue2(strval2);
1182   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1183 }
1184 
1185 
T1_TO_T2(gDay,str)1186 T1_TO_T2(gDay, str)
1187 {
1188   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1189 }
1190 
1191 
T1_TO_T2(gMon,uA)1192 T1_TO_T2(gMon, uA)
1193 {
1194   zstring strval2;
1195   aItem->getStringValue2(strval2);
1196   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1197 }
1198 
1199 
T1_TO_T2(gMon,str)1200 T1_TO_T2(gMon, str)
1201 {
1202   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1203 }
1204 
1205 
T1_TO_T2(bool,uA)1206 T1_TO_T2(bool, uA)
1207 {
1208   zstring strval2;
1209   aItem->getStringValue2(strval2);
1210   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1211 }
1212 
1213 
T1_TO_T2(bool,str)1214 T1_TO_T2(bool, str)
1215 {
1216   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1217 }
1218 
1219 
T1_TO_T2(bool,flt)1220 T1_TO_T2(bool, flt)
1221 {
1222   if (aItem->getBooleanValue())
1223     return aFactory->createFloat(result, xs_float::one());
1224   else
1225     return aFactory->createFloat(result, xs_float::zero());
1226 }
1227 
1228 
T1_TO_T2(bool,dbl)1229 T1_TO_T2(bool, dbl)
1230 {
1231   if (aItem->getBooleanValue())
1232     return aFactory->createDouble(result, xs_double::one());
1233   else
1234     return aFactory->createDouble(result, xs_double::zero());
1235 }
1236 
1237 
T1_TO_T2(bool,dec)1238 T1_TO_T2(bool, dec)
1239 {
1240   if (aItem->getBooleanValue())
1241     return aFactory->createDecimal(result, xs_decimal::one());
1242   else
1243     return aFactory->createDecimal(result, xs_decimal::zero());
1244 }
1245 
1246 
T1_TO_T2(bool,int)1247 T1_TO_T2(bool, int)
1248 {
1249   if (aItem->getBooleanValue())
1250     return aFactory->createInteger(result, xs_integer::one());
1251   else
1252     return aFactory->createInteger(result, xs_integer::zero());
1253 }
1254 
1255 
T1_TO_T2(b64,uA)1256 T1_TO_T2(b64, uA)
1257 {
1258   zstring strval2;
1259   aItem->getStringValue2(strval2);
1260   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1261 }
1262 
1263 
T1_TO_T2(b64,str)1264 T1_TO_T2(b64, str)
1265 {
1266   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1267 }
1268 
1269 
T1_TO_T2(b64,hxB)1270 T1_TO_T2(b64, hxB)
1271 {
1272   size_t s;
1273   const char* c = aItem->getBase64BinaryValue(s);
1274   Base64 tmp;
1275   if (aItem->isEncoded())
1276   {
1277     Base64::parseString(c, s, tmp);
1278   }
1279   else
1280   {
1281     Base64::encode((const unsigned char*)c, s, tmp);
1282   }
1283   return aFactory->createHexBinary(result, xs_hexBinary(tmp));
1284 }
1285 
1286 
T1_TO_T2(hxB,uA)1287 T1_TO_T2(hxB, uA)
1288 {
1289   zstring strval2;
1290   aItem->getStringValue2(strval2);
1291   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1292 }
1293 
1294 
T1_TO_T2(hxB,str)1295 T1_TO_T2(hxB, str)
1296 {
1297   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1298 }
1299 
1300 
T1_TO_T2(hxB,b64)1301 T1_TO_T2(hxB, b64)
1302 {
1303   return aFactory->createBase64Binary(result,
1304                                       xs_base64Binary(aItem->getHexBinaryValue()));
1305 }
1306 
1307 
T1_TO_T2(aURI,uA)1308 T1_TO_T2(aURI, uA)
1309 {
1310   zstring strval2;
1311   aItem->getStringValue2(strval2);
1312   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1313 }
1314 
1315 
T1_TO_T2(aURI,str)1316 T1_TO_T2(aURI, str)
1317 {
1318   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1319 }
1320 
1321 
T1_TO_T2(QN,uA)1322 T1_TO_T2(QN, uA)
1323 {
1324   zstring strval2;
1325   aItem->getStringValue2(strval2);
1326   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1327 }
1328 
1329 
T1_TO_T2(QN,str)1330 T1_TO_T2(QN, str)
1331 {
1332   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1333 }
1334 
1335 
T1_TO_T2(NOT,uA)1336 T1_TO_T2(NOT, uA)
1337 {
1338   zstring strval2;
1339   aItem->getStringValue2(strval2);
1340   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1341 }
1342 
1343 
T1_TO_T2(NOT,str)1344 T1_TO_T2(NOT, str)
1345 {
1346   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1347 }
1348 
T1_TO_T2(uint,uA)1349 T1_TO_T2(uint, uA)
1350 {
1351   zstring strval2;
1352   aItem->getStringValue2(strval2);
1353   return str_uA(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1354 }
1355 
1356 
T1_TO_T2(uint,str)1357 T1_TO_T2(uint, str)
1358 {
1359   return uA_str(result, aItem, strval, aFactory, nsCtx, aErrorInfo);
1360 }
1361 
1362 
T1_TO_T2(uint,flt)1363 T1_TO_T2(uint, flt)
1364 {
1365   return aFactory->createFloat(
1366     result, xs_float(aItem->getUnsignedIntegerValue())
1367   );
1368 }
1369 
1370 
T1_TO_T2(uint,dbl)1371 T1_TO_T2(uint, dbl)
1372 {
1373   return aFactory->createDouble(
1374     result, xs_double(aItem->getUnsignedIntegerValue())
1375   );
1376 }
1377 
1378 
T1_TO_T2(uint,dec)1379 T1_TO_T2(uint, dec)
1380 {
1381   return aFactory->createDecimal(
1382     result, xs_decimal(aItem->getUnsignedIntegerValue())
1383   );
1384 }
1385 
1386 
T1_TO_T2(uint,bool)1387 T1_TO_T2(uint, bool)
1388 {
1389   aFactory->createBoolean(result, aItem->getEBV());
1390   return true;
1391 }
1392 
1393 
T1_TO_T2(uA,uint)1394 T1_TO_T2(uA, uint)
1395 {
1396   zstring strval2;
1397   aItem->getStringValue2(strval2);
1398   return str_int(result, aItem, strval2, aFactory, nsCtx, aErrorInfo);
1399 }
1400 
1401 
T1_TO_T2(flt,uint)1402 T1_TO_T2(flt, uint)
1403 {
1404   try
1405   {
1406     xs_nonNegativeInteger const n(aItem->getFloatValue());
1407     return aFactory->createNonNegativeInteger(result, n);
1408   }
1409   catch ( std::exception const& )
1410   {
1411     throwTypeException( err::FOCA0002, aErrorInfo );
1412     return false;
1413   }
1414 }
1415 
1416 
T1_TO_T2(int,uint)1417 T1_TO_T2(int, uint)
1418 {
1419   try
1420   {
1421     xs_nonNegativeInteger const n(aItem->getIntegerValue());
1422     return aFactory->createNonNegativeInteger(result, n);
1423   }
1424   catch ( std::exception const& )
1425   {
1426     throwTypeException( err::FOCA0002, aErrorInfo );
1427     return false;
1428   }
1429 }
1430 
1431 
T1_TO_T2(uint,int)1432 T1_TO_T2(uint, int)
1433 {
1434   try
1435   {
1436     xs_integer const n(aItem->getIntegerValue());
1437     return aFactory->createInteger(result, n);
1438   }
1439   catch ( std::exception const& )
1440   {
1441     throwTypeException( err::FOCA0002, aErrorInfo );
1442     return false;
1443   }
1444 }
1445 
1446 
T1_TO_T2(dbl,uint)1447 T1_TO_T2(dbl, uint)
1448 {
1449   try
1450   {
1451     xs_nonNegativeInteger const n(aItem->getDoubleValue());
1452     return aFactory->createInteger(result, n);
1453   }
1454   catch ( std::exception const& )
1455   {
1456     throwTypeException( err::FOCA0002, aErrorInfo );
1457     return false;
1458   }
1459 }
1460 
1461 
T1_TO_T2(dec,uint)1462 T1_TO_T2(dec, uint)
1463 {
1464   xs_nonNegativeInteger const n(aItem->getDecimalValue());
1465   return aFactory->createNonNegativeInteger(result, n);
1466 }
1467 
1468 
T1_TO_T2(bool,uint)1469 T1_TO_T2(bool, uint)
1470 {
1471   if (aItem->getBooleanValue())
1472     return aFactory->createNonNegativeInteger(
1473       result, xs_nonNegativeInteger::one()
1474     );
1475   else
1476     return aFactory->createNonNegativeInteger(
1477       result, xs_nonNegativeInteger::zero()
1478     );
1479 }
1480 
1481 
T1_TO_T2(str,uint)1482 T1_TO_T2(str, uint)
1483 {
1484   try {
1485     xs_nonNegativeInteger const n(strval.c_str());
1486     return aFactory->createNonNegativeInteger(result, n);
1487   }
1488   catch ( std::invalid_argument const& ) {
1489     throwTypeException( err::FORG0001, aErrorInfo );
1490   }
1491   catch ( std::range_error const& ) {
1492     throwTypeException( err::FOCA0002, aErrorInfo );
1493   }
1494   return false;
1495 }
1496 
T1_TO_T2(NUL,str)1497 T1_TO_T2(NUL, str)
1498 {
1499   zstring val("null");
1500   return aFactory->createString(result, val);
1501 }
1502 
1503 
1504 /*******************************************************************************
1505 
1506 ********************************************************************************/
str_down(store::Item_t & result,const store::Item * aItem,ATOMIC_CODE_T aTargetAtomicType,store::ItemFactory * aFactory,const ErrorInfo & aErrorInfo)1507 bool str_down(
1508     store::Item_t& result,
1509     const store::Item* aItem,
1510     ATOMIC_CODE_T aTargetAtomicType,
1511     store::ItemFactory* aFactory,
1512     const ErrorInfo& aErrorInfo)
1513 {
1514   zstring strval;
1515   aItem->getStringValue2(strval);
1516 
1517   switch(aTargetAtomicType)
1518   {
1519   case store::XS_NORMALIZED_STRING:
1520   {
1521     if (GenericCast::instance()->castableToNormalizedString(strval))
1522       return aFactory->createNormalizedString(result, strval);
1523     break;
1524   }
1525   case store::XS_TOKEN:
1526   {
1527     if (GenericCast::instance()->castableToToken(strval))
1528       return aFactory->createToken(result, strval);
1529     break;
1530   }
1531   case store::XS_LANGUAGE:
1532   {
1533     if (GenericCast::instance()->castableToLanguage(strval))
1534       return aFactory->createLanguage(result, strval);
1535     break;
1536   }
1537   case store::XS_NMTOKEN:
1538   {
1539     ascii::trim_whitespace(strval);
1540 
1541     if (GenericCast::instance()->castableToNMToken(strval))
1542     {
1543       return aFactory->createNMTOKEN(result, strval);
1544     }
1545     break;
1546   }
1547   case store::XS_NAME:
1548   {
1549     ascii::trim_whitespace(strval);
1550 
1551     if (GenericCast::instance()->castableToName(strval))
1552     {
1553       return aFactory->createName(result, strval);
1554     }
1555     break;
1556   }
1557   case store::XS_NCNAME:
1558   {
1559     ascii::normalize_whitespace(strval);
1560     ascii::trim_whitespace(strval);
1561 
1562     if (GenericCast::instance()->castableToNCName(strval))
1563     {
1564       return aFactory->createNCName(result, strval);
1565     }
1566     break;
1567   }
1568   case store::XS_ID:
1569   {
1570     if (GenericCast::instance()->castableToNCName(strval))
1571       return aFactory->createID(result, strval);
1572     break;
1573   }
1574   case store::XS_IDREF:
1575   {
1576     if (GenericCast::instance()->castableToNCName(strval))
1577       return aFactory->createIDREF(result, strval);
1578     break;
1579   }
1580   case store::XS_ENTITY:
1581   {
1582     if (GenericCast::instance()->castableToNCName(strval))
1583       return aFactory->createENTITY(result, strval);
1584     break;
1585   }
1586   default:
1587     ZORBA_ASSERT(false);
1588   }
1589 
1590   throwTypeException( err::FORG0001, aErrorInfo );
1591   return false;
1592 }
1593 
1594 
1595 /*******************************************************************************
1596 
1597 ********************************************************************************/
int_down(store::Item_t & result,const store::Item * aItem,ATOMIC_CODE_T aTargetAtomicType,store::ItemFactory * aFactory,const ErrorInfo & aErrorInfo)1598 bool int_down(
1599     store::Item_t& result,
1600     const store::Item* aItem,
1601     ATOMIC_CODE_T aTargetAtomicType,
1602     store::ItemFactory* aFactory,
1603     const ErrorInfo& aErrorInfo)
1604 {
1605   switch(aTargetAtomicType)
1606   {
1607   case store::XS_NON_POSITIVE_INTEGER:
1608   {
1609     xs_integer const lInteger = aItem->getIntegerValue();
1610     if (lInteger.sign() <= 0)
1611       return aFactory->createNonPositiveInteger(result, lInteger);
1612     break;
1613   }
1614   case store::XS_NEGATIVE_INTEGER:
1615   {
1616     xs_integer const lInteger = aItem->getIntegerValue();
1617     if (lInteger.sign() < 0)
1618       return aFactory->createNegativeInteger(result, lInteger);
1619     break;
1620   }
1621   case store::XS_LONG:
1622   {
1623     zstring lString;
1624     aItem->getStringValue2(lString);
1625     try
1626     {
1627       xs_long const n = ztd::aton<xs_long>(lString.c_str());
1628       return aFactory->createLong(result, n);
1629     }
1630     catch ( std::exception const& )
1631     {
1632       // ignore
1633     }
1634     break;
1635   }
1636   case store::XS_INT:
1637   {
1638     zstring lString;
1639     aItem->getStringValue2(lString);
1640     try
1641     {
1642       xs_int const n = ztd::aton<xs_int>(lString.c_str());
1643       return aFactory->createInt(result, n);
1644     }
1645     catch ( std::exception const& )
1646     {
1647       // ignore
1648     }
1649     break;
1650   }
1651   case store::XS_SHORT:
1652   {
1653     zstring lString;
1654     aItem->getStringValue2(lString);
1655     try
1656     {
1657       xs_short const n = ztd::aton<xs_short>(lString.c_str());
1658       return aFactory->createShort(result, n);
1659     }
1660     catch ( std::exception const& )
1661     {
1662       // ignore
1663     }
1664     break;
1665   }
1666   case store::XS_BYTE:
1667   {
1668     zstring lString;
1669     aItem->getStringValue2(lString);
1670     try
1671     {
1672       xs_byte const n = ztd::aton<xs_byte>(lString.c_str());
1673       return aFactory->createByte(result, n);
1674     }
1675     catch ( std::exception const& )
1676     {
1677       // ignore
1678     }
1679     break;
1680   }
1681   case store::XS_NON_NEGATIVE_INTEGER:
1682   {
1683     xs_decimal const d = aItem->getDecimalValue();
1684     if (d.sign() >= 0)
1685       try {
1686         xs_nonNegativeInteger const i(d);
1687         return aFactory->createNonNegativeInteger(result, i);
1688       }
1689       catch ( std::exception const& ) {
1690         // ignore
1691       }
1692     break;
1693   }
1694   case store::XS_UNSIGNED_LONG:
1695   {
1696     zstring lString;
1697     aItem->getStringValue2(lString);
1698     try
1699     {
1700       xs_unsignedLong const n = ztd::aton<xs_unsignedLong>(lString.c_str());
1701       return aFactory->createUnsignedLong(result, n);
1702     }
1703     catch ( std::exception const& )
1704     {
1705       // ignore
1706     }
1707     break;
1708   }
1709   case store::XS_UNSIGNED_INT:
1710   {
1711     zstring lString;
1712     aItem->getStringValue2(lString);
1713     try
1714     {
1715       xs_unsignedInt const n = ztd::aton<xs_unsignedInt>(lString.c_str());
1716       return aFactory->createUnsignedInt(result, n);
1717     }
1718     catch ( std::exception const& )
1719     {
1720       // ignore
1721     }
1722     break;
1723   }
1724   case store::XS_UNSIGNED_SHORT:
1725   {
1726     zstring lString;
1727     aItem->getStringValue2(lString);
1728     try
1729     {
1730       xs_unsignedShort const n = ztd::aton<xs_unsignedShort>(lString.c_str());
1731       return aFactory->createUnsignedShort(result, n);
1732     }
1733     catch ( std::exception const& )
1734     {
1735       // ignore
1736     }
1737     break;
1738   }
1739   case store::XS_UNSIGNED_BYTE:
1740   {
1741     zstring lString;
1742     aItem->getStringValue2(lString);
1743     try
1744     {
1745       xs_unsignedByte const n = ztd::aton<xs_unsignedByte>(lString.c_str());
1746       return aFactory->createUnsignedByte(result, n);
1747     }
1748     catch ( std::exception const& )
1749     {
1750       // ignore
1751     }
1752     break;
1753   }
1754   case store::XS_POSITIVE_INTEGER:
1755   {
1756     xs_positiveInteger const i = aItem->getUnsignedIntegerValue();
1757     if (i.sign() > 0)
1758       return aFactory->createPositiveInteger(result, i);
1759     break;
1760   }
1761   default:
1762     ZORBA_ASSERT (false);
1763   }
1764 
1765   throwTypeException( err::FORG0001, aErrorInfo );
1766   return false;
1767 }
1768 
1769 
1770 /*******************************************************************************
1771   For each builtin atomic type T, this array maps the typecode of T to an
1772   index to be used in addessing theCastingMatrix.
1773 ********************************************************************************/
1774 const int GenericCast::theMapping[store::XS_LAST] =
1775 {
1776   -1,  //  0 XS_ANY_ATOMIC
1777    1,  //  1 XS_STRING
1778    1,  //  2 XS_NORMALIZED_STRING
1779    1,  //  3 XS_TOKEN
1780    1,  //  4 XS_LANGUAGE
1781    1,  //  5 XS_NMTOKEN
1782    1,  //  6 XS_NAME
1783    1,  //  7 XS_NCNAME
1784    1,  //  8 XS_ID
1785    1,  //  9 XS_IDREF
1786    1,  // 10 XS_ENTITY
1787    0,  // 11 XS_UNTYPED_ATOMIC
1788    9,  // 12 XS_DATETIME
1789   11,  // 13 XS_DATE
1790   10,  // 14 XS_TIME
1791    6,  // 15 XS_DURATION
1792    8,  // 16 XS_DT_DURATION
1793    7,  // 17 XS_YM_DURATION
1794    2,  // 18 XS_FLOAT
1795    3,  // 19 XS_DOUBLE
1796    4,  // 20 XS_DECIMAL
1797    5,  // 21 XS_INTEGER
1798    5,  // 22 XS_NON_POSITIVE_INTEGER
1799    5,  // 23 XS_NEGATIVE_INTEGER
1800    5,  // 24 XS_LONG
1801    5,  // 25 XS_INT
1802    5,  // 26 XS_SHORT
1803    5,  // 27 XS_BYTE
1804   23,  // 28 XS_NON_NEGATIVE_INTEGER
1805   23,  // 29 XS_UNSIGNED_LONG
1806   23,  // 30 XS_UNSIGNED_INT
1807   23,  // 31 XS_UNSIGNED_SHORT
1808   23,  // 32 XS_UNSIGNED_BYTE
1809   23,  // 33 XS_POSITIVE_INTEGER
1810   12,  // 34 XS_GYEAR_MONTH
1811   13,  // 35 XS_GYEAR
1812   14,  // 36 XS_GMONTH_DAY
1813   15,  // 37 XS_GDAY
1814   16,  // 38 XS_GMONTH
1815   17,  // 39 XS_BOOLEAN
1816   18,  // 40 XS_BASE64BINARY
1817   19,  // 41 XS_HEXBINARY
1818   20,  // 42 XS_ANY_URI
1819   21,  // 43 XS_QNAME
1820   22,  // 44 XS_NOTATION
1821   23   // 45 JS_NULL
1822 };
1823 
1824 
1825 /*******************************************************************************
1826 
1827 ********************************************************************************/
1828 const GenericCast::DownCastFunc GenericCast::theDownCastMatrix[25] =
1829 {
1830 /*uA*/    0,
1831 /*str*/   str_down,
1832 /*flt*/   0,
1833 /*dbl*/   0,
1834 /*dec*/   0,
1835 /*int*/   int_down,
1836 /*dur*/   0,
1837 /*yMD*/   0,
1838 /*dTD*/   0,
1839 /*dT*/    0,
1840 /*tim*/   0,
1841 /*dat*/   0,
1842 /*gYM*/   0,
1843 /*gYr*/   0,
1844 /*gMD*/   0,
1845 /*gDay*/  0,
1846 /*gMon*/  0,
1847 /*bool*/  0,
1848 /*b64*/   0,
1849 /*hxB*/   0,
1850 /*aURI*/  0,
1851 /*QN*/    0,
1852 /*NOT*/   0,
1853 /*uint*/  int_down,
1854 /*null*/  0
1855 };
1856 
1857 
1858 /*******************************************************************************
1859 
1860 ********************************************************************************/
1861 const GenericCast::CastFunc GenericCast::theCastMatrix[25][25] =
1862 {
1863 // uA        str        flt       dbl         dec        int       dur       yMD
1864 // dTD       dT         tim       dat         gYM        gYr       gMD       gDay
1865 // gMon      bool       b64       hxB         aURI       QN        NOT       uint
1866 // null
1867 
1868 {&uA_uA,    &uA_str,   &uA_flt,  &uA_dbl ,   &uA_dec ,  &uA_int,   &uA_dur,  &uA_yMD,
1869  &uA_dTD,   &uA_dT,    &uA_tim,  &uA_dat,    &uA_gYM ,  &uA_gYr ,  &uA_gMD,  &uA_gDay,
1870  &uA_gMon, &uA_bool,   &uA_b64,  &uA_hxB,    &uA_aURI,  0,         0,        &uA_uint,
1871  0}, // uA
1872 
1873 {&str_uA,   &str_str,  &str_flt,  &str_dbl,  &str_dec,  &str_int,  &str_dur, &str_yMD,
1874  &str_dTD,  &str_dT,   &str_tim,  &str_dat,  &str_gYM,  &str_gYr,  &str_gMD, &str_gDay,
1875  &str_gMon, &str_bool, &str_b64,  &str_hxB,  &str_aURI, &str_QN,   &str_NOT, &str_uint,
1876  0}, // str
1877 
1878 {&flt_uA,   &flt_str,  &flt_flt,  &flt_dbl,  &flt_dec,  &flt_int,  0,        0,
1879  0,         0,         0,         0,         0,         0,         0,        0,
1880  0,         &flt_bool, 0,         0,         0,         0,         0,        &flt_uint,
1881  0}, // flt
1882 
1883 {&dbl_uA,   &dbl_str,  &dbl_flt,  &dbl_dbl,  &dbl_dec,  &dbl_int,  0,        0,
1884  0,         0,         0,         0,         0,         0,         0,        0,
1885  0,         &dbl_bool, 0,         0,         0,         0,         0,        &dbl_uint,
1886  0}, // dbl
1887 
1888 {&dec_uA,   &dec_str,  &dec_flt,  &dec_dbl,  &dec_dec,  &dec_int,  0,        0,
1889  0,         0,         0,         0,         0,         0,         0,        0,
1890  0,         &dec_bool, 0,         0,         0,         0,         0,        &dec_uint,
1891  0}, // dec
1892 
1893 {&int_uA,   &int_str,  &int_flt,  &int_dbl,  &int_dec,  &int_int,  0,        0,
1894  0,         0,         0,         0,         0,         0,         0,        0,
1895  0,         &int_bool, 0,         0,         0,         0,         0,        &int_uint,
1896  0}, // int
1897 
1898 {&dur_uA,   &dur_str,  0,         0,         0,         0,         &dur_dur, &dur_yMD,
1899  &dur_dTD,  0,         0,         0,         0,         0,         0,        0,
1900  0,         0,         0,         0,         0,         0,         0,        0,
1901  0}, // dur
1902 
1903 {&yMD_uA,   &yMD_str,  0,         0,         0,         0,         &yMD_dur, &yMD_yMD,
1904  &yMD_dTD,  0,         0,         0,         0,         0,         0,        0,
1905  0,         0,         0,         0,         0,         0,         0,        0,
1906  0}, // yMD
1907 
1908 {&dTD_uA,   &dTD_str,  0,         0,         0,         0,         &dTD_dur, &dTD_yMD,
1909  &dTD_dTD,  0,         0,         0,         0,         0,         0,        0,
1910  0,         0,         0,         0,         0,         0,         0,        0,
1911  0}, // dTD
1912 
1913 {&dT_uA,    &dT_str,   0,         0,         0,         0,         0,        0,
1914  0,         &dT_dT,    &dT_tim,   &dT_dat,   &dT_gYM,   &dT_gYr,   &dT_gMD,  &dT_gDay,
1915  &dT_gMon,  0,         0,         0,         0,         0,         0,        0,
1916  0}, // dT
1917 
1918 {&tim_uA,   &tim_str,  0,         0,         0,         0,         0,        0,
1919  0,         0,         &tim_tim,  0,         0,         0,         0,        0,
1920  0,         0,         0,         0,         0,         0,         0,        0,
1921  0}, // tim
1922 
1923 {&dat_uA,   &dat_str,  0,         0,         0,         0,         0,        0,
1924  0,         &dat_dT,   0,         &dat_dat,  &dat_gYM,  &dat_gYr,  &dat_gMD, &dat_gDay,
1925  &dat_gMon, 0,         0,         0,         0,         0,         0,        0,
1926  0}, // dat
1927 
1928 {&gYM_uA,   &gYM_str,  0,         0,         0,         0,         0,        0,
1929  0,         0,         0,         0,         &gYM_gYM,  0,         0,        0,
1930  0,         0,         0,         0,         0,         0,         0,        0,
1931  0}, // gYM
1932 
1933 {&gYr_uA,   &gYr_str,  0,         0,         0,         0,         0,        0,
1934  0,         0,         0,         0,         0,         &gYr_gYr,  0,        0,
1935  0,         0,         0,         0,         0,         0,         0,        0,
1936  0}, // gYr
1937 
1938 {&gMD_uA,   &gMD_str,  0,         0,         0,         0,         0,        0,
1939  0,         0,         0,         0,         0,         0,         &gMD_gMD, 0,
1940  0,         0,         0,         0,         0,         0,         0,        0,
1941  0}, // gMD
1942 
1943 {&gDay_uA,  &gDay_str, 0,         0,         0,         0,         0,        0,
1944  0,         0,         0,         0,         0,         0,         0,        &gDay_gDay,
1945  0,         0,         0,         0,         0,         0,         0,        0,
1946  0}, // gDay
1947 
1948 {&gMon_uA,  &gMon_str, 0,         0,         0,         0,         0,        0,
1949  0,         0,         0,         0,         0,         0,         0,        0,
1950  &gMon_gMon,0,         0,         0,         0,         0,         0,        0,
1951  0}, // gMon
1952 
1953 {&bool_uA,  &bool_str, &bool_flt, &bool_dbl, &bool_dec, &bool_int, 0,        0,
1954  0,         0,         0,         0,         0,         0,         0,        0,
1955  0,         &bool_bool,0,         0,         0,         0,         0,        &bool_uint,
1956  0}, // bool
1957 
1958 {&b64_uA,   &b64_str,  0,         0,         0,         0,         0,        0,
1959  0,         0,         0,         0,         0,         0,         0,        0,
1960  0,         0,         &b64_b64,  &b64_hxB,  0,         0,         0,        0,
1961  0}, // b64
1962 
1963 {&hxB_uA,   &hxB_str,  0,         0,         0,         0,         0,        0,
1964  0,         0,         0,         0,         0,         0,         0,        0,
1965  0,         0,         &hxB_b64,  &hxB_hxB,  0,         0,         0,        0,
1966  0}, // hxB
1967 
1968 {&aURI_uA,  &aURI_str, 0,         0,         0,         0,         0,        0,
1969  0,         0,         0,         0,         0,         0,         0,        0,
1970  0,         0,         0,         0,         &aURI_aURI,0,         0,        0,
1971  0}, // aURI
1972 
1973 {&QN_uA,    &QN_str,   0,         0,         0,         0,         0,        0,
1974  0,         0,         0,         0,         0,         0,         0,        0,
1975  0,         0,         0,         0,         0,         &QN_QN,    0,        0,
1976  0}, // QN
1977 
1978 {&NOT_uA,   &NOT_str,  0,         0,         0,         0,         0,        0,
1979  0,         0,         0,         0,         0,         0,         0,        0,
1980  0,         0,         0,         0,         0,         0,         &NOT_NOT, 0,
1981  0}, // NOT
1982 
1983 {&uint_uA,  &uint_str, &uint_flt, &uint_dbl, &uint_dec, &uint_int, 0,        0,
1984  0,         0,         0,         0,         0,         0,         0,        0,
1985  0,         &uint_bool,0,         0,         0,         0,         0,        &uint_uint,
1986  0},
1987 
1988 {0,         &NUL_str,  0,         0,         0,         0,         0,        0,
1989  0,         0,         0,         0,         0,         0,         0,        0,
1990  0,         0,         0,         0,         0,         0,         0,        0,
1991  &NUL_NUL} // NUL
1992 };
1993 
1994 
1995 
1996 /*******************************************************************************
1997 
1998 ********************************************************************************/
instance()1999 GenericCast* GenericCast::instance()
2000 {
2001   static GenericCast aGenericCast;
2002   return &aGenericCast;
2003 }
2004 
2005 
2006 /*******************************************************************************
2007 
2008 ********************************************************************************/
castToAtomic(store::Item_t & result,zstring & str,const XQType * targetType,const TypeManager * tm,namespace_context * aNsCtx,const QueryLoc & loc)2009 bool GenericCast::castToAtomic(
2010     store::Item_t& result,
2011     zstring& str,
2012     const XQType* targetType,
2013     const TypeManager* tm,
2014     namespace_context* aNsCtx,
2015     const QueryLoc& loc)
2016 {
2017   RootTypeManager& rtm = GENV_TYPESYSTEM;
2018   store::ItemFactory* lFactory = GENV_ITEMFACTORY;
2019 
2020   const XQType* sourceType = rtm.STRING_TYPE_ONE.getp();
2021 
2022   ErrorInfo lErrorInfo(sourceType, targetType, loc);
2023 
2024   if (!TypeOps::is_atomic(tm, *targetType))
2025     RAISE_ERROR(err::XPST0051, loc, ERROR_PARAMS(targetType));
2026 
2027 #ifndef ZORBA_NO_XMLSCHEMA
2028   if (targetType->type_kind() == XQType::USER_DEFINED_KIND)
2029   {
2030     store::Item_t baseItem;
2031 
2032     bool success = tm->getSchema()->parseUserAtomicTypes(str,
2033                                                          targetType,
2034                                                          baseItem,
2035                                                          aNsCtx,
2036                                                          loc);
2037     if (success)
2038     {
2039       const UserDefinedXQType* udt = static_cast<const UserDefinedXQType*>(targetType);
2040       store::Item_t typeName = udt->get_qname();
2041 
2042       GENV_ITEMFACTORY->createUserTypedAtomicItem(result, baseItem, typeName);
2043       return true;
2044     }
2045 
2046     return false;
2047   }
2048 #endif
2049 
2050   store::Item_t lItem;
2051   ATOMIC_CODE_T sourceTypeCode = store::XS_STRING;
2052   ATOMIC_CODE_T targetTypeCode = TypeOps::get_atomic_type_code(*targetType);
2053   bool valid = true;
2054 
2055   if (theMapping[sourceTypeCode] == theMapping[targetTypeCode])
2056   {
2057     lFactory->createString(result, str);
2058   }
2059   else
2060   {
2061     CastFunc lCastFunc = theCastMatrix[theMapping[sourceTypeCode]]
2062                                       [theMapping[targetTypeCode]];
2063     if (lCastFunc == 0)
2064       throwTypeException(err::XPTY0004, lErrorInfo);
2065 
2066     valid = (*lCastFunc)(result,
2067                          lItem,
2068                          str,
2069                          lFactory,
2070                          aNsCtx,
2071                          lErrorInfo);
2072   }
2073 
2074   DownCastFunc lDownCastFunc = theDownCastMatrix[theMapping[targetTypeCode]];
2075 
2076   if (lDownCastFunc != 0 &&
2077       targetTypeCode != store::XS_STRING &&
2078       targetTypeCode != store::XS_INTEGER)
2079   {
2080     valid = (*lDownCastFunc)(result,
2081                              &*result,
2082                              targetTypeCode,
2083                              lFactory,
2084                              lErrorInfo);
2085   }
2086 
2087   return valid;
2088 }
2089 
2090 
2091 /*******************************************************************************
2092   Cast, if possible, a given atomic item SI to an atomic item TI of a given
2093   type TT. If the cast is not allowed, the method raises an error. If the cast
2094   is not possible, the method may raise an error or return false (TODO fix
2095   this!). Otherwise, it returns true.
2096 ********************************************************************************/
castToAtomic(store::Item_t & result,store::Item_t & aItem,const XQType * targetType,const TypeManager * tm,namespace_context * nsCtx,const QueryLoc & loc)2097 bool GenericCast::castToAtomic(
2098     store::Item_t&       result,
2099     store::Item_t&       aItem,
2100     const XQType*        targetType,
2101     const TypeManager*   tm,
2102     namespace_context*   nsCtx,
2103     const QueryLoc&      loc)
2104 {
2105   store::ItemFactory* factory = GENV_ITEMFACTORY;
2106 
2107   ZORBA_ASSERT(aItem->isAtomic());
2108 
2109   xqtref_t sourceType = tm->create_named_type(aItem->getType(),
2110                                               TypeConstants::QUANT_ONE,
2111                                               QueryLoc::null,
2112                                               err::XPTY0004);
2113   ZORBA_ASSERT(sourceType != NULL);
2114   assert(TypeOps::is_atomic(tm, *sourceType));
2115 
2116   // std::cout << "-castToAtomic: " << aItem.getp()->getStringValue()->c_str()
2117   //           << " srcType: " << sourceType->get_qname()->getLocalName()->c_str()
2118   //           << " @ " << sourceType->get_qname()->getNamespace()->c_str() << "\n";
2119   // std::cout << "\t\t  tgtType: " << aTargetType->get_qname()->getLocalName()->c_str()
2120   //           << " @ " << aTargetType->get_qname()->getNamespace()->c_str() << "\n";
2121 
2122   ErrorInfo errorInfo(sourceType.getp(), targetType, loc);
2123 
2124   if (!TypeOps::is_atomic(tm, *targetType))
2125     RAISE_ERROR(err::XPST0051, loc, ERROR_PARAMS(targetType));
2126 
2127 #ifndef ZORBA_NO_XMLSCHEMA
2128   if (targetType->type_kind() == XQType::USER_DEFINED_KIND)
2129   {
2130     castToUserDefinedType(result, aItem, sourceType.getp(), targetType, loc);
2131     return result != NULL;
2132   }
2133 #endif // ZORBA_NO_XMLSCHEMA
2134 
2135   sourceType = sourceType->getBaseBuiltinType();
2136 
2137   zstring sourceString;
2138   ATOMIC_CODE_T sourceTypeCode = TypeOps::get_atomic_type_code(*sourceType);
2139   ATOMIC_CODE_T targetTypeCode = TypeOps::get_atomic_type_code(*targetType);
2140 
2141   if (sourceTypeCode == targetTypeCode)
2142   {
2143     result.transfer(aItem);
2144     return true;
2145   }
2146 
2147   if (targetTypeCode == store::XS_NOTATION ||
2148       targetTypeCode == store::XS_ANY_ATOMIC)
2149   {
2150     RAISE_ERROR(err::XPST0080, loc, ERROR_PARAMS(*errorInfo.theTargetType));
2151   }
2152 
2153   if (sourceTypeCode == store::XS_ANY_ATOMIC)
2154     throwTypeException(err::XPTY0004, errorInfo);
2155 
2156   if (targetTypeCode == store::XS_NCNAME &&
2157       sourceTypeCode != store::XS_STRING &&
2158       sourceTypeCode != store::XS_NCNAME &&
2159       sourceTypeCode != store::XS_UNTYPED_ATOMIC)
2160     throwTypeException(err::XPTY0004, errorInfo);
2161 
2162   if (targetTypeCode == store::JS_NULL)
2163     throwTypeException(err::XPTY0004, errorInfo);
2164 
2165   CastFunc castFunc = theCastMatrix[theMapping[sourceTypeCode]]
2166                                     [theMapping[targetTypeCode]];
2167   if (castFunc == 0)
2168     throwTypeException(err::XPTY0004, errorInfo);
2169 
2170   if (theMapping[sourceTypeCode] == theMapping[store::XS_STRING])
2171   {
2172     aItem->getStringValue2(sourceString);
2173   }
2174 
2175   bool valid = (*castFunc)(result,
2176                            aItem,
2177                            sourceString,
2178                            factory,
2179                            nsCtx,
2180                            errorInfo);
2181 
2182   DownCastFunc downCastFunc = theDownCastMatrix[theMapping[targetTypeCode]];
2183 
2184   if (downCastFunc != 0 &&
2185       targetTypeCode != store::XS_STRING &&
2186       targetTypeCode != store::XS_INTEGER)
2187   {
2188     valid = (*downCastFunc)(result,
2189                             &*result,
2190                             targetTypeCode,
2191                             factory,
2192                             errorInfo);
2193   }
2194 
2195   assert(valid);
2196   return valid;
2197 }
2198 
2199 
2200 /*******************************************************************************
2201   Cast, if possible, a given atomic item SI to an atomic item TI of a given
2202   type TT. If the cast is not allowed, the method raises an error. If the cast
2203   is not possible, the method may raise an error or return false (TODO fix
2204   this!). Otherwise, it returns true.
2205 ********************************************************************************/
castToAtomic(store::Item_t & result,store::Item_t & item,store::SchemaTypeCode targetType,const TypeManager * tm,namespace_context * nsCtx,const QueryLoc & loc)2206 bool GenericCast::castToAtomic(
2207     store::Item_t&        result,
2208     store::Item_t&        item,
2209     store::SchemaTypeCode targetType,
2210     const TypeManager*    tm,
2211     namespace_context*    nsCtx,
2212     const QueryLoc&       loc)
2213 {
2214   store::ItemFactory* factory = GENV_ITEMFACTORY;
2215   zstring sourceString;
2216 
2217   store::SchemaTypeCode sourceType = item->getTypeCode();
2218 
2219   if (sourceType == targetType)
2220   {
2221     result.transfer(item);
2222     return true;
2223   }
2224 
2225   ErrorInfo errorInfo(sourceType, targetType, loc);
2226 
2227   if (targetType == store::XS_NOTATION ||
2228       targetType == store::XS_ANY_ATOMIC)
2229   {
2230     RAISE_ERROR(err::XPST0080, loc, ERROR_PARAMS(*errorInfo.theTargetType));
2231   }
2232 
2233   if (sourceType == store::XS_ANY_ATOMIC)
2234   {
2235     throwTypeException(err::XPTY0004, errorInfo);
2236   }
2237 
2238   if (targetType == store::XS_NCNAME &&
2239       sourceType != store::XS_STRING &&
2240       sourceType != store::XS_NCNAME &&
2241       sourceType != store::XS_UNTYPED_ATOMIC)
2242   {
2243     throwTypeException(err::XPTY0004, errorInfo);
2244   }
2245 
2246   CastFunc castFunc = theCastMatrix[theMapping[sourceType]]
2247                                     [theMapping[targetType]];
2248   if (castFunc == 0)
2249   {
2250     throwTypeException(err::XPTY0004, errorInfo);
2251   }
2252 
2253   if (theMapping[sourceType] == theMapping[store::XS_STRING])
2254   {
2255     item->getStringValue2(sourceString);
2256   }
2257 
2258   bool valid = (*castFunc)(result,
2259                            item,
2260                            sourceString,
2261                            factory,
2262                            nsCtx,
2263                            errorInfo);
2264 
2265   DownCastFunc downCastFunc = theDownCastMatrix[theMapping[targetType]];
2266 
2267   if (downCastFunc != 0 &&
2268       targetType != store::XS_STRING &&
2269       targetType != store::XS_INTEGER)
2270   {
2271     valid = (*downCastFunc)(result,
2272                             &*result,
2273                             targetType,
2274                             factory,
2275                             errorInfo);
2276   }
2277 
2278   assert(valid);
2279   return valid;
2280 }
2281 
2282 
2283 /*******************************************************************************
2284 
2285 ********************************************************************************/
castToUserDefinedType(store::Item_t & result,const store::Item_t & aItem,const XQType * aSourceType,const XQType * aTargetType,const QueryLoc & loc)2286 void castToUserDefinedType(
2287     store::Item_t& result,
2288     const store::Item_t& aItem,
2289     const XQType* aSourceType,
2290     const XQType* aTargetType,
2291     const QueryLoc& loc)
2292 {
2293   ErrorInfo lErrorInfo(aSourceType, aTargetType, loc);
2294 
2295   // std::cout << "-castToUserDefinedType: " << aItem.getp()->getStringValue()->c_str()
2296   //           << " srcType: " << aSourceType->get_qname()->getLocalName()->c_str()
2297   //           << " @ " << aSourceType->get_qname()->getNamespace()->c_str() << "\n";
2298   // std::cout << "\t\t           tgtType: "
2299   //           << aTargetType->get_qname()->getLocalName()->c_str() << " @ "
2300   //           << aTargetType->get_qname()->getNamespace()->c_str() << "\n";
2301 
2302   const TypeManager* lTypeManager = aTargetType->get_manager();
2303   Schema* schema = lTypeManager->getSchema();
2304 
2305   if (aSourceType->type_kind() != XQType::ATOMIC_TYPE_KIND ||
2306       (TypeOps::get_atomic_type_code(*aSourceType) != store::XS_STRING))
2307   {
2308     throwTypeException(err::FORG0001, lErrorInfo);
2309   }
2310 
2311   const UserDefinedXQType* udt = static_cast<const UserDefinedXQType*>(aTargetType);
2312 
2313   switch ( udt->getTypeCategory() )
2314   {
2315   case UserDefinedXQType::ATOMIC_TYPE:
2316   {
2317     zstring strValue;
2318     aItem->getStringValue2(strValue);
2319 
2320     store::Item_t baseItem;
2321     bool hasResult = schema->parseUserAtomicTypes(strValue,
2322                                                   aTargetType,
2323                                                   baseItem,
2324                                                   NULL,
2325                                                   loc);
2326     if (hasResult)
2327     {
2328       store::Item_t typeName = udt->get_qname();
2329       GENV_ITEMFACTORY->createUserTypedAtomicItem(result, baseItem, typeName);
2330       return;
2331     }
2332   }
2333   break;
2334 
2335   case UserDefinedXQType::LIST_TYPE:
2336   case UserDefinedXQType::UNION_TYPE:
2337   case UserDefinedXQType::COMPLEX_TYPE:
2338   default:
2339     ZORBA_ASSERT( false);
2340     break;
2341   }
2342 
2343   result = NULL;
2344 }
2345 
2346 
2347 /*******************************************************************************
2348 
2349 ********************************************************************************/
castToSimple(zstring & str,const xqtref_t & aTargetType,std::vector<store::Item_t> & aResultList,const TypeManager * tm,const QueryLoc & loc)2350 bool GenericCast::castToSimple(
2351     zstring& str,
2352     const xqtref_t& aTargetType,
2353     std::vector<store::Item_t>& aResultList,
2354     const TypeManager* tm,
2355     const QueryLoc& loc)
2356 {
2357   //std::cout << "-castToSimple: " << aStr.c_str() << " tgtType: " << aTargetType->get_qname()->getLocalName()->c_str() << " @ " << aTargetType->get_qname()->getNamespace()->c_str() << "\n";
2358 
2359   return tm->getSchema()->parseUserSimpleTypes(str, aTargetType, aResultList, loc);
2360 }
2361 
2362 
2363 /*******************************************************************************
2364   Casts an atomic item to a qname, if possible.
2365 ********************************************************************************/
castToQName(store::Item_t & result,const store::Item_t & item,namespace_context * nsCtx,bool isAttrName,const TypeManager * tm,const QueryLoc & loc)2366 bool GenericCast::castToQName(
2367     store::Item_t& result,
2368     const store::Item_t& item,
2369     namespace_context* nsCtx,
2370     bool isAttrName,
2371     const TypeManager* tm,
2372     const QueryLoc& loc)
2373 {
2374   RootTypeManager& rtm = GENV_TYPESYSTEM;
2375 
2376   xqtref_t sourceType = tm->create_named_type(item->getType(),
2377                                               TypeConstants::QUANT_ONE,
2378                                               loc,
2379                                               err::XPTY0004);
2380 
2381   ZORBA_ASSERT(item->isAtomic());
2382   ZORBA_ASSERT(sourceType != NULL);
2383 
2384   if (TypeOps::is_subtype(tm, *sourceType, *rtm.QNAME_TYPE_ONE))
2385   {
2386     result = item;
2387     return true;
2388   }
2389   else if (!TypeOps::is_subtype(tm, *sourceType, *rtm.STRING_TYPE_ONE) &&
2390            !TypeOps::is_equal(tm, *sourceType, *rtm.UNTYPED_ATOMIC_TYPE_ONE))
2391   {
2392     RAISE_ERROR(err::XPTY0004, loc,
2393     ERROR_PARAMS(ZED(BadType_23o), *sourceType, ZED(NoCastTo_45o), "QName"));
2394   }
2395 
2396   ErrorInfo errorInfo(sourceType.getp(), rtm.QNAME_TYPE_ONE.getp(), loc);
2397 
2398   zstring strval;
2399   item->getStringValue2(strval);
2400   ascii::trim_whitespace(strval);
2401 
2402   zstring::size_type idx = strval.find(":");
2403   zstring::size_type lidx = strval.rfind(":", strval.size(), 1);
2404   if (idx != lidx)
2405     throwTypeException(err::FORG0001, errorInfo);
2406 
2407   zstring prefix;
2408   zstring nsuri;
2409   zstring local;
2410 
2411   if (idx == zstring::npos)
2412   {
2413     if (nsCtx && !isAttrName)
2414     {
2415       nsCtx->findBinding(prefix, nsuri);
2416     }
2417 
2418     local = strval;
2419   }
2420   else
2421   {
2422     prefix = strval.substr(0, idx);
2423 
2424     if (!GenericCast::instance()->castableToNCName(prefix))
2425       throwTypeException(err::FORG0001, errorInfo);
2426 
2427     if (nsCtx)
2428     {
2429       if (!nsCtx->findBinding(prefix, nsuri))
2430         throw XQUERY_EXCEPTION(err::FONS0004, ERROR_PARAMS(prefix));
2431     }
2432 
2433     local = strval.substr(idx + 1);
2434   }
2435 
2436   if (!GenericCast::instance()->castableToNCName(local.c_str()))
2437     throwTypeException(err::FORG0001, errorInfo );
2438 
2439   return GENV_ITEMFACTORY->createQName(result, nsuri, prefix, local);
2440 }
2441 
2442 
2443 /*******************************************************************************
2444   NCName          ::= NCNameStartChar NCNameChar* // An XML Name, minus the ":"
2445   NCNameChar      ::= NameChar - ':'
2446   NCNameStartChar ::= Letter | '_'
2447   NameChar        ::= Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar |
2448                       Extender
2449 ********************************************************************************/
castableToNCName(const zstring & str)2450 bool GenericCast::castableToNCName(const zstring& str)
2451 {
2452   std::vector<uint32_t> cps;
2453 
2454   utf8::to_codepoints(str, &cps);
2455 
2456   std::vector<uint32_t>::size_type i;
2457   std::vector<uint32_t>::size_type cps_size = cps.size();
2458 
2459   if (cps_size == 0)
2460     return false;
2461 
2462   uint32_t cp = cps[0];
2463 
2464   if(!XQCharType::isLetter(cp) && (cp != '_'))
2465     return false;
2466 
2467   for (i = 1; i < cps_size; i++)
2468   {
2469     cp = cps[i];
2470 
2471     if(!XQCharType::isLetter(cp) && !XQCharType::isDigit(cp) &&
2472       (cp != '.') && (cp != '-') && (cp != '_') &&
2473       !XQCharType::isCombiningChar(cp) && !XQCharType::isExtender(cp))
2474       return false;
2475   }
2476 
2477   return true;
2478 }
2479 
2480 
2481 /*******************************************************************************
2482 
2483 ********************************************************************************/
castableToNormalizedString(const zstring & str)2484 bool GenericCast::castableToNormalizedString(const zstring& str)
2485 {
2486   char ch;
2487   zstring::size_type  sz = str.size();
2488 
2489   if (sz == 0)
2490     return true;
2491 
2492   for (zstring::size_type i = 0; i < sz; ++i)
2493   {
2494     ch = str[i];
2495     // do not contain the carriage return (#xD), line feed (#xA) nor tab (#x9)
2496     // characters
2497     if (ch == '\r' || ch == '\n' || ch == '\t')
2498     {
2499       return false;
2500     }
2501   }
2502 
2503   return true;
2504 }
2505 
2506 
2507 /*******************************************************************************
2508 
2509 ********************************************************************************/
castableToToken(const zstring & str)2510 bool GenericCast::castableToToken(const zstring& str)
2511 {
2512   char ch;
2513   zstring::size_type sz = str.size();
2514 
2515   if (sz == 0)
2516     return true;
2517 
2518   bool spaceSeen = false;
2519 
2520   for (zstring::size_type i = 0; i < sz; ++i)
2521   {
2522     ch = str[i];
2523 
2524     // do not contain the carriage return (#xD), line feed (#xA) nor tab (#x9)
2525     // characters */
2526     if (ch == '\r' || ch == '\n' || ch == '\t')
2527     {
2528       return false;
2529     }
2530 
2531     if (ch == ' ')
2532     {
2533       /* two consecutive spaces not allowed. */
2534       if (spaceSeen)
2535         return false;
2536 
2537       /* no leading or trailing spaces */
2538       if (i == 0 || i == sz - 1)
2539         return false;
2540 
2541       spaceSeen = true;
2542     }
2543     else
2544     {
2545       spaceSeen = false;
2546     }
2547   }
2548 
2549   return true;
2550 }
2551 
2552 
2553 /*******************************************************************************
2554 
2555 ********************************************************************************/
castableToLanguage(const zstring & str)2556 bool GenericCast::castableToLanguage(const zstring& str)
2557 {
2558   char ch;
2559   zstring::size_type i = 0;
2560   zstring::size_type sz = str.size();
2561 
2562   if (sz == 0)
2563     return false;
2564 
2565   /* automation for [a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})* */
2566   bool firstBlock = true;
2567   i = 0;
2568   uint32_t blkIdx = 0;
2569 
2570   while (i < sz)
2571   {
2572     ch = str[i];
2573 
2574     if (ch == '-')
2575     {
2576       if (blkIdx == 0)
2577       {
2578         return false;
2579       }
2580 
2581       blkIdx = 0;
2582       firstBlock = false;
2583       ++i;
2584       continue;
2585     }
2586 
2587     if (blkIdx >= 8)
2588     {
2589       return false;
2590     }
2591 
2592     if (!((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')))
2593     {
2594       if (firstBlock)
2595       {
2596         return false;
2597       }
2598       if (!(ch >= '0' && ch <= '9'))
2599       {
2600         return false;
2601       }
2602     }
2603 
2604     ++i;
2605     ++blkIdx;
2606   }
2607 
2608   if (blkIdx == 0)
2609   {
2610     return false;
2611   }
2612 
2613   return true;
2614 }
2615 
2616 
2617 /*******************************************************************************
2618 
2619 ********************************************************************************/
castableToNMToken(const zstring & str)2620 bool GenericCast::castableToNMToken(const zstring& str)
2621 {
2622   uint32_t cp;
2623   std::vector<uint32_t> cps;
2624 
2625   utf8::to_codepoints(str, &cps);
2626 
2627   std::vector<uint32_t>::size_type i;
2628   std::vector<uint32_t>::size_type sz = cps.size();
2629 
2630   if (sz == 0)
2631     return false;
2632 
2633   for (i = 0; i < sz; ++i)
2634   {
2635     cp = cps[i];
2636     if (!(XQCharType::isLetter(cp)
2637       || XQCharType::isDigit(cp)
2638       || XQCharType::isExtender(cp)
2639       || XQCharType::isCombiningChar(cp)
2640       || cp == '.'
2641       || cp == '-'
2642       || cp == '_'
2643       || cp == ':'))
2644     {
2645       return false;
2646     }
2647   }
2648 
2649   return true;
2650 }
2651 
2652 
2653 /*******************************************************************************
2654 
2655 ********************************************************************************/
castableToName(const zstring & str)2656 bool GenericCast::castableToName(const zstring& str)
2657 {
2658   uint32_t cp;
2659   std::vector<uint32_t> cps;
2660 
2661   utf8::to_codepoints(str, &cps);
2662 
2663   std::vector<uint32_t>::size_type i;
2664   std::vector<uint32_t>::size_type sz = cps.size();
2665 
2666   if (sz == 0)
2667     return false;
2668 
2669   for (i = 0; i < sz; ++i)
2670   {
2671     cp = cps[i];
2672     if (!(XQCharType::isLetter(cp) || cp == '_' || cp == ':') )
2673     {
2674       if (i == 0)
2675       {
2676         return false;
2677       }
2678 
2679       if (!(XQCharType::isDigit(cp)
2680         || XQCharType::isExtender(cp)
2681         || XQCharType::isCombiningChar(cp)
2682         || cp == '.'
2683         || cp == '-'))
2684       {
2685         return false;
2686       }
2687     }
2688   }
2689 
2690   return true;
2691 }
2692 
2693 
2694 /*******************************************************************************
2695 
2696 ********************************************************************************/
isCastable(const store::Item_t & aItem,const XQType * aTargetType,const TypeManager * tm)2697 bool GenericCast::isCastable(
2698     const store::Item_t& aItem,
2699     const XQType* aTargetType,
2700     const TypeManager* tm)
2701 {
2702 #ifndef ZORBA_NO_XMLSCHEMA
2703   if (aTargetType->type_kind() == XQType::USER_DEFINED_KIND )
2704   {
2705     const UserDefinedXQType* udt = static_cast<const UserDefinedXQType*>(aTargetType);
2706     if (!udt->isComplex())
2707     {
2708       return tm->getSchema()->
2709              isCastableUserSimpleTypes(aItem->getStringValue(),
2710                                        udt->getBaseType().getp());
2711     }
2712   }
2713 #endif // ZORBA_NO_XMLSCHEMA
2714 
2715   xqtref_t lSourceType = tm->create_named_type(aItem->getType(),
2716                                                TypeConstants::QUANT_ONE,
2717                                                QueryLoc::null,
2718                                                err::XPTY0004);
2719 
2720   TypeConstants::castable_t lIsCastable = TypeOps::castability(*lSourceType,
2721                                                                *aTargetType);
2722   switch(lIsCastable)
2723   {
2724   case TypeConstants::NOT_CASTABLE:
2725     return false;
2726     break;
2727   case TypeConstants::CASTABLE:
2728     return true;
2729     break;
2730   case TypeConstants::MAYBE_CASTABLE:
2731   {
2732     try
2733     {
2734       store::Item_t temp = aItem;
2735       return castToAtomic(temp, temp, aTargetType, tm, NULL, QueryLoc::null);
2736     }
2737     catch (ZorbaException const&)
2738     {
2739       return false;
2740     }
2741   }
2742   break;
2743   }
2744 
2745   return false;
2746 }
2747 
2748 
2749 /*******************************************************************************
2750 
2751 ********************************************************************************/
isCastable(const zstring & str,const XQType * aTargetType,const TypeManager * tm)2752 bool GenericCast::isCastable(
2753     const zstring& str,
2754     const XQType* aTargetType,
2755     const TypeManager* tm)
2756 {
2757 #ifndef ZORBA_NO_XMLSCHEMA
2758   if (aTargetType->type_kind() == XQType::USER_DEFINED_KIND )
2759   {
2760     const UserDefinedXQType* udt = static_cast<const UserDefinedXQType*>(aTargetType);
2761     if (!udt->isComplex())
2762     {
2763       return tm->getSchema()->
2764              isCastableUserSimpleTypes(str,
2765                                        udt->getBaseType().getp());
2766     }
2767   }
2768 #endif // ZORBA_NO_XMLSCHEMA
2769 
2770   RootTypeManager& rtm = GENV_TYPESYSTEM;
2771 
2772   xqtref_t lSourceType = rtm.STRING_TYPE_ONE;
2773 
2774   TypeConstants::castable_t lIsCastable = TypeOps::castability(*lSourceType,
2775                                                                *aTargetType);
2776   switch(lIsCastable)
2777   {
2778   case TypeConstants::NOT_CASTABLE:
2779     return false;
2780     break;
2781   case TypeConstants::CASTABLE:
2782     return true;
2783     break;
2784   case TypeConstants::MAYBE_CASTABLE:
2785   {
2786     try
2787     {
2788       store::Item_t dummy;
2789       zstring copyStr = str;
2790       return castToAtomic(dummy, copyStr, aTargetType, tm, NULL, QueryLoc::null);
2791     }
2792     catch (ZorbaException const&)
2793     {
2794       return false;
2795     }
2796   }
2797   break;
2798   }
2799 
2800   return false;
2801 }
2802 
2803 
2804 /*******************************************************************************
2805 
2806 ********************************************************************************/
promote(store::Item_t & result,store::Item_t & item,const XQType * targetType,const TypeManager * tm,const QueryLoc & loc)2807 bool GenericCast::promote(
2808     store::Item_t& result,
2809     store::Item_t& item,
2810     const XQType* targetType,
2811     const TypeManager* tm,
2812     const QueryLoc& loc)
2813 {
2814   RootTypeManager& rtm = GENV_TYPESYSTEM;
2815 
2816   assert(item->isAtomic());
2817 
2818   // If the target type is a builtin atomic type
2819   if (targetType->type_kind() == XQType::ATOMIC_TYPE_KIND)
2820   {
2821     return promote(result,
2822                    item,
2823                    static_cast<const AtomicXQType*>(targetType)->get_type_code(),
2824                    tm,
2825                    loc);
2826   }
2827 
2828   if (targetType->type_kind() == XQType::NONE_KIND)
2829       return false;
2830 
2831   xqtref_t itemType = tm->create_value_type(item);
2832 
2833   if (TypeOps::is_subtype(tm, *itemType, *targetType))
2834   {
2835     result.transfer(item);
2836     return result != NULL;
2837   }
2838 
2839   // untyped --> target type
2840   if (TypeOps::is_equal(tm, *itemType, *rtm.UNTYPED_ATOMIC_TYPE_ONE) &&
2841       ! TypeOps::is_equal(tm, *TypeOps::prime_type(tm, *targetType), *rtm.QNAME_TYPE_ONE))
2842   {
2843     return castToAtomic(result, item, targetType, tm, NULL, loc);
2844   }
2845 
2846     // Decimal/Float --> xs:double
2847   else if (TypeOps::is_subtype(tm, *targetType, *rtm.DOUBLE_TYPE_ONE))
2848   {
2849     store::SchemaTypeCode itemTypeCode = item->getTypeCode();
2850 
2851     if (TypeOps::is_subtype(itemTypeCode, store::XS_DECIMAL) ||
2852         TypeOps::is_subtype(itemTypeCode, store::XS_FLOAT))
2853     {
2854       return castToAtomic(result, item, targetType, tm, NULL, loc);
2855     }
2856   }
2857 
2858   // decimal --> xs:float
2859   else if (TypeOps::is_subtype(tm, *targetType, *rtm.FLOAT_TYPE_ONE))
2860   {
2861     store::SchemaTypeCode itemTypeCode = item->getTypeCode();
2862 
2863     if (TypeOps::is_subtype(itemTypeCode, store::XS_DECIMAL))
2864     {
2865       return castToAtomic(result, item, targetType, tm, NULL, loc);
2866     }
2867   }
2868 
2869   // URI --> xs:String
2870   else if (TypeOps::is_subtype(tm, *targetType, *rtm.STRING_TYPE_ONE))
2871   {
2872     store::SchemaTypeCode itemTypeCode = item->getTypeCode();
2873 
2874     if (TypeOps::is_subtype(itemTypeCode, store::XS_ANY_URI))
2875     {
2876       return castToAtomic(result, item, store::XS_STRING, tm, NULL, loc);
2877     }
2878   }
2879 
2880   return false;
2881 }
2882 
2883 
2884 /*******************************************************************************
2885 
2886 ********************************************************************************/
promote(store::Item_t & result,store::Item_t & item,store::SchemaTypeCode targetType,const TypeManager * tm,const QueryLoc & loc)2887 bool GenericCast::promote(
2888     store::Item_t& result,
2889     store::Item_t& item,
2890     store::SchemaTypeCode targetType,
2891     const TypeManager* tm,
2892     const QueryLoc& loc)
2893 {
2894   assert(item->isAtomic());
2895 
2896   store::SchemaTypeCode itemType = item->getTypeCode();
2897 
2898   if (TypeOps::is_subtype(itemType, targetType))
2899   {
2900     result.transfer(item);
2901     return result != NULL;
2902   }
2903 
2904   if (TypeOps::is_subtype(itemType, store::XS_UNTYPED_ATOMIC) &&
2905       ! TypeOps::is_subtype(targetType, store::XS_QNAME))
2906   {
2907     // untyped --> target type
2908     return castToAtomic(result, item, targetType, tm, NULL, loc);
2909   }
2910   else if (TypeOps::is_subtype(targetType, store::XS_DOUBLE))
2911   {
2912     // Decimal/Float --> xs:double
2913     if (TypeOps::is_subtype(itemType, store::XS_DECIMAL) ||
2914         TypeOps::is_subtype(itemType, store::XS_FLOAT))
2915     {
2916       return castToAtomic(result, item, targetType, tm, NULL, loc);
2917     }
2918   }
2919   else if (TypeOps::is_subtype(targetType, store::XS_FLOAT))
2920   {
2921     // decimal --> xs:float
2922     if (TypeOps::is_subtype(itemType, store::XS_DECIMAL))
2923     {
2924       return castToAtomic(result, item, targetType, tm, NULL, loc);
2925     }
2926   }
2927   else if (TypeOps::is_subtype(targetType, store::XS_STRING))
2928   {
2929     // URI --> xs:String Promotion
2930     if (TypeOps::is_subtype(itemType, store::XS_ANY_URI))
2931     {
2932       return castToAtomic(result, item, store::XS_STRING, tm, NULL, loc);
2933     }
2934   }
2935 
2936   return false;
2937 }
2938 
2939 
2940 #undef ATOMIC_TYPE
2941 
2942 
2943 /* end class GenericCast */
2944 } // namespace zorba
2945 /* vim:set et sw=2 ts=2: */
2946