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