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 #include "atomic_items.h"
18
19 #include <limits.h>
20
21 #include <zorba/internal/unique_ptr.h>
22
23 #include "diagnostics/assert.h"
24 #include "diagnostics/xquery_diagnostics.h"
25 #include "diagnostics/util_macros.h"
26
27 #include "zorbatypes/collation_manager.h"
28 #include "zorbatypes/numconversions.h"
29 #include "zorbatypes/URI.h"
30
31 #include "zorbautils/hashfun.h"
32
33 #include "store/api/item.h"
34 #include "store/api/store.h"
35 #include "store/api/item_factory.h"
36 #include "store/api/collection.h"
37 #include "qname_pool.h"
38 #include "simple_store.h"
39 #include "simple_item_factory.h"
40 #include "store_defs.h"
41 #include "item_iterator.h"
42 #include "node_items.h"
43 #include "ordpath.h"
44 #include "tree_id.h"
45
46 #include "util/ascii_util.h"
47 #include "util/string_util.h"
48 #include "util/utf8_util.h"
49
50 #define CREATE_XS_TYPE(aType) \
51 GET_STORE().getItemFactory()->createQName(Store::XS_URI, "xs", aType);
52
53 #define CREATE_BOOLITEM(item, aValue) \
54 GET_STORE().getItemFactory()->createBoolean(item, aValue)
55
56 using namespace std;
57 #ifndef ZORBA_NO_FULL_TEXT
58 using namespace zorba::locale;
59 #endif /* ZORBA_NO_FULL_TEXT */
60
61 namespace zorba {
62 namespace simplestore {
63
64
65 /*******************************************************************************
66
67 ********************************************************************************/
getTypedValue(store::Item_t & val,store::Iterator_t & iter) const68 void AtomicItem::getTypedValue(store::Item_t& val, store::Iterator_t& iter) const
69 {
70 store::Item* lItem = const_cast<AtomicItem *>(this);
71 val = lItem;
72 }
73
74
75 /*******************************************************************************
76
77 ********************************************************************************/
getAnyUriTypeCode() const78 AnyUriTypeCode AtomicItem::getAnyUriTypeCode() const
79 {
80 throw ZORBA_EXCEPTION(
81 zerr::ZSTR0050_FUNCTION_NOT_IMPLEMENTED_FOR_ITEMTYPE,
82 ERROR_PARAMS( __FUNCTION__, typeid(*this).name() )
83 );
84 }
85
86
87 /*******************************************************************************
88 For numeric items or the untyped item: convert this item to a long item,
89 if possible, i.e., if the conversion is going to be lossless.
90 ********************************************************************************/
castToLong(store::Item_t & result) const91 bool AtomicItem::castToLong(store::Item_t& result) const
92 {
93 xs_long longValue;
94
95 result = NULL;
96
97 const AtomicItem* item1 = static_cast<AtomicItem*>(getBaseItem());
98 if (item1 == NULL)
99 item1 = this;
100
101 switch (item1->getTypeCode())
102 {
103 case store::XS_UNTYPED_ATOMIC:
104 {
105 const UntypedAtomicItem* item = static_cast<const UntypedAtomicItem*>(item1);
106 try
107 {
108 longValue = ztd::aton<xs_long>(item->theValue.c_str());
109 GET_FACTORY().createLong(result, longValue);
110 }
111 catch (std::exception const&)
112 {
113 // ignore
114 }
115 break;
116 }
117
118 case store::XS_DOUBLE:
119 case store::XS_FLOAT:
120 {
121 double doubleValue = item1->getDoubleValue().getNumber();
122 longValue = static_cast<xs_long>(doubleValue);
123
124 if (doubleValue == static_cast<double>(longValue))
125 GET_FACTORY().createLong(result, longValue);
126
127 break;
128 }
129
130 case store::XS_DECIMAL:
131 {
132 const DecimalItem* item = static_cast<const DecimalItem*>(item1);
133 try
134 {
135 longValue = to_xs_long(item->theValue);
136 GET_FACTORY().createLong(result, longValue);
137 }
138 catch (std::range_error const&)
139 {
140 // ignore
141 }
142 break;
143 }
144
145 case store::XS_INTEGER:
146 case store::XS_NON_POSITIVE_INTEGER:
147 case store::XS_NEGATIVE_INTEGER:
148 case store::XS_NON_NEGATIVE_INTEGER:
149 case store::XS_POSITIVE_INTEGER:
150 {
151 const IntegerItem* item = static_cast<const IntegerItem*>(item1);
152 try
153 {
154 longValue = item->getLongValue();
155 GET_FACTORY().createLong(result, longValue);
156 }
157 catch (std::range_error const&)
158 {
159 // ignore
160 }
161 break;
162 }
163
164 case store::XS_UNSIGNED_LONG:
165 {
166 const UnsignedLongItem* item = static_cast<const UnsignedLongItem*>(item1);
167 if ((item->theValue >> 63) == 0)
168 {
169 longValue = static_cast<xs_long>(item->theValue);
170 GET_FACTORY().createLong(result, longValue);
171 }
172 break;
173 }
174
175 default:
176 {
177 RAISE_ERROR_NO_LOC(zerr::ZSTR0050_FUNCTION_NOT_IMPLEMENTED_FOR_ITEMTYPE,
178 ERROR_PARAMS(__FUNCTION__, typeid(*this).name()));
179 }
180 }
181
182 return (result != NULL);
183 }
184
185
186 /*******************************************************************************
187 For numeric items: convert this item to a double item. If the conversion is
188 a lossy one, set "lossy" to true, otherwise set "lossy" to false. If "force"
189 is true, the conversion is done always; otherwise, the conversion is done only
190 if it is lossy.
191 ********************************************************************************/
coerceToDouble(store::Item_t & result,bool force,bool & lossy) const192 void AtomicItem::coerceToDouble(store::Item_t& result, bool force, bool& lossy) const
193 {
194 xs_double doubleValue;
195
196 result = NULL;
197
198 const AtomicItem* item1 = static_cast<AtomicItem*>(getBaseItem());
199 if (item1 == NULL)
200 item1 = this;
201
202 switch (item1->getTypeCode())
203 {
204 case store::XS_DECIMAL:
205 {
206 const DecimalItem* item = static_cast<const DecimalItem*>(item1);
207
208 doubleValue = item->theValue;
209
210 const xs_decimal decValue(doubleValue);
211
212 lossy = (decValue != item->theValue);
213 break;
214 }
215
216 case store::XS_INTEGER:
217 case store::XS_NON_POSITIVE_INTEGER:
218 case store::XS_NEGATIVE_INTEGER:
219 case store::XS_NON_NEGATIVE_INTEGER:
220 case store::XS_POSITIVE_INTEGER:
221 {
222 const IntegerItem* item = static_cast<const IntegerItem*>(item1);
223
224 doubleValue = item->getIntegerValue();
225
226 const xs_integer intValue(doubleValue);
227
228 lossy = (intValue != item->getIntegerValue());
229 break;
230 }
231
232 case store::XS_UNSIGNED_LONG:
233 {
234 const UnsignedLongItem* item = static_cast<const UnsignedLongItem*>(item1);
235
236 doubleValue = item->theValue;
237
238 xs_unsignedLong ulongValue = static_cast<xs_unsignedLong>(doubleValue.getNumber());
239
240 lossy = (ulongValue != item->theValue);
241 break;
242 }
243
244 case store::XS_UNSIGNED_INT:
245 case store::XS_UNSIGNED_SHORT:
246 case store::XS_UNSIGNED_BYTE:
247 {
248 doubleValue = getUnsignedIntValue();
249 lossy = false;
250 break;
251 }
252
253 case store::XS_LONG:
254 {
255 const LongItem* item = static_cast<const LongItem*>(item1);
256
257 doubleValue = item->theValue;
258
259 xs_long longValue = static_cast<xs_long>(doubleValue.getNumber());
260
261 /*
262 std::cout << "original long value = " << item->theValue << std::endl
263 << "double value = " << doubleValue << std::endl
264 << "new long value = " << longValue << std::endl << std::endl;
265
266 */
267 lossy = (longValue != item->theValue);
268
269 /*
270 std::cout << "original long value = " << item->theValue << std::endl
271 << "double value = " << doubleValue << std::endl
272 << "new long value = " << longValue << std::endl << std::endl;
273
274 std::cout << "lossy = " << lossy << std::endl << std::endl;
275 */
276
277 break;
278 }
279
280 case store::XS_INT:
281 case store::XS_SHORT:
282 case store::XS_BYTE:
283 {
284 doubleValue = item1->getIntValue();
285 lossy = false;
286 break;
287 }
288
289 default:
290 {
291 RAISE_ERROR_NO_LOC(zerr::ZSTR0050_FUNCTION_NOT_IMPLEMENTED_FOR_ITEMTYPE,
292 ERROR_PARAMS(__FUNCTION__, typeid(*this).name()));
293 }
294 }
295
296 if (force || lossy)
297 GET_FACTORY().createDouble(result, doubleValue);
298 }
299
300
301 #if 0
302 /*******************************************************************************
303 For xs:double and xs:float items: convert this item to an xs:long item. If
304 the conversion is a lossy one, set "lossy" to true, otherwise set "lossy"
305 to false.
306 ********************************************************************************/
307 void AtomicItem::coerceToLong(
308 store::Item_t& result,
309 bool& lossy,
310 bool& negINF,
311 bool& posINF) const
312 {
313 if (getTypeCode() != store::XS_DOUBLE && getTypeCode() != store::XS_FLOAT)
314 {
315 RAISE_ERROR_NO_LOC(zerr::ZSTR0050_FUNCTION_NOT_IMPLEMENTED_FOR_ITEMTYPE,
316 ERROR_PARAMS(__FUNCTION__, typeid(*this).name()));
317 }
318
319 xs_double doubleObj = getDoubleValue();
320
321 if (doubleObj.isNaN())
322 throw ZORBA_EXCEPTION(zerr::ZSTR0041_NAN_COMPARISON);
323
324 int64_t longMax = std::numeric_limits<int64_t>::max();
325 int64_t longMin = std::numeric_limits<int64_t>::min();
326
327 int64_t longValue;
328
329 if (doubleObj.isPosInf())
330 {
331 longValue = longMax;
332 lossy = true;
333 negINF = false;
334 posINF = true;
335 }
336 else if (doubleObj.isNegInf())
337 {
338 longValue = longMin;
339 lossy = true;
340 negINF = true;
341 posINF = false;
342 }
343 else
344 {
345 double doubleMaxLong = static_cast<double>(longMax);
346 double doubleMinLong = static_cast<double>(longMin);
347
348 assert(longMax == static_cast<int64_t>(doubleMaxLong));
349 assert(longMin == static_cast<int64_t>(doubleMinLong));
350
351 double doubleValue = doubleObj.getNumber();
352
353 if (doubleValue > doubleMaxLong)
354 {
355 longValue = longMax;
356 lossy = true;
357 negINF = false;
358 posINF = true;
359 }
360 else if (doubleValue < doubleMinLong)
361 {
362 longValue = longMin;
363 lossy = true;
364 negINF = true;
365 posINF = false;
366 }
367 else
368 {
369 double doubleFloor = ::floor(doubleValue);
370 longValue = static_cast<uint64_t>(doubleFloor);
371 lossy = (doubleFloor != doubleValue);
372 negINF = false;
373 posINF = false;
374 }
375 }
376
377 GET_FACTORY().createLong(result, longValue);
378 }
379 #endif
380
381
382 /*******************************************************************************
383 class UserTypedAtomicItem
384 ********************************************************************************/
getBaseItem() const385 store::Item* UserTypedAtomicItem::getBaseItem() const
386 {
387 store::Item* baseItem = theBaseItem.getp();
388
389 while (baseItem->getBaseItem() != NULL)
390 {
391 baseItem = baseItem->getBaseItem();
392 }
393
394 return baseItem;
395 }
396
397
398 /*******************************************************************************
399 class UntypedAtomicItem
400 ********************************************************************************/
castToUri(store::Item_t & result) const401 bool UntypedAtomicItem::castToUri(store::Item_t& result) const
402 {
403 result = NULL;
404
405 try
406 {
407 URI uriVal(theValue);
408 zstring tmp = uriVal.toString();
409 return GET_FACTORY().createAnyURI(result, tmp);
410 }
411 catch (ZorbaException const&)
412 {
413 result = NULL;
414 }
415
416 return false;
417 }
418
419
castToString(store::Item_t & result) const420 bool UntypedAtomicItem::castToString(store::Item_t& result) const
421 {
422 zstring tmp = theValue;
423 return GET_FACTORY().createString(result, tmp);
424 }
425
426
castToDateTime(store::Item_t & result) const427 bool UntypedAtomicItem::castToDateTime(store::Item_t& result) const
428 {
429 return GET_FACTORY().createDateTime(result, theValue.c_str(), theValue.size());
430 }
431
432
castToDate(store::Item_t & result) const433 bool UntypedAtomicItem::castToDate(store::Item_t& result) const
434 {
435 return GET_FACTORY().createDate(result, theValue.c_str(), theValue.size());
436 }
437
438
castToTime(store::Item_t & result) const439 bool UntypedAtomicItem::castToTime(store::Item_t& result) const
440 {
441 return GET_FACTORY().createTime(result, theValue.c_str(), theValue.size());
442 }
443
444
castToGYear(store::Item_t & result) const445 bool UntypedAtomicItem::castToGYear(store::Item_t& result) const
446 {
447 return GET_FACTORY().createGYear(result, theValue.c_str(), theValue.size());
448 }
449
450
castToGYearMonth(store::Item_t & result) const451 bool UntypedAtomicItem::castToGYearMonth(store::Item_t& result) const
452 {
453 return GET_FACTORY().createGYearMonth(result, theValue.c_str(), theValue.size());
454 }
455
456
castToGMonthDay(store::Item_t & result) const457 bool UntypedAtomicItem::castToGMonthDay(store::Item_t& result) const
458 {
459 return GET_FACTORY().createGMonthDay(result, theValue.c_str(), theValue.size());
460 }
461
462
castToGMonth(store::Item_t & result) const463 bool UntypedAtomicItem::castToGMonth(store::Item_t& result) const
464 {
465 return GET_FACTORY().createGMonth(result, theValue.c_str(), theValue.size());
466 }
467
468
castToGDay(store::Item_t & result) const469 bool UntypedAtomicItem::castToGDay(store::Item_t& result) const
470 {
471 return GET_FACTORY().createGDay(result, theValue.c_str(), theValue.size());
472 }
473
474
castToDuration(store::Item_t & result) const475 bool UntypedAtomicItem::castToDuration(store::Item_t& result) const
476 {
477 return GET_FACTORY().createDuration(result, theValue.c_str(), theValue.size());
478 }
479
480
castToDouble(store::Item_t & result) const481 bool UntypedAtomicItem::castToDouble(store::Item_t& result) const
482 {
483 try
484 {
485 xs_double const doubleValue(theValue.c_str());
486 return GET_FACTORY().createDouble(result, doubleValue);
487 }
488 catch ( std::exception const& )
489 {
490 result = NULL;
491 return false;
492 }
493 }
494
495
castToDecimal(store::Item_t & result) const496 bool UntypedAtomicItem::castToDecimal(store::Item_t& result) const
497 {
498 try
499 {
500 xs_decimal const decValue(theValue.c_str());
501 return GET_FACTORY().createDecimal(result, decValue);
502 }
503 catch ( std::exception const& )
504 {
505 result = NULL;
506 return false;
507 }
508 }
509
510
castToInteger(store::Item_t & result) const511 bool UntypedAtomicItem::castToInteger(store::Item_t& result) const
512 {
513 try
514 {
515 xs_integer const intValue(theValue.c_str());
516 return GET_FACTORY().createInteger(result, intValue);
517 }
518 catch ( std::exception const& )
519 {
520 result = NULL;
521 return false;
522 }
523 }
524
525
castToHexBinary(store::Item_t & result) const526 bool UntypedAtomicItem::castToHexBinary(store::Item_t& result) const
527 {
528 Base16 value;
529 if (Base16::parseString(theValue, value))
530 {
531 return GET_FACTORY().createHexBinary(result, value);
532 }
533 else
534 {
535 result = NULL;
536 return false;
537 }
538 }
539
540
castToBase64Binary(store::Item_t & result) const541 bool UntypedAtomicItem::castToBase64Binary(store::Item_t& result) const
542 {
543 Base64 value;
544 if (Base64::parseString(theValue, value))
545 {
546 return GET_FACTORY().createBase64Binary(result, value);
547 }
548 else
549 {
550 result = NULL;
551 return false;
552 }
553 }
554
555
castToBoolean(store::Item_t & result) const556 bool UntypedAtomicItem::castToBoolean(store::Item_t& result) const
557 {
558 zstring str;
559 ascii::trim_whitespace(theValue, &str);
560 bool value = true;
561
562 if (ZSTREQ(str, "false") || ZSTREQ(str, "0"))
563 {
564 value = false;
565 }
566 else if (!ZSTREQ(str, "true") && !ZSTREQ(str, "1"))
567 {
568 result = NULL;
569 return false;
570 }
571
572 return GET_FACTORY().createBoolean(result, value);
573 }
574
575
getType() const576 store::Item* UntypedAtomicItem::getType() const
577 {
578 return GET_STORE().theSchemaTypeNames[store::XS_UNTYPED_ATOMIC];
579 }
580
581
hash(long timezone,const XQPCollator * aCollation) const582 uint32_t UntypedAtomicItem::hash(long timezone, const XQPCollator* aCollation) const
583 {
584 return utf8::hash(theValue);
585 }
586
587
equals(const store::Item * other,long timezone,const XQPCollator * collation) const588 bool UntypedAtomicItem::equals(
589 const store::Item* other,
590 long timezone,
591 const XQPCollator* collation) const
592 {
593 if (collation == NULL || collation->doMemCmp())
594 return theValue == other->getString();
595
596 return (utf8::compare(theValue, other->getString(), collation) == 0);
597 }
598
599
compare(const Item * other,long timezone,const XQPCollator * aCollation) const600 long UntypedAtomicItem::compare(
601 const Item* other,
602 long timezone,
603 const XQPCollator* aCollation) const
604 {
605 // Note: utf8::compare does byte comparison if the collation is null or
606 // requires byte comparison.
607 return utf8::compare(theValue, other->getString(), aCollation);
608 }
609
610
getEBV() const611 bool UntypedAtomicItem::getEBV() const
612 {
613 return ! ( theValue == "" );
614 }
615
616
show() const617 zstring UntypedAtomicItem::show() const
618 {
619 zstring res("xs:untypedAtomic(");
620 res += theValue;
621 res += ")";
622 return res;
623 }
624
625
626 /*******************************************************************************
627 class QNameItem
628 ********************************************************************************/
QNameItem(const char * ns,const char * prefix,const char * local)629 QNameItem::QNameItem(const char* ns, const char* prefix, const char* local)
630 :
631 theNormalizedQName(NULL),
632 theIsInPool(false)
633 {
634 initializeAsQNameNotInPool(ns, prefix, local);
635 }
636
637
QNameItem(const zstring & ns,const zstring & prefix,const zstring & local)638 QNameItem::QNameItem(const zstring& ns, const zstring& prefix, const zstring& local)
639 :
640 theNormalizedQName(NULL),
641 theIsInPool(false)
642 {
643 initializeAsQNameNotInPool(ns, prefix, local);
644 }
645
646
initializeAsQNameNotInPool(const zstring & aNamespace,const zstring & aPrefix,const zstring & aLocalName)647 void QNameItem::initializeAsQNameNotInPool(
648 const zstring& aNamespace,
649 const zstring& aPrefix,
650 const zstring& aLocalName)
651 {
652 assert(!isValid());
653
654 store::Item_t lPoolQName =
655 GET_STORE().getQNamePool().insert(aNamespace, zstring(), aLocalName);
656
657 QNameItem* lNormalized = static_cast<QNameItem*>(lPoolQName.getp());
658 assert(lNormalized->isNormalized());
659
660 initializeAsUnnormalizedQName(lNormalized, aPrefix);
661
662 theIsInPool = false;
663 }
664
665
free()666 void QNameItem::free()
667 {
668 QNamePool& thePool = GET_STORE().getQNamePool();
669
670 if (theIsInPool)
671 {
672 thePool.remove(this);
673 return;
674 }
675
676 assert(!isNormalized());
677
678 invalidate(false, NULL);
679 delete this;
680 }
681
682
equals(const store::Item * item,long timezone,const XQPCollator * aCollation) const683 bool QNameItem::equals(
684 const store::Item* item,
685 long timezone,
686 const XQPCollator* aCollation) const
687 {
688 assert(dynamic_cast<const QNameItem*>(item) != NULL);
689
690 return (theNormalizedQName ==
691 static_cast<const QNameItem*>(item)->theNormalizedQName);
692 }
693
694
hash(long timezone,const XQPCollator * aCollation) const695 uint32_t QNameItem::hash(long timezone, const XQPCollator* aCollation) const
696 {
697 const void* tmp = theNormalizedQName;
698 return hashfun::h32(&tmp, sizeof(void*), FNV_32_INIT);
699 }
700
701
getType() const702 store::Item* QNameItem::getType() const
703 {
704 return GET_STORE().theSchemaTypeNames[store::XS_QNAME];
705 }
706
707
getEBV() const708 bool QNameItem::getEBV() const
709 {
710 throw XQUERY_EXCEPTION(err::FORG0006,
711 ERROR_PARAMS(ZED(OperationNotDef_23), ZED(EffectiveBooleanValue), "QName"));
712 }
713
714
getStringValue() const715 zstring QNameItem::getStringValue() const
716 {
717 if (thePrefix.empty())
718 {
719 return getLocalName();
720 }
721 else
722 {
723 return (thePrefix + ":" + getLocalName());
724 }
725 }
726
727
getStringValue2(zstring & val) const728 void QNameItem::getStringValue2(zstring& val) const
729 {
730 if (thePrefix.empty())
731 {
732 val = getLocalName();
733 }
734 else
735 {
736 val.reserve(thePrefix.size() + getLocalName().size() + 1);
737 val = thePrefix;
738 val += ":";
739 val += getLocalName();
740 }
741 }
742
743
appendStringValue(zstring & buf) const744 void QNameItem::appendStringValue(zstring& buf) const
745 {
746 if (thePrefix.empty())
747 {
748 buf += getLocalName();
749 }
750 else
751 {
752 buf.reserve(buf.size() + thePrefix.size() + getLocalName().size() + 1);
753 buf += thePrefix;
754 buf += ":";
755 buf += getLocalName();
756 }
757 }
758
759
isIdQName() const760 bool QNameItem::isIdQName() const
761 {
762 if (ZSTREQ(getLocalName(), "id"))
763 {
764 if (ZSTREQ(getPrefix(), "xml") ||
765 ztd::equals(theNamespace, Store::XML_URI, Store::XML_URI_LEN))
766 return true;
767 }
768
769 return false;
770 }
771
772
isBaseUri() const773 bool QNameItem::isBaseUri() const
774 {
775 if (ZSTREQ(getLocalName(), "base"))
776 {
777 if (ZSTREQ(getPrefix(), "xml") ||
778 ztd::equals(getNamespace(), Store::XML_URI, Store::XML_URI_LEN))
779 return true;
780 }
781
782 return false;
783 }
784
785
show() const786 zstring QNameItem::show() const
787 {
788 zstring res("xs:QName(");
789 res += getNamespace();
790 res += ",";
791 res += getPrefix();
792 res += ",";
793 res += getLocalName();
794 res += ")";
795 return res;
796 }
797
798 /*******************************************************************************
799 class NotationItem
800 ********************************************************************************/
801
NotationItem(const zstring & nameSpace,const zstring & prefix,const zstring & localName)802 NotationItem::NotationItem(
803 const zstring& nameSpace,
804 const zstring& prefix,
805 const zstring& localName)
806 {
807 store::Item_t temp;
808 GET_FACTORY().createQName(temp, nameSpace, prefix, localName);
809 theQName = static_cast<QNameItem*>(temp.getp());
810 }
811
812
NotationItem(store::Item * qname)813 NotationItem::NotationItem(store::Item* qname)
814 {
815 theQName = qname;
816 }
817
818
equals(const store::Item * item,long timezone,const XQPCollator * aCollation) const819 bool NotationItem::equals(
820 const store::Item* item,
821 long timezone,
822 const XQPCollator* aCollation) const
823 {
824 return theQName->equals(
825 static_cast<const NotationItem*>(item)->theQName);
826 }
827
828
getType() const829 store::Item* NotationItem::getType() const
830 {
831 return GET_STORE().theSchemaTypeNames[store::XS_NOTATION];
832 }
833
834
getStringValue() const835 zstring NotationItem::getStringValue() const
836 {
837 return theQName->getStringValue();
838 }
839
840
getStringValue2(zstring & val) const841 void NotationItem::getStringValue2(zstring& val) const
842 {
843 theQName->getStringValue2(val);
844 }
845
846
appendStringValue(zstring & buf) const847 void NotationItem::appendStringValue(zstring& buf) const
848 {
849 theQName->appendStringValue(buf);
850 }
851
852
show() const853 zstring NotationItem::show() const
854 {
855 zstring res("xs:NOTATION(");
856 res += theQName->getStringValue();
857 res += ")";
858 return res;
859 }
860
861
~NotationItem()862 NotationItem::~NotationItem()
863 {
864 }
865
866
867 /*******************************************************************************
868 class AnyUriItem
869 ********************************************************************************/
getType() const870 store::Item* AnyUriItem::getType() const
871 {
872 return GET_STORE().theSchemaTypeNames[store::XS_ANY_URI];
873 }
874
875
hash(long timezone,const XQPCollator * aCollation) const876 uint32_t AnyUriItem::hash(long timezone, const XQPCollator* aCollation) const
877 {
878 return hashfun::h32(theValue.data(), (uint32_t)theValue.size());
879 }
880
881
getEBV() const882 bool AnyUriItem::getEBV() const
883 {
884 return ! (theValue == "");
885 }
886
887
show() const888 zstring AnyUriItem::show() const
889 {
890 zstring res("xs:anyURI(");
891 res += theValue;
892 res += ")";
893 return res;
894 }
895
896
isAncestor(const store::Item_t & aOther) const897 bool AnyUriItem::isAncestor(const store::Item_t& aOther) const
898 {
899 store::Item_t lThisUri;
900 zstring tempValue=theValue;
901 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
902 return lThisUri->isAncestor(aOther);
903 }
904
905
isFollowingSibling(const store::Item_t & aOther) const906 bool AnyUriItem::isFollowingSibling(const store::Item_t& aOther) const
907 {
908 store::Item_t lThisUri;
909 zstring tempValue = theValue;
910 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
911 return lThisUri->isFollowingSibling(aOther);
912 }
913
914
isFollowing(const store::Item_t & aOther) const915 bool AnyUriItem::isFollowing(const store::Item_t& aOther) const
916 {
917 store::Item_t lThisUri;
918 zstring tempValue = theValue;
919 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
920 return lThisUri->isFollowing(aOther);
921 }
922
923
isDescendant(const store::Item_t & aOther) const924 bool AnyUriItem::isDescendant(const store::Item_t& aOther) const
925 {
926 store::Item_t lThisUri;
927 zstring tempValue = theValue;
928 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
929 return lThisUri->isDescendant(aOther);
930 }
931
932
isInSubtreeOf(const store::Item_t & aOther) const933 bool AnyUriItem::isInSubtreeOf(const store::Item_t& aOther) const
934 {
935 store::Item_t lThisUri;
936 zstring tempValue = theValue;
937 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
938 return lThisUri->isInSubtreeOf(aOther);
939 }
940
941
isPrecedingSibling(const store::Item_t & aOther) const942 bool AnyUriItem::isPrecedingSibling(const store::Item_t& aOther) const
943 {
944 store::Item_t lThisUri;
945 zstring tempValue = theValue;
946 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
947 return lThisUri->isPrecedingSibling(aOther);
948 }
949
950
isPreceding(const store::Item_t & aOther) const951 bool AnyUriItem::isPreceding(const store::Item_t& aOther) const
952 {
953 store::Item_t lThisUri;
954 zstring tempValue = theValue;
955 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
956 return lThisUri->isPreceding(aOther);
957 }
958
959
isChild(const store::Item_t & aOther) const960 bool AnyUriItem::isChild(const store::Item_t& aOther) const
961 {
962 store::Item_t lThisUri;
963 zstring tempValue = theValue;
964 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
965 return lThisUri->isChild(aOther);
966 }
967
968
isAttribute(const store::Item_t & aOther) const969 bool AnyUriItem::isAttribute(const store::Item_t& aOther) const
970 {
971 store::Item_t lThisUri;
972 zstring tempValue = theValue;
973 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
974 return lThisUri->isAttribute(aOther);
975 }
976
977
isParent(const store::Item_t & aOther) const978 bool AnyUriItem::isParent(const store::Item_t& aOther) const
979 {
980 store::Item_t lThisUri;
981 zstring tempValue = theValue;
982 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
983 return lThisUri->isParent(aOther);
984 }
985
986
isPrecedingInDocumentOrder(const store::Item_t & aOther) const987 bool AnyUriItem::isPrecedingInDocumentOrder(const store::Item_t& aOther) const
988 {
989 store::Item_t lThisUri;
990 zstring tempValue = theValue;
991 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
992 return lThisUri->isPrecedingInDocumentOrder(aOther);
993 }
994
995
isFollowingInDocumentOrder(const store::Item_t & aOther) const996 bool AnyUriItem::isFollowingInDocumentOrder(const store::Item_t& aOther) const
997 {
998 store::Item_t lThisUri;
999 zstring tempValue = theValue;
1000 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
1001 return lThisUri->isFollowingInDocumentOrder(aOther);
1002 }
1003
1004
getLevel() const1005 store::Item_t AnyUriItem::getLevel() const
1006 {
1007 store::Item_t lThisUri;
1008 zstring tempValue = theValue;
1009 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
1010 return lThisUri->getLevel();
1011 }
1012
1013
isAttributeRef() const1014 bool AnyUriItem::isAttributeRef() const
1015 {
1016 store::Item_t lThisUri;
1017 zstring tempValue = theValue;
1018 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
1019 return lThisUri->isAttributeRef();
1020 }
1021
1022
isCommentRef() const1023 bool AnyUriItem::isCommentRef() const
1024 {
1025 store::Item_t lThisUri;
1026 zstring tempValue = theValue;
1027 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
1028 return lThisUri->isCommentRef();
1029 }
1030
1031
isDocumentRef() const1032 bool AnyUriItem::isDocumentRef() const
1033 {
1034 store::Item_t lThisUri;
1035 zstring tempValue = theValue;
1036 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
1037 return lThisUri->isDocumentRef();
1038 }
1039
1040
isElementRef() const1041 bool AnyUriItem::isElementRef() const
1042 {
1043 store::Item_t lThisUri;
1044 zstring tempValue = theValue;
1045 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
1046 return lThisUri->isElementRef();
1047 }
1048
1049
isProcessingInstructionRef() const1050 bool AnyUriItem::isProcessingInstructionRef() const
1051 {
1052 store::Item_t lThisUri;
1053 zstring tempValue = theValue;
1054 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
1055 return lThisUri->isProcessingInstructionRef();
1056 }
1057
1058
isTextRef() const1059 bool AnyUriItem::isTextRef() const
1060 {
1061 store::Item_t lThisUri;
1062 zstring tempValue = theValue;
1063 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
1064 return lThisUri->isTextRef();
1065 }
1066
1067
isSibling(const store::Item_t & aOther) const1068 bool AnyUriItem::isSibling(const store::Item_t& aOther) const
1069 {
1070 store::Item_t lThisUri;
1071 zstring tempValue = theValue;
1072 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
1073 return lThisUri->isSibling(aOther);
1074 }
1075
1076
inSameTree(const store::Item_t & aOther) const1077 bool AnyUriItem::inSameTree(const store::Item_t& aOther) const
1078 {
1079 store::Item_t lThisUri;
1080 zstring tempValue = theValue;
1081 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
1082 return lThisUri->inSameTree(aOther);
1083 }
1084
1085
inCollection() const1086 bool AnyUriItem::inCollection() const
1087 {
1088 store::Item_t lThisUri;
1089 zstring tempValue = theValue;
1090 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
1091 return static_cast<StructuralAnyUriItem *>(lThisUri.getp())->inCollection();
1092 }
1093
1094
inSameCollection(const store::Item_t & aOther) const1095 bool AnyUriItem::inSameCollection(const store::Item_t& aOther) const
1096 {
1097 store::Item_t lThisUri;
1098 zstring tempValue = theValue;
1099 GET_FACTORY().createStructuralAnyURI(lThisUri, tempValue);
1100 return lThisUri->inSameCollection(aOther);
1101 }
1102
1103
1104 /*******************************************************************************
1105 class StructuralAnyUriItem
1106 ********************************************************************************/
1107
StructuralAnyUriItem(ulong collectionId,const TreeId & treeId,store::StoreConsts::NodeKind nodeKind,const OrdPath & ordPath)1108 StructuralAnyUriItem::StructuralAnyUriItem(
1109 ulong collectionId,
1110 const TreeId& treeId,
1111 store::StoreConsts::NodeKind nodeKind,
1112 const OrdPath& ordPath)
1113 :
1114 theCollectionId(collectionId),
1115 theTreeId(treeId),
1116 theNodeKind(nodeKind),
1117 theOrdPath(ordPath),
1118 theEncodedValue("")
1119 {
1120 }
1121
1122
StructuralAnyUriItem(zstring & value)1123 StructuralAnyUriItem::StructuralAnyUriItem(zstring& value)
1124 {
1125 if (value == "")
1126 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1127 ERROR_PARAMS(theEncodedValue));
1128
1129 theEncodedValue.take(value);
1130 std::istringstream input(theEncodedValue.str());
1131
1132 ulong prefixlen = (ulong)strlen("zorba:");
1133
1134 input.width(prefixlen);
1135
1136 std::string prefix;
1137 input >> prefix;
1138
1139 if (!input.good())
1140 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1141 ERROR_PARAMS(theEncodedValue));
1142
1143 if (prefix != "zorba:")
1144 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1145 ERROR_PARAMS(theEncodedValue));
1146
1147 input >> theCollectionId;
1148
1149 if (!input.good())
1150 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1151 ERROR_PARAMS(theEncodedValue));
1152
1153 char period;
1154 input >> period;
1155 if (!input.good())
1156 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1157 ERROR_PARAMS(theEncodedValue));
1158 if (period != '.')
1159 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1160 ERROR_PARAMS(theEncodedValue));
1161
1162
1163 input >> theTreeId;
1164 if (!input.good())
1165 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1166 ERROR_PARAMS(theEncodedValue));
1167
1168 input >> period;
1169 if (!input.good())
1170 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1171 ERROR_PARAMS(theEncodedValue));
1172 if (period != '.')
1173 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1174 ERROR_PARAMS(theEncodedValue));
1175
1176 int lNodeKind;
1177 input >> lNodeKind;
1178 theNodeKind = static_cast<store::StoreConsts::NodeKind>(lNodeKind);
1179 if (!input.good())
1180 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1181 ERROR_PARAMS(theEncodedValue));
1182 if (lNodeKind <= 0 || lNodeKind > 6)
1183 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1184 ERROR_PARAMS(theEncodedValue));
1185
1186 input >> period;
1187 if (period != '.')
1188 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1189 ERROR_PARAMS(theEncodedValue));
1190 if (!input.good())
1191 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1192 ERROR_PARAMS(theEncodedValue));
1193
1194 input >> prefix;
1195 if (!input.eof())
1196 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI,
1197 ERROR_PARAMS(theEncodedValue));
1198
1199 try
1200 {
1201 theOrdPath.deserialize(prefix);
1202 }
1203 catch(...)
1204 {
1205 throw ZORBA_EXCEPTION(zerr::ZAPI0028_INVALID_NODE_URI, ERROR_PARAMS(theEncodedValue));
1206 }
1207 }
1208
getType() const1209 store::Item* StructuralAnyUriItem::getType() const
1210 {
1211 return GET_STORE().theSchemaTypeNames[store::XS_ANY_URI];
1212 }
1213
1214
hash(long timezone,const XQPCollator * aCollation) const1215 uint32_t StructuralAnyUriItem::hash(long timezone, const XQPCollator* aCollation) const
1216 {
1217 return hashfun::h32(theEncodedValue.data(), (uint32_t)theEncodedValue.size());
1218 }
1219
1220
encode() const1221 void StructuralAnyUriItem::encode() const
1222 {
1223 ZORBA_FATAL(theNodeKind,"Unexpected node kind");
1224 std::ostringstream stream;
1225 stream << "zorba:"
1226 << theCollectionId << "."
1227 << theTreeId << "."
1228 << static_cast<int>(theNodeKind) << "."
1229 << theOrdPath.serialize();
1230 zorba::zstring lValue = stream.str();
1231 theEncodedValue.take(lValue);
1232 }
1233
1234
show() const1235 zstring StructuralAnyUriItem::show() const
1236 {
1237 zstring res("xs:anyURI(");
1238 res += getString();
1239 res += ")";
1240 return res;
1241 }
1242
1243
equals(const store::Item * other,long timezone,const XQPCollator * aCollation) const1244 bool StructuralAnyUriItem::equals(
1245 const store::Item* other,
1246 long timezone,
1247 const XQPCollator* aCollation) const
1248 {
1249 const StructuralAnyUriItem* lOther =
1250 dynamic_cast<const StructuralAnyUriItem*>(other);
1251
1252 if (lOther == NULL)
1253 {
1254 throw ZORBA_EXCEPTION(zerr::ZSTR0040_TYPE_ERROR,
1255 ERROR_PARAMS(ZED(NoCompareTypes_23),
1256 "xs:structuralAnyURI",
1257 other->getType()->getStringValue()));
1258 }
1259
1260 return (lOther->theCollectionId == theCollectionId &&
1261 lOther->theTreeId == theTreeId &&
1262 lOther->theNodeKind == theNodeKind &&
1263 lOther->theOrdPath == theOrdPath);
1264 }
1265
1266
compare(const Item * other,long timezone,const XQPCollator * aCollation) const1267 long StructuralAnyUriItem::compare(
1268 const Item* other,
1269 long timezone,
1270 const XQPCollator* aCollation) const
1271 {
1272 const StructuralAnyUriItem* lOther =
1273 dynamic_cast<const StructuralAnyUriItem*>(other);
1274
1275 if (lOther == NULL)
1276 {
1277 throw ZORBA_EXCEPTION(zerr::ZSTR0040_TYPE_ERROR,
1278 ERROR_PARAMS(ZED(NoCompareTypes_23),
1279 "xs:structuralAnyURI",
1280 other->getType()->getStringValue()));
1281 }
1282
1283 if (theCollectionId < lOther->theCollectionId)
1284 {
1285 return -1;
1286 }
1287 if (theCollectionId > lOther->theCollectionId)
1288 {
1289 return 1;
1290 }
1291 if (theTreeId < lOther->theTreeId)
1292 {
1293 return -1;
1294 }
1295 if (theTreeId > lOther->theTreeId)
1296 {
1297 return 1;
1298 }
1299 if (theNodeKind < lOther->theNodeKind)
1300 {
1301 return -1;
1302 }
1303 if (theNodeKind > lOther->theNodeKind)
1304 {
1305 return 1;
1306 }
1307 if (theOrdPath < lOther->theOrdPath)
1308 {
1309 return -1;
1310 }
1311 if (theOrdPath > lOther->theOrdPath)
1312 {
1313 return 1;
1314 }
1315 return 0;
1316 }
1317
1318
getStringValue() const1319 zstring StructuralAnyUriItem::getStringValue() const
1320 {
1321 return getString();
1322 }
1323
1324
getStringValue2(zstring & val) const1325 void StructuralAnyUriItem::getStringValue2(zstring& val) const
1326 {
1327 val = getString();
1328 }
1329
1330
appendStringValue(zstring & buf) const1331 void StructuralAnyUriItem::appendStringValue(zstring& buf) const
1332 {
1333 buf += getString();
1334 }
1335
1336
isAncestor(const store::Item_t & aOther) const1337 bool StructuralAnyUriItem::isAncestor(const store::Item_t& aOther) const
1338 {
1339 // Is the "other" an ancestor of "this"?
1340
1341 ZORBA_ASSERT(aOther->isAtomic());
1342
1343 AtomicItem* lOtherUriP = static_cast<AtomicItem *>(aOther.getp());
1344
1345 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1346 {
1347 store::Item_t lOtherUri;
1348 zstring tmp = lOtherUriP->getString();
1349 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1350 return isAncestor(lOtherUri);
1351 }
1352 else
1353 {
1354 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1355
1356 return
1357 (other->theCollectionId == theCollectionId &&
1358 other->theTreeId == theTreeId &&
1359 theOrdPath.getRelativePosition(other->theOrdPath) == OrdPath::ANCESTOR);
1360 }
1361 }
1362
1363
isFollowingSibling(const store::Item_t & aOther) const1364 bool StructuralAnyUriItem::isFollowingSibling(const store::Item_t& aOther) const
1365 {
1366 // Is the "other" a following sibling of "this"?
1367
1368 ZORBA_ASSERT(aOther->isAtomic());
1369
1370 AtomicItem* lOtherUriP = static_cast<AtomicItem *>(aOther.getp());
1371
1372 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1373 {
1374 store::Item_t lOtherUri;
1375 zstring tmp = lOtherUriP->getString();
1376 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1377 return isFollowingSibling(lOtherUri);
1378 }
1379 else
1380 {
1381 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1382
1383 return
1384 (other->theCollectionId == theCollectionId &&
1385 other->theTreeId == theTreeId &&
1386 other->theNodeKind != store::StoreConsts::attributeNode &&
1387 theNodeKind != store::StoreConsts::attributeNode &&
1388 theOrdPath.getRelativePosition2(other->theOrdPath) == OrdPath::FOLLOWING_SIBLING);
1389 }
1390 }
1391
1392
isFollowing(const store::Item_t & aOther) const1393 bool StructuralAnyUriItem::isFollowing(const store::Item_t& aOther) const
1394 {
1395 // Is the "other" a following node of "this"?
1396
1397 ZORBA_ASSERT(aOther->isAtomic());
1398
1399 AtomicItem* lOtherUriP = static_cast<AtomicItem *>(aOther.getp());
1400
1401 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1402 {
1403 store::Item_t lOtherUri;
1404 zstring tmp = lOtherUriP->getString();
1405 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1406 return isFollowing(lOtherUri);
1407 }
1408 else
1409 {
1410 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1411
1412 return
1413 (other->theCollectionId == theCollectionId &&
1414 other->theTreeId == theTreeId &&
1415 theOrdPath.getRelativePosition(other->theOrdPath) == OrdPath::FOLLOWING);
1416 }
1417 }
1418
1419
isDescendant(const store::Item_t & aOther) const1420 bool StructuralAnyUriItem::isDescendant(const store::Item_t& aOther) const
1421 {
1422 // Is the "other" a descendant of "this"?
1423
1424 ZORBA_ASSERT(aOther->isAtomic());
1425
1426 AtomicItem* lOtherUriP = static_cast<AtomicItem *>(aOther.getp());
1427
1428 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1429 {
1430 store::Item_t lOtherUri;
1431 zstring tmp = lOtherUriP->getString();
1432 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1433 return isDescendant(lOtherUri);
1434 }
1435 else
1436 {
1437 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1438 return
1439 (other->theCollectionId == theCollectionId &&
1440 other->theTreeId == theTreeId &&
1441 other->theNodeKind != store::StoreConsts::attributeNode &&
1442 theOrdPath.getRelativePosition(other->theOrdPath) == OrdPath::DESCENDANT);
1443 }
1444 }
1445
1446
isInSubtreeOf(const store::Item_t & aOther) const1447 bool StructuralAnyUriItem::isInSubtreeOf(const store::Item_t& aOther) const
1448 {
1449 // Is the "other" in the subtree rooted at "this"?
1450
1451 ZORBA_ASSERT(aOther->isAtomic());
1452
1453 AtomicItem* lOtherUriP = static_cast<AtomicItem *>(aOther.getp());
1454
1455 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1456 {
1457 store::Item_t lOtherUri;
1458 zstring tmp = lOtherUriP->getString();
1459 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1460 return isInSubtreeOf(lOtherUri);
1461 }
1462 else
1463 {
1464 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1465 return
1466 (other->theCollectionId == theCollectionId &&
1467 other->theTreeId == theTreeId &&
1468 theOrdPath.getRelativePosition(other->theOrdPath) == OrdPath::DESCENDANT);
1469 }
1470 }
1471
1472
isPrecedingSibling(const store::Item_t & aOther) const1473 bool StructuralAnyUriItem::isPrecedingSibling(const store::Item_t& aOther) const
1474 {
1475 // Is the "other" a preceding sibling of "this"?
1476
1477 ZORBA_ASSERT(aOther->isAtomic());
1478
1479 AtomicItem* lOtherUriP = static_cast<AtomicItem *>(aOther.getp());
1480
1481 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1482 {
1483 store::Item_t lOtherUri;
1484 zstring tmp = lOtherUriP->getString();
1485 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1486 return isPrecedingSibling(lOtherUri);
1487 }
1488 else
1489 {
1490 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1491 return
1492 (other->theCollectionId == theCollectionId &&
1493 other->theTreeId == theTreeId &&
1494 other->theNodeKind != store::StoreConsts::attributeNode &&
1495 theNodeKind != store::StoreConsts::attributeNode &&
1496 theOrdPath.getRelativePosition2(other->theOrdPath) == OrdPath::PRECEDING_SIBLING);
1497 }
1498 }
1499
1500
isPreceding(const store::Item_t & aOther) const1501 bool StructuralAnyUriItem::isPreceding(const store::Item_t& aOther) const
1502 {
1503 // Is the "other" a preceding node of "this"?
1504
1505 ZORBA_ASSERT(aOther->isAtomic());
1506
1507 AtomicItem* lOtherUriP = static_cast<AtomicItem *>(aOther.getp());
1508
1509 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1510 {
1511 store::Item_t lOtherUri;
1512 zstring tmp = lOtherUriP->getString();
1513 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1514 return isPreceding(lOtherUri);
1515 }
1516 else
1517 {
1518 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1519 return
1520 (other->theCollectionId == theCollectionId &&
1521 other->theTreeId == theTreeId &&
1522 theOrdPath.getRelativePosition(other->theOrdPath) == OrdPath::PRECEDING);
1523 }
1524 }
1525
1526
isChild(const store::Item_t & aOther) const1527 bool StructuralAnyUriItem::isChild(const store::Item_t& aOther) const
1528 {
1529 // Is the "other" a child of "this"?
1530
1531 ZORBA_ASSERT(aOther->isAtomic());
1532
1533 AtomicItem* lOtherUriP = static_cast<AtomicItem *>(aOther.getp());
1534
1535 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1536 {
1537 store::Item_t lOtherUri;
1538 zstring tmp = lOtherUriP->getString();
1539 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1540 return isChild(lOtherUri);
1541 }
1542 else
1543 {
1544 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1545 return
1546 (other->theCollectionId == theCollectionId &&
1547 other->theTreeId == theTreeId &&
1548 other->theNodeKind != store::StoreConsts::attributeNode &&
1549 theOrdPath.getRelativePosition2(other->theOrdPath) == OrdPath::CHILD);
1550 }
1551 }
1552
1553
isAttribute(const store::Item_t & aOther) const1554 bool StructuralAnyUriItem::isAttribute(const store::Item_t& aOther) const
1555 {
1556 // Is the "other" an attribute of "this"?
1557
1558 ZORBA_ASSERT(aOther->isAtomic());
1559
1560 AtomicItem* lOtherUriP = static_cast<AtomicItem *>(aOther.getp());
1561
1562 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1563 {
1564 store::Item_t lOtherUri;
1565 zstring tmp = lOtherUriP->getString();
1566 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1567 return isAttribute(lOtherUri);
1568 }
1569 else
1570 {
1571 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1572 return
1573 (other->theCollectionId == theCollectionId &&
1574 other->theTreeId == theTreeId &&
1575 other->theNodeKind == store::StoreConsts::attributeNode &&
1576 theOrdPath.getRelativePosition2(other->theOrdPath) == OrdPath::CHILD);
1577 }
1578 }
1579
1580
isParent(const store::Item_t & aOther) const1581 bool StructuralAnyUriItem::isParent(const store::Item_t& aOther) const
1582 {
1583 // Is the "other" an parent of "this"?
1584
1585 ZORBA_ASSERT(aOther->isAtomic());
1586
1587 AnyUriItem* lOtherUriP = static_cast<AnyUriItem *>(aOther.getp());
1588
1589 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1590 {
1591 store::Item_t lOtherUri;
1592 zstring tmp = lOtherUriP->getString();
1593 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1594 return isParent(lOtherUri);
1595 }
1596 else
1597 {
1598 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1599 return
1600 (other->theCollectionId == theCollectionId &&
1601 other->theTreeId == theTreeId &&
1602 theOrdPath.getRelativePosition2(other->theOrdPath) == OrdPath::PARENT);
1603 }
1604 }
1605
1606
isPrecedingInDocumentOrder(const store::Item_t & aOther) const1607 bool StructuralAnyUriItem::isPrecedingInDocumentOrder(const store::Item_t& aOther) const
1608 {
1609 ZORBA_ASSERT(aOther->isAtomic());
1610
1611 AtomicItem* lOtherUriP = static_cast<AtomicItem *>(aOther.getp());
1612
1613 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1614 {
1615 store::Item_t lOtherUri;
1616 zstring tmp = lOtherUriP->getString();
1617 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1618 return isPrecedingInDocumentOrder(lOtherUri);
1619 }
1620 else
1621 {
1622 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1623 return
1624 (theCollectionId > other->theCollectionId ||
1625 (theCollectionId == other->theCollectionId &&
1626 other->theTreeId < theTreeId) ||
1627 (theCollectionId == other->theCollectionId &&
1628 other->theTreeId == theTreeId &&
1629 theOrdPath > other->theOrdPath));
1630 }
1631 }
1632
1633
isFollowingInDocumentOrder(const store::Item_t & aOther) const1634 bool StructuralAnyUriItem::isFollowingInDocumentOrder(const store::Item_t& aOther) const
1635 {
1636 ZORBA_ASSERT(aOther->isAtomic());
1637
1638 AtomicItem* lOtherUriP = static_cast<AtomicItem *>(aOther.getp());
1639
1640 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1641 {
1642 store::Item_t lOtherUri;
1643 zstring tmp = lOtherUriP->getString();
1644 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1645 return isFollowingInDocumentOrder(lOtherUri);
1646 }
1647 else
1648 {
1649 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1650 return
1651 (theCollectionId < other->theCollectionId ||
1652 (theCollectionId == other->theCollectionId &&
1653 theTreeId < other->theTreeId) ||
1654 (theCollectionId == other->theCollectionId &&
1655 other->theTreeId == theTreeId &&
1656 theOrdPath < other->theOrdPath));
1657 }
1658 }
1659
1660
getLevel() const1661 store::Item_t StructuralAnyUriItem::getLevel() const
1662 {
1663 store::Item_t lResult;
1664 GET_FACTORY().createInteger(lResult, xs_integer(theOrdPath.getLevel()));
1665 return lResult;
1666 }
1667
1668
isAttributeRef() const1669 bool StructuralAnyUriItem::isAttributeRef() const
1670 {
1671 return theNodeKind == store::StoreConsts::attributeNode;
1672 }
1673
1674
isCommentRef() const1675 bool StructuralAnyUriItem::isCommentRef() const
1676 {
1677 return theNodeKind == store::StoreConsts::commentNode;
1678 }
1679
1680
isDocumentRef() const1681 bool StructuralAnyUriItem::isDocumentRef() const
1682 {
1683 return theNodeKind == store::StoreConsts::documentNode;
1684 }
1685
1686
isElementRef() const1687 bool StructuralAnyUriItem::isElementRef() const
1688 {
1689 return theNodeKind == store::StoreConsts::elementNode;
1690 }
1691
1692
isProcessingInstructionRef() const1693 bool StructuralAnyUriItem::isProcessingInstructionRef() const
1694 {
1695 return theNodeKind == store::StoreConsts::piNode;
1696 }
1697
1698
isTextRef() const1699 bool StructuralAnyUriItem::isTextRef() const
1700 {
1701 return theNodeKind == store::StoreConsts::textNode;
1702 }
1703
1704
isSibling(const store::Item_t & aOther) const1705 bool StructuralAnyUriItem::isSibling(const store::Item_t& aOther) const
1706 {
1707 ZORBA_ASSERT(aOther->isAtomic());
1708
1709 AnyUriItem* lOtherUriP = static_cast<AnyUriItem *>(aOther.getp());
1710
1711 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1712 {
1713 store::Item_t lOtherUri;
1714 zstring tmp = lOtherUriP->getString();
1715 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1716 return isSibling(lOtherUri);
1717 }
1718 else
1719 {
1720 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1721
1722 if (other->theCollectionId == theCollectionId &&
1723 other->theTreeId == theTreeId &&
1724 other->theNodeKind != store::StoreConsts::attributeNode &&
1725 theNodeKind != store::StoreConsts::attributeNode)
1726 {
1727 OrdPath::RelativePosition pos =
1728 theOrdPath.getRelativePosition2(other->theOrdPath);
1729
1730 return (pos == OrdPath::FOLLOWING_SIBLING ||
1731 pos==OrdPath::PRECEDING_SIBLING);
1732 }
1733 else
1734 {
1735 return false;
1736 }
1737 }
1738 }
1739
1740
inSameTree(const store::Item_t & aOther) const1741 bool StructuralAnyUriItem::inSameTree(const store::Item_t& aOther) const
1742 {
1743 ZORBA_ASSERT(aOther->isAtomic());
1744
1745 AnyUriItem* lOtherUriP = static_cast<AnyUriItem *>(aOther.getp());
1746
1747 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1748 {
1749 store::Item_t lOtherUri;
1750 zstring tmp = lOtherUriP->getString();
1751 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1752 return inSameTree(lOtherUri);
1753 }
1754 else
1755 {
1756 StructuralAnyUriItem* other = static_cast<StructuralAnyUriItem*>(aOther.getp());
1757 return (theCollectionId == other->theCollectionId &&
1758 other->theTreeId == theTreeId);
1759 }
1760 }
1761
1762
inCollection() const1763 bool StructuralAnyUriItem::inCollection() const
1764 {
1765 return theCollectionId != 0;
1766 }
1767
1768
inSameCollection(const store::Item_t & aOther) const1769 bool StructuralAnyUriItem::inSameCollection(const store::Item_t& aOther) const
1770 {
1771 ZORBA_ASSERT(aOther->isAtomic());
1772
1773 AnyUriItem* lOtherUriP = static_cast<AnyUriItem *>(aOther.getp());
1774
1775 if (lOtherUriP->getAnyUriTypeCode() != STRUCTURAL_INFORMATION_ANY_URI)
1776 {
1777 store::Item_t lOtherUri;
1778 zstring tmp = lOtherUriP->getString();
1779 GET_FACTORY().createStructuralAnyURI(lOtherUri, tmp);
1780 return inSameCollection(lOtherUri);
1781 }
1782 else
1783 {
1784 return
1785 (
1786 theCollectionId !=0 &&
1787 theCollectionId == static_cast<StructuralAnyUriItem*>(aOther.getp())->theCollectionId
1788 );
1789
1790 }
1791 }
1792
1793
1794 /*******************************************************************************
1795 class StringItem
1796 ********************************************************************************/
getType() const1797 store::Item* StringItem::getType() const
1798 {
1799 return GET_STORE().theSchemaTypeNames[store::XS_STRING];
1800 }
1801
1802
hash(long timezone,const XQPCollator * aCollation) const1803 uint32_t StringItem::hash(long timezone, const XQPCollator* aCollation) const
1804 {
1805 return utf8::hash(theValue, aCollation);
1806 }
1807
1808
equals(const store::Item * other,long timezone,const XQPCollator * aCollation) const1809 bool StringItem::equals(
1810 const store::Item* other,
1811 long timezone,
1812 const XQPCollator* aCollation) const
1813 {
1814 if (aCollation == NULL || aCollation->doMemCmp())
1815 return theValue == other->getString();
1816
1817 return (utf8::compare(theValue, other->getString(), aCollation) == 0);
1818 }
1819
1820
compare(const Item * other,long timezone,const XQPCollator * aCollation) const1821 long StringItem::compare(
1822 const Item* other,
1823 long timezone,
1824 const XQPCollator* aCollation) const
1825 {
1826 // Note: utf8::compare does byte comparison if the collation is null or
1827 // requires byte comparison.
1828 return utf8::compare(theValue, other->getString(), aCollation);
1829 }
1830
1831
getEBV() const1832 bool StringItem::getEBV() const
1833 {
1834 return ! ( theValue == "" );
1835 }
1836
1837
show() const1838 zstring StringItem::show() const
1839 {
1840 zstring res("xs:string(");
1841 res += theValue;
1842 res += ")";
1843 return res;
1844 }
1845
1846 #ifndef ZORBA_NO_FULL_TEXT
getTokens(TokenizerProvider const & provider,Tokenizer::State & state,iso639_1::type lang,bool wildcards) const1847 FTTokenIterator_t StringItem::getTokens(
1848 TokenizerProvider const &provider,
1849 Tokenizer::State &state,
1850 iso639_1::type lang,
1851 bool wildcards ) const
1852 {
1853 typedef NaiveFTTokenIterator::container_type tokens_t;
1854 unique_ptr<tokens_t> tokens( new tokens_t );
1855 AtomicItemTokenizerCallback callback( *tokens );
1856
1857 Tokenizer::ptr tokenizer;
1858 if ( provider.getTokenizer( lang, &state, &tokenizer ) )
1859 tokenizer->tokenize_string(
1860 theValue.data(), theValue.size(), lang, wildcards, callback
1861 );
1862
1863 return FTTokenIterator_t( new NaiveFTTokenIterator( tokens.release() ) );
1864 }
1865 #endif /* ZORBA_NO_FULL_TEXT */
1866
1867
1868 /*******************************************************************************
1869 class StreamableStringItem
1870 ********************************************************************************/
StreamableStringItem(std::istream & aStream,StreamReleaser streamReleaser,bool seekable)1871 StreamableStringItem::StreamableStringItem(
1872 std::istream& aStream,
1873 StreamReleaser streamReleaser,
1874 bool seekable) :
1875 theIstream(aStream),
1876 theIsMaterialized(false),
1877 theIsConsumed(false),
1878 theIsSeekable(seekable),
1879 theStreamReleaser(streamReleaser),
1880 theStreamableDependent(nullptr)
1881 {
1882 }
1883
StreamableStringItem(store::Item_t & aStreamableDependent)1884 StreamableStringItem::StreamableStringItem(
1885 store::Item_t& aStreamableDependent) :
1886 theIstream(aStreamableDependent->getStream()),
1887 theIsMaterialized(false),
1888 theIsConsumed(false),
1889 theIsSeekable(aStreamableDependent->isSeekable()),
1890 theStreamReleaser(nullptr),
1891 theStreamableDependent(aStreamableDependent)
1892 {
1893 ZORBA_ASSERT(theStreamableDependent->isStreamable());
1894
1895 // We copied the dependent item's stream and seekable flag in the initializer
1896 // above, but did NOT copy the StreamReleaser. The dependent item maintains
1897 // memory ownership of the stream in this way.
1898 }
1899
1900
appendStringValue(zstring & aBuf) const1901 void StreamableStringItem::appendStringValue(zstring& aBuf) const
1902 {
1903 if (!theIsMaterialized)
1904 {
1905 materialize();
1906 }
1907 aBuf += theValue;
1908 }
1909
1910
compare(const Item * aOther,long aTimezone,const XQPCollator * aCollator) const1911 long StreamableStringItem::compare(
1912 const Item* aOther,
1913 long aTimezone,
1914 const XQPCollator* aCollator) const
1915 {
1916 if (!theIsMaterialized)
1917 {
1918 materialize();
1919 }
1920 return StringItem::compare(aOther, aTimezone, aCollator);
1921 }
1922
1923
equals(store::Item const * aItem,long aTimezone,XQPCollator const * aCollator) const1924 bool StreamableStringItem::equals(
1925 store::Item const* aItem,
1926 long aTimezone,
1927 XQPCollator const* aCollator) const
1928 {
1929 if (!theIsMaterialized)
1930 {
1931 materialize();
1932 }
1933 return StringItem::equals(aItem, aTimezone, aCollator);
1934 }
1935
1936
getEBV() const1937 bool StreamableStringItem::getEBV() const
1938 {
1939 if (!theIsMaterialized)
1940 {
1941 materialize();
1942 }
1943 return StringItem::getEBV();
1944 }
1945
1946
getString() const1947 zstring const& StreamableStringItem::getString() const
1948 {
1949 if (!theIsMaterialized)
1950 {
1951 materialize();
1952 }
1953 return theValue;
1954 }
1955
1956
getStringValue() const1957 zstring StreamableStringItem::getStringValue() const
1958 {
1959 if (!theIsMaterialized)
1960 {
1961 materialize();
1962 }
1963 return theValue;
1964 }
1965
1966
getStringValue2(zstring & val) const1967 void StreamableStringItem::getStringValue2(zstring &val) const
1968 {
1969 if (!theIsMaterialized)
1970 {
1971 materialize();
1972 }
1973 val = theValue;
1974 }
1975
1976
hash(long aTimezone,XQPCollator const * aCollator) const1977 uint32_t StreamableStringItem::hash(
1978 long aTimezone,
1979 XQPCollator const* aCollator) const
1980 {
1981 if (!theIsMaterialized)
1982 {
1983 materialize();
1984 }
1985 return StringItem::hash(aTimezone, aCollator);
1986 }
1987
1988
show() const1989 zstring StreamableStringItem::show() const
1990 {
1991 if (!theIsMaterialized)
1992 {
1993 materialize();
1994 }
1995 return StringItem::show();
1996 }
1997
1998
isStreamable() const1999 bool StreamableStringItem::isStreamable() const
2000 {
2001 return true;
2002 }
2003
2004
isSeekable() const2005 bool StreamableStringItem::isSeekable() const
2006 {
2007 return theIsSeekable;
2008 }
2009
2010
getStream()2011 std::istream& StreamableStringItem::getStream()
2012 {
2013 // a non-seekable stream can only be consumed once
2014 // we raise an error if getStream is called twice
2015 // if a query requires a stream to be consumed more than once,
2016 // the query needs to make sure that the stream is explicitly
2017 // materialized before
2018 if (!theIsSeekable && theIsConsumed)
2019 {
2020 throw ZORBA_EXCEPTION( zerr::ZSTR0055_STREAMABLE_STRING_CONSUMED );
2021 }
2022 else
2023 {
2024 // if the stream is seekable, we seek to the beginning.
2025 // We are not using theIstream.seekg because the USER_ERROR that is thrown
2026 // by Zorba is lost possibly in an internal try/catch of the seekg
2027 std::streambuf * pbuf;
2028 pbuf = theIstream.rdbuf();
2029 pbuf->pubseekoff(0, std::ios::beg);
2030 theIstream.clear();
2031 }
2032 theIsConsumed = true;
2033 return theIstream;
2034 }
2035
2036
getStreamReleaser()2037 StreamReleaser StreamableStringItem::getStreamReleaser()
2038 {
2039 return theStreamReleaser;
2040 }
2041
2042
setStreamReleaser(StreamReleaser aReleaser)2043 void StreamableStringItem::setStreamReleaser(StreamReleaser aReleaser)
2044 {
2045 theStreamReleaser = aReleaser;
2046 }
2047
2048
materialize() const2049 void StreamableStringItem::materialize() const
2050 {
2051 StreamableStringItem* const lSsi = const_cast<StreamableStringItem*>(this);
2052 std::istream& lStream = lSsi->getStream();
2053
2054 lSsi->theIsMaterialized = true;
2055 lSsi->theIsConsumed = true;
2056
2057 char lBuf[4096];
2058 while (theIstream)
2059 {
2060 lStream.read(lBuf, sizeof(lBuf));
2061 lSsi->theValue.append(lBuf, static_cast<unsigned int>(lStream.gcount()));
2062 }
2063 }
2064
2065
2066 /*******************************************************************************
2067 class NormalizedStringItem
2068 ********************************************************************************/
getType() const2069 store::Item* NormalizedStringItem::getType() const
2070 {
2071 return GET_STORE().theSchemaTypeNames[store::XS_NORMALIZED_STRING];
2072 }
2073
2074
show() const2075 zstring NormalizedStringItem::show() const
2076 {
2077 zstring res("xs:NormalizedString(");
2078 res += theValue;
2079 res += ")";
2080 return res;
2081 }
2082
2083
2084 /*******************************************************************************
2085 class TokenItem
2086 ********************************************************************************/
getType() const2087 store::Item* TokenItem::getType() const
2088 {
2089 return GET_STORE().theSchemaTypeNames[store::XS_TOKEN];
2090 }
2091
2092
show() const2093 zstring TokenItem::show() const
2094 {
2095 zstring res("xs:TOKEN(");
2096 res += theValue;
2097 res += ")";
2098 return res;
2099 }
2100
2101
2102 /*******************************************************************************
2103 class LanguageItem
2104 ********************************************************************************/
getType() const2105 store::Item* LanguageItem::getType() const
2106 {
2107 return GET_STORE().theSchemaTypeNames[store::XS_LANGUAGE];
2108 }
2109
2110
show() const2111 zstring LanguageItem::show() const
2112 {
2113 zstring res("xs:LANGUAGE(");
2114 res += theValue;
2115 res += ")";
2116 return res;
2117 }
2118
2119
2120 /*******************************************************************************
2121 class NMTOKENItem
2122 ********************************************************************************/
getType() const2123 store::Item* NMTOKENItem::getType() const
2124 {
2125 return GET_STORE().theSchemaTypeNames[store::XS_NMTOKEN];
2126 }
2127
2128
show() const2129 zstring NMTOKENItem::show() const
2130 {
2131 zstring res("xs:NMTOKEN(");
2132 res += theValue;
2133 res += ")";
2134 return res;
2135 }
2136
2137
2138 /*******************************************************************************
2139 class NameItem
2140 ********************************************************************************/
getType() const2141 store::Item* NameItem::getType() const
2142 {
2143 return GET_STORE().theSchemaTypeNames[store::XS_NAME];
2144 }
2145
2146
show() const2147 zstring NameItem::show() const
2148 {
2149 zstring res("xs:NAME(");
2150 res += theValue;
2151 res += ")";
2152 return res;
2153 }
2154
2155
2156 /*******************************************************************************
2157 class NCNameItem
2158 ********************************************************************************/
getType() const2159 store::Item* NCNameItem::getType() const
2160 {
2161 return GET_STORE().theSchemaTypeNames[store::XS_NCNAME];
2162 }
2163
2164
show() const2165 zstring NCNameItem::show() const
2166 {
2167 zstring res("xs:NCName(");
2168 res += theValue;
2169 res += ")";
2170 return res;
2171 }
2172
2173
2174 /*******************************************************************************
2175 class IDItem
2176 ********************************************************************************/
getType() const2177 store::Item* IDItem::getType() const
2178 {
2179 return GET_STORE().theSchemaTypeNames[store::XS_ID];
2180 }
2181
2182
show() const2183 zstring IDItem::show() const
2184 {
2185 zstring res("xs:ID(");
2186 res += theValue;
2187 res += ")";
2188 return res;
2189 }
2190
2191
2192 /*******************************************************************************
2193 class IDREFItem
2194 ********************************************************************************/
getType() const2195 store::Item* IDREFItem::getType() const
2196 {
2197 return GET_STORE().theSchemaTypeNames[store::XS_IDREF];
2198 }
2199
2200
show() const2201 zstring IDREFItem::show() const
2202 {
2203 zstring res("xs:IDREF(");
2204 res += theValue;
2205 res += ")";
2206 return res;
2207 }
2208
2209
2210 /*******************************************************************************
2211 class ENTITYItem
2212 ********************************************************************************/
getType() const2213 store::Item* ENTITYItem::getType() const
2214 {
2215 return GET_STORE().theSchemaTypeNames[store::XS_ENTITY];
2216 }
2217
show() const2218 zstring ENTITYItem::show() const
2219 {
2220 zstring res("xs:ENTITY(");
2221 res += theValue;
2222 res += ")";
2223 return res;
2224 }
2225
2226
2227 /*******************************************************************************
2228 class DateTimeItem
2229 ********************************************************************************/
getStringValue() const2230 zstring DateTimeItem::getStringValue() const
2231 {
2232 return theValue.toString();
2233 }
2234
2235
getStringValue2(zstring & val) const2236 void DateTimeItem::getStringValue2(zstring& val) const
2237 {
2238 val = theValue.toString();
2239 }
2240
appendStringValue(zstring & buf) const2241 void DateTimeItem::appendStringValue(zstring& buf) const
2242 {
2243 buf += theValue.toString();
2244 }
2245
2246
getTypeCode() const2247 store::SchemaTypeCode DateTimeItem::getTypeCode() const
2248 {
2249 switch (theValue.getFacet())
2250 {
2251 case DateTime::GYEARMONTH_FACET:
2252 return store::XS_GYEAR_MONTH;
2253
2254 case DateTime::GYEAR_FACET:
2255 return store::XS_GYEAR;
2256
2257 case DateTime::GMONTH_FACET:
2258 return store::XS_GMONTH;
2259
2260 case DateTime::GMONTHDAY_FACET:
2261 return store::XS_GMONTH_DAY;
2262
2263 case DateTime::GDAY_FACET:
2264 return store::XS_GDAY;
2265
2266 case DateTime::DATE_FACET:
2267 return store::XS_DATE;
2268
2269 case DateTime::TIME_FACET:
2270 return store::XS_TIME;
2271
2272 case DateTime::DATETIME_FACET:
2273 return store::XS_DATETIME;
2274
2275 default:
2276 ZORBA_ASSERT(false);
2277 }
2278 }
2279
2280
getType() const2281 store::Item* DateTimeItem::getType() const
2282 {
2283 return GET_STORE().theSchemaTypeNames[getTypeCode()];
2284 }
2285
2286
equals(const store::Item * aItem,long timezone,const XQPCollator * coll) const2287 bool DateTimeItem::equals(
2288 const store::Item* aItem,
2289 long timezone,
2290 const XQPCollator* coll) const
2291 {
2292 try
2293 {
2294 return 0 == theValue.compare(&aItem->getDateTimeValue(), timezone);
2295 }
2296 catch (InvalidTimezoneException const&)
2297 {
2298 throw XQUERY_EXCEPTION(err::FODT0003);
2299 }
2300 }
2301
2302
compare(const Item * other,long timezone,const XQPCollator * aCollation) const2303 long DateTimeItem::compare(
2304 const Item* other,
2305 long timezone,
2306 const XQPCollator* aCollation) const
2307 {
2308 try
2309 {
2310 return theValue.compare(&other->getDateTimeValue(), timezone);
2311 }
2312 catch (InvalidTimezoneException const&)
2313 {
2314 throw XQUERY_EXCEPTION(err::FODT0003);
2315 }
2316 }
2317
2318
hash(long timezone,const XQPCollator * aCollation) const2319 uint32_t DateTimeItem::hash(long timezone, const XQPCollator* aCollation) const
2320 {
2321 return theValue.hash(0);
2322 }
2323
2324
getEBV() const2325 bool DateTimeItem::getEBV() const
2326 {
2327 switch (theValue.getFacet())
2328 {
2329 case DateTime::DATE_FACET:
2330 throw XQUERY_EXCEPTION(err::FORG0006,
2331 ERROR_PARAMS(ZED(OperationNotDef_23), ZED(EffectiveBooleanValue), "xs:Date"));
2332
2333 case DateTime::TIME_FACET:
2334 throw XQUERY_EXCEPTION(err::FORG0006,
2335 ERROR_PARAMS(ZED(OperationNotDef_23), ZED(EffectiveBooleanValue), "xs:Time"));
2336
2337 case DateTime::GYEARMONTH_FACET:
2338 throw XQUERY_EXCEPTION(err::FORG0006,
2339 ERROR_PARAMS(ZED(OperationNotDef_23), ZED(EffectiveBooleanValue), "xs:GYearMonth"));
2340
2341 case DateTime::GYEAR_FACET:
2342 throw XQUERY_EXCEPTION(err::FORG0006,
2343 ERROR_PARAMS(ZED(OperationNotDef_23), ZED(EffectiveBooleanValue), "xs:GYear"));
2344
2345 case DateTime::GMONTH_FACET:
2346 throw XQUERY_EXCEPTION(err::FORG0006,
2347 ERROR_PARAMS(ZED(OperationNotDef_23), ZED(EffectiveBooleanValue), "xs:GMonth"));
2348
2349 case DateTime::GMONTHDAY_FACET:
2350 throw XQUERY_EXCEPTION(err::FORG0006,
2351 ERROR_PARAMS(ZED(OperationNotDef_23), ZED(EffectiveBooleanValue), "xs:GMonthDay"));
2352
2353 case DateTime::GDAY_FACET:
2354 throw XQUERY_EXCEPTION(err::FORG0006,
2355 ERROR_PARAMS(ZED(OperationNotDef_23), ZED(EffectiveBooleanValue), "xs:GDay"));
2356
2357 default:
2358 throw XQUERY_EXCEPTION(err::FORG0006,
2359 ERROR_PARAMS(ZED(OperationNotDef_23), ZED(EffectiveBooleanValue), "dateTime"));
2360 }
2361 return false;
2362 }
2363
2364
show() const2365 zstring DateTimeItem::show() const
2366 {
2367 return theValue.toString();
2368 }
2369
2370
2371 /*******************************************************************************
2372 class DurationItem
2373 ********************************************************************************/
getDurationValue() const2374 const xs_duration& DurationItem::getDurationValue() const
2375 {
2376 return theValue;
2377 }
2378
2379
getDayTimeDurationValue() const2380 const xs_dayTimeDuration& DurationItem::getDayTimeDurationValue() const
2381 {
2382 return theValue;
2383 }
2384
2385
getYearMonthDurationValue() const2386 const xs_yearMonthDuration& DurationItem::getYearMonthDurationValue() const
2387 {
2388 return theValue;
2389 }
2390
2391
getStringValue() const2392 zstring DurationItem::getStringValue() const
2393 {
2394 return theValue.toString();
2395 }
2396
2397
getStringValue2(zstring & val) const2398 void DurationItem::getStringValue2(zstring& val) const
2399 {
2400 val = theValue.toString();
2401 }
2402
2403
appendStringValue(zstring & buf) const2404 void DurationItem::appendStringValue(zstring& buf) const
2405 {
2406 buf += theValue.toString();
2407 }
2408
2409
getTypeCode() const2410 store::SchemaTypeCode DurationItem::getTypeCode() const
2411 {
2412 switch (theValue.getFacet())
2413 {
2414 case Duration::DURATION_FACET:
2415 return store::XS_DURATION;
2416
2417 case Duration::DAYTIMEDURATION_FACET:
2418 return store::XS_DT_DURATION;
2419
2420 case Duration::YEARMONTHDURATION_FACET:
2421 default:
2422 return store::XS_YM_DURATION;
2423 }
2424 }
2425
2426
getType() const2427 store::Item* DurationItem::getType() const
2428 {
2429 return GET_STORE().theSchemaTypeNames[getTypeCode()];
2430 }
2431
2432
getEBV() const2433 bool DurationItem::getEBV() const
2434 {
2435 RAISE_ERROR_NO_LOC(err::FORG0006,
2436 ERROR_PARAMS(ZED(OperationNotDef_23), ZED(EffectiveBooleanValue), "duration"));
2437 }
2438
2439
show() const2440 zstring DurationItem::show() const
2441 {
2442 return theValue.toString();
2443 }
2444
2445
2446
2447 /*******************************************************************************
2448 class DoubleItem
2449 ********************************************************************************/
getType() const2450 store::Item* DoubleItem::getType() const
2451 {
2452 return GET_STORE().theSchemaTypeNames[store::XS_DOUBLE];
2453 }
2454
2455
getEBV() const2456 bool DoubleItem::getEBV() const
2457 {
2458 if (theValue.isNaN())
2459 {
2460 return false;
2461 }
2462 else
2463 {
2464 return !theValue.isZero();
2465 }
2466 }
2467
2468
getStringValue() const2469 zstring DoubleItem::getStringValue() const
2470 {
2471 return theValue.toString();
2472 }
2473
2474
getStringValue2(zstring & val) const2475 void DoubleItem::getStringValue2(zstring& val) const
2476 {
2477 val = theValue.toString();
2478 }
2479
2480
appendStringValue(zstring & buf) const2481 void DoubleItem::appendStringValue(zstring& buf) const
2482 {
2483 buf += theValue.toString();
2484 }
2485
2486
show() const2487 zstring DoubleItem::show() const
2488 {
2489 zstring res("xs:double(");
2490 appendStringValue(res);
2491 res += ")";
2492 return res;
2493 }
2494
2495
isNaN() const2496 bool DoubleItem::isNaN() const
2497 {
2498 return theValue.isNaN();
2499 }
2500
2501
isPosOrNegInf() const2502 bool DoubleItem::isPosOrNegInf() const
2503 {
2504 return theValue.isPosInf() || theValue.isNegInf();
2505 }
2506
2507
2508 uint32_t
hash(long timezone,const XQPCollator * aCollation) const2509 DoubleItem::hash(long timezone, const XQPCollator* aCollation) const
2510 {
2511 return theValue.hash();
2512 }
2513
2514
2515 /*******************************************************************************
2516 class FloatItem
2517 ********************************************************************************/
getType() const2518 store::Item* FloatItem::getType() const
2519 {
2520 return GET_STORE().theSchemaTypeNames[store::XS_FLOAT];
2521 }
2522
2523
getEBV() const2524 bool FloatItem::getEBV() const
2525 {
2526 if (theValue.isNaN())
2527 {
2528 return false;
2529 }
2530 else
2531 {
2532 return !theValue.isZero();
2533 }
2534 }
2535
2536
getStringValue() const2537 zstring FloatItem::getStringValue() const
2538 {
2539 return theValue.toString();
2540 }
2541
2542
getStringValue2(zstring & val) const2543 void FloatItem::getStringValue2(zstring& val) const
2544 {
2545 val = theValue.toString();
2546 }
2547
2548
appendStringValue(zstring & buf) const2549 void FloatItem::appendStringValue(zstring& buf) const
2550 {
2551 buf += theValue.toString();
2552 }
2553
2554
show() const2555 zstring FloatItem::show() const
2556 {
2557 zstring res("xs:float(");
2558 appendStringValue(res);
2559 res += ")";
2560 return res;
2561 }
2562
2563
isNaN() const2564 bool FloatItem::isNaN() const
2565 {
2566 return theValue.isNaN();
2567 }
2568
2569
isPosOrNegInf() const2570 bool FloatItem::isPosOrNegInf() const
2571 {
2572 return theValue.isPosInf() || theValue.isNegInf();
2573 }
2574
2575
hash(long timezone,const XQPCollator * aCollation) const2576 uint32_t FloatItem::hash(long timezone, const XQPCollator* aCollation) const
2577 {
2578 return theValue.hash();
2579 }
2580
2581
2582 /*******************************************************************************
2583 class DecimalItem
2584 ********************************************************************************/
2585
getType() const2586 store::Item* DecimalItem::getType() const
2587 {
2588 return GET_STORE().theSchemaTypeNames[store::XS_DECIMAL];
2589 }
2590
2591
getEBV() const2592 bool DecimalItem::getEBV() const
2593 {
2594 return ( theValue != xs_decimal::zero() );
2595 }
2596
2597
getStringValue() const2598 zstring DecimalItem::getStringValue() const
2599 {
2600 return theValue.toString();
2601 }
2602
2603
getStringValue2(zstring & val) const2604 void DecimalItem::getStringValue2(zstring& val) const
2605 {
2606 val = theValue.toString();
2607 }
2608
2609
appendStringValue(zstring & buf) const2610 void DecimalItem::appendStringValue(zstring& buf) const
2611 {
2612 buf += theValue.toString();
2613 }
2614
2615
isNaN() const2616 bool DecimalItem::isNaN() const
2617 {
2618 return theValue != theValue;
2619 }
2620
2621
show() const2622 zstring DecimalItem::show() const
2623 {
2624 zstring res("xs:decimal(");
2625 appendStringValue(res);
2626 res += ")";
2627 return res;
2628 }
2629
2630
2631 /*******************************************************************************
2632 class IntegerItemImpl
2633 ********************************************************************************/
2634
compare(Item const * other,long,const XQPCollator *) const2635 long IntegerItemImpl::compare( Item const *other, long,
2636 const XQPCollator* ) const {
2637 try
2638 {
2639 return theValue.compare( other->getIntegerValue() );
2640 }
2641 catch ( ZorbaException const& )
2642 {
2643 return getDecimalValue().compare( other->getDecimalValue() );
2644 }
2645 }
2646
equals(const store::Item * other,long,const XQPCollator *) const2647 bool IntegerItemImpl::equals( const store::Item* other, long,
2648 const XQPCollator*) const
2649 {
2650 try
2651 {
2652 return theValue == other->getIntegerValue();
2653 }
2654 catch (ZorbaException const&)
2655 {
2656 return getDecimalValue() == other->getDecimalValue();
2657 }
2658 }
2659
getDecimalValue() const2660 xs_decimal IntegerItemImpl::getDecimalValue() const
2661 {
2662 return xs_decimal(theValue);
2663 }
2664
2665
getLongValue() const2666 xs_long IntegerItemImpl::getLongValue() const
2667 {
2668 try
2669 {
2670 return to_xs_long(theValue);
2671 }
2672 catch ( std::range_error const& )
2673 {
2674 RAISE_ERROR_NO_LOC(err::FORG0001,
2675 ERROR_PARAMS(theValue, ZED(CastFromToFailed_34), "integer", "long"));
2676 }
2677 }
2678
2679
getUnsignedIntValue() const2680 xs_unsignedInt IntegerItemImpl::getUnsignedIntValue() const
2681 {
2682 try
2683 {
2684 return to_xs_unsignedInt(theValue);
2685 }
2686 catch ( std::range_error const& )
2687 {
2688 RAISE_ERROR_NO_LOC(err::FORG0001,
2689 ERROR_PARAMS(theValue, ZED(CastFromToFailed_34), "integer", "unsignedInt"));
2690 }
2691 }
2692
2693
getType() const2694 store::Item* IntegerItemImpl::getType() const
2695 {
2696 return GET_STORE().theSchemaTypeNames[store::XS_INTEGER];
2697 }
2698
2699
getEBV() const2700 bool IntegerItemImpl::getEBV() const
2701 {
2702 return !!theValue.sign();
2703 }
2704
2705
getStringValue() const2706 zstring IntegerItemImpl::getStringValue() const
2707 {
2708 return theValue.toString();
2709 }
2710
2711
getStringValue2(zstring & val) const2712 void IntegerItemImpl::getStringValue2(zstring& val) const
2713 {
2714 val = theValue.toString();
2715 }
2716
hash(long,const XQPCollator *) const2717 uint32_t IntegerItemImpl::hash(long, const XQPCollator*) const
2718 {
2719 return theValue.hash();
2720 }
2721
2722
appendStringValue(zstring & buf) const2723 void IntegerItemImpl::appendStringValue(zstring& buf) const
2724 {
2725 buf += theValue.toString();
2726 }
2727
2728
show() const2729 zstring IntegerItemImpl::show() const
2730 {
2731 zstring res("xs:integer(");
2732 appendStringValue(res);
2733 res += ")";
2734 return res;
2735 }
2736
2737
2738 /*******************************************************************************
2739 class NonPositiveIntegerItem
2740 ********************************************************************************/
compare(Item const * other,long,const XQPCollator *) const2741 long NonPositiveIntegerItem::compare( Item const *other, long,
2742 const XQPCollator* ) const {
2743 try
2744 {
2745 return theValue.compare( other->getIntegerValue() );
2746 }
2747 catch ( ZorbaException const& )
2748 {
2749 return getDecimalValue().compare( other->getDecimalValue() );
2750 }
2751 }
2752
equals(const store::Item * other,long,const XQPCollator *) const2753 bool NonPositiveIntegerItem::equals( const store::Item* other, long,
2754 const XQPCollator* ) const
2755 {
2756 try
2757 {
2758 return theValue == other->getIntegerValue();
2759 }
2760 catch (ZorbaException const&)
2761 {
2762 return getDecimalValue() == other->getDecimalValue();
2763 }
2764 }
2765
getType() const2766 store::Item* NonPositiveIntegerItem::getType() const
2767 {
2768 return GET_STORE().theSchemaTypeNames[store::XS_NON_POSITIVE_INTEGER];
2769 }
2770
getDecimalValue() const2771 xs_decimal NonPositiveIntegerItem::getDecimalValue() const
2772 {
2773 return xs_decimal(theValue);
2774 }
2775
getIntegerValue() const2776 xs_integer NonPositiveIntegerItem::getIntegerValue() const
2777 {
2778 return xs_integer(theValue);
2779 }
2780
getLongValue() const2781 xs_long NonPositiveIntegerItem::getLongValue() const
2782 {
2783 try
2784 {
2785 return to_xs_long(theValue);
2786 }
2787 catch ( std::range_error const& )
2788 {
2789 throw XQUERY_EXCEPTION(
2790 err::FORG0001,
2791 ERROR_PARAMS( theValue, ZED( CastFromToFailed_34 ), "integer", "long" )
2792 );
2793 }
2794 }
2795
getStringValue() const2796 zstring NonPositiveIntegerItem::getStringValue() const
2797 {
2798 return theValue.toString();
2799 }
2800
2801
getStringValue2(zstring & val) const2802 void NonPositiveIntegerItem::getStringValue2(zstring& val) const
2803 {
2804 val = theValue.toString();
2805 }
2806
hash(long,const XQPCollator *) const2807 uint32_t NonPositiveIntegerItem::hash(long, const XQPCollator*) const
2808 {
2809 return theValue.hash();
2810 }
2811
2812
appendStringValue(zstring & buf) const2813 void NonPositiveIntegerItem::appendStringValue(zstring& buf) const
2814 {
2815 buf += theValue.toString();
2816 }
2817
getEBV() const2818 bool NonPositiveIntegerItem::getEBV() const
2819 {
2820 return !!theValue.sign();
2821 }
2822
show() const2823 zstring NonPositiveIntegerItem::show() const
2824 {
2825 zstring res("xs:nonPositiveInteger(");
2826 appendStringValue(res);
2827 res += ")";
2828 return res;
2829 }
2830
2831
2832 /*******************************************************************************
2833 class NegativeIntegerItem
2834 ********************************************************************************/
getType() const2835 store::Item* NegativeIntegerItem::getType() const
2836 {
2837 return GET_STORE().theSchemaTypeNames[store::XS_NEGATIVE_INTEGER];
2838 }
2839
2840
show() const2841 zstring NegativeIntegerItem::show() const
2842 {
2843 zstring res("xs:negativeInteger(");
2844 appendStringValue(res);
2845 res += ")";
2846 return res;
2847 }
2848
2849
2850 /*******************************************************************************
2851 class NonNegativeIntegerItem
2852 ********************************************************************************/
compare(Item const * other,long,const XQPCollator *) const2853 long NonNegativeIntegerItem::compare( Item const *other, long,
2854 const XQPCollator* ) const {
2855 try
2856 {
2857 return theValue.compare( other->getUnsignedIntegerValue() );
2858 }
2859 catch ( ZorbaException const& )
2860 {
2861 return getDecimalValue().compare( other->getDecimalValue() );
2862 }
2863 }
2864
equals(const store::Item * other,long,const XQPCollator *) const2865 bool NonNegativeIntegerItem::equals( const store::Item* other, long,
2866 const XQPCollator* ) const
2867 {
2868 try
2869 {
2870 return theValue == other->getUnsignedIntegerValue();
2871 }
2872 catch (ZorbaException const&)
2873 {
2874 return getDecimalValue() == other->getDecimalValue();
2875 }
2876 }
2877
getType() const2878 store::Item* NonNegativeIntegerItem::getType() const
2879 {
2880 return GET_STORE().theSchemaTypeNames[store::XS_NON_NEGATIVE_INTEGER];
2881 }
2882
2883
getDecimalValue() const2884 xs_decimal NonNegativeIntegerItem::getDecimalValue() const
2885 {
2886 return xs_decimal(theValue);
2887 }
2888
getIntegerValue() const2889 xs_integer NonNegativeIntegerItem::getIntegerValue() const
2890 {
2891 return xs_integer(theValue);
2892 }
2893
getLongValue() const2894 xs_long NonNegativeIntegerItem::getLongValue() const
2895 {
2896 try
2897 {
2898 return to_xs_long(theValue);
2899 }
2900 catch ( std::range_error const& )
2901 {
2902 throw XQUERY_EXCEPTION(
2903 err::FORG0001,
2904 ERROR_PARAMS( theValue, ZED( CastFromToFailed_34 ), "integer", "long" )
2905 );
2906 }
2907 }
2908
getStringValue() const2909 zstring NonNegativeIntegerItem::getStringValue() const
2910 {
2911 return theValue.toString();
2912 }
2913
2914
getStringValue2(zstring & val) const2915 void NonNegativeIntegerItem::getStringValue2(zstring& val) const
2916 {
2917 val = theValue.toString();
2918 }
2919
hash(long,const XQPCollator *) const2920 uint32_t NonNegativeIntegerItem::hash(long, const XQPCollator*) const
2921 {
2922 return theValue.hash();
2923 }
2924
2925
appendStringValue(zstring & buf) const2926 void NonNegativeIntegerItem::appendStringValue(zstring& buf) const
2927 {
2928 buf += theValue.toString();
2929 }
2930
getEBV() const2931 bool NonNegativeIntegerItem::getEBV() const
2932 {
2933 return !!theValue.sign();
2934 }
2935
show() const2936 zstring NonNegativeIntegerItem::show() const
2937 {
2938 zstring res("xs:nonNegativeInteger(");
2939 appendStringValue(res);
2940 res += ")";
2941 return res;
2942 }
2943
2944
2945 /*******************************************************************************
2946 class PositiveIntegerItem
2947 ********************************************************************************/
getType() const2948 store::Item* PositiveIntegerItem::getType() const
2949 {
2950 return GET_STORE().theSchemaTypeNames[store::XS_POSITIVE_INTEGER];
2951 }
2952
2953
show() const2954 zstring PositiveIntegerItem::show() const
2955 {
2956 zstring res("xs:positiveInteger(");
2957 appendStringValue(res);
2958 res += ")";
2959 return res;
2960 }
2961
2962
2963 /*******************************************************************************
2964 class LongItem
2965 ********************************************************************************/
getDecimalValue() const2966 xs_decimal LongItem::getDecimalValue() const
2967 {
2968 return xs_decimal(theValue);
2969 }
2970
2971
getIntegerValue() const2972 xs_integer LongItem::getIntegerValue() const
2973 {
2974 return xs_integer(theValue);
2975 }
2976
getUnsignedIntegerValue() const2977 xs_nonNegativeInteger LongItem::getUnsignedIntegerValue() const {
2978 return xs_nonNegativeInteger( theValue >= 0 ? theValue : -theValue );
2979 }
2980
getType() const2981 store::Item* LongItem::getType() const
2982 {
2983 return GET_STORE().theSchemaTypeNames[store::XS_LONG];
2984 }
2985
2986
getEBV() const2987 bool LongItem::getEBV() const
2988 {
2989 return (theValue != 0);
2990 }
2991
2992
getStringValue() const2993 zstring LongItem::getStringValue() const
2994 {
2995 zstring result;
2996 ztd::to_string(theValue, &result);
2997 return result;
2998 }
2999
3000
getStringValue2(zstring & val) const3001 void LongItem::getStringValue2(zstring& val) const
3002 {
3003 ztd::to_string(theValue,&val);
3004 }
3005
3006
appendStringValue(zstring & buf) const3007 void LongItem::appendStringValue(zstring& buf) const
3008 {
3009 zstring temp;
3010 ztd::to_string(theValue, &temp);
3011 buf += temp;
3012 }
3013
3014
show() const3015 zstring LongItem::show() const
3016 {
3017 zstring res("xs:long(");
3018 appendStringValue(res);
3019 res += ")";
3020 return res;
3021 }
3022
3023
3024 /*******************************************************************************
3025 class IntItem
3026 ********************************************************************************/
getDecimalValue() const3027 xs_decimal IntItem::getDecimalValue() const
3028 {
3029 return xs_decimal(theValue);
3030 }
3031
3032
getIntegerValue() const3033 xs_integer IntItem::getIntegerValue() const
3034 {
3035 return Integer( theValue );
3036 }
3037
3038
getType() const3039 store::Item* IntItem::getType() const
3040 {
3041 return GET_STORE().theSchemaTypeNames[store::XS_INT];
3042 }
3043
3044
getEBV() const3045 bool IntItem::getEBV() const
3046 {
3047 return ( theValue != (int32_t)0 );
3048 }
3049
3050
getStringValue() const3051 zstring IntItem::getStringValue() const
3052 {
3053 zstring result;
3054 ztd::to_string(theValue, &result);
3055 return result;
3056 }
3057
3058
getStringValue2(zstring & val) const3059 void IntItem::getStringValue2(zstring& val) const
3060 {
3061 ztd::to_string(theValue, &val);
3062 }
3063
3064
appendStringValue(zstring & buf) const3065 void IntItem::appendStringValue(zstring& buf) const
3066 {
3067 zstring temp;
3068 ztd::to_string(theValue, &temp);
3069 buf += temp;
3070 }
3071
3072
show() const3073 zstring IntItem::show() const
3074 {
3075 zstring res("xs:int(");
3076 appendStringValue(res);
3077 res += ")";
3078 return res;
3079 }
3080
3081
3082 /*******************************************************************************
3083 class ShortItem
3084 ********************************************************************************/
getDecimalValue() const3085 xs_decimal ShortItem::getDecimalValue() const
3086 {
3087 return xs_decimal( theValue );
3088 }
3089
3090
getIntegerValue() const3091 xs_integer ShortItem::getIntegerValue() const
3092 {
3093 return Integer(theValue);
3094 }
3095
3096
getType() const3097 store::Item* ShortItem::getType() const
3098 {
3099 return GET_STORE().theSchemaTypeNames[store::XS_SHORT];
3100 }
3101
3102
getEBV() const3103 bool ShortItem::getEBV() const
3104 {
3105 return (theValue != 0);
3106 }
3107
3108
getStringValue() const3109 zstring ShortItem::getStringValue() const
3110 {
3111 zstring result;
3112 ztd::to_string(theValue, &result);
3113 return result;
3114 }
3115
3116
getStringValue2(zstring & val) const3117 void ShortItem::getStringValue2(zstring& val) const
3118 {
3119 ztd::to_string(theValue, &val);
3120 }
3121
3122
appendStringValue(zstring & buf) const3123 void ShortItem::appendStringValue(zstring& buf) const
3124 {
3125 zstring temp;
3126 ztd::to_string(theValue, &temp);
3127 buf += temp;
3128 }
3129
3130
show() const3131 zstring ShortItem::show() const
3132 {
3133 zstring res("xs:short(");
3134 appendStringValue(res);
3135 res += ")";
3136 return res;
3137 }
3138
3139
3140 /*******************************************************************************
3141 class ByteItem
3142 ********************************************************************************/
getDecimalValue() const3143 xs_decimal ByteItem::getDecimalValue() const
3144 {
3145 return xs_decimal(theValue);
3146 }
3147
3148
getIntegerValue() const3149 xs_integer ByteItem::getIntegerValue() const
3150 {
3151 return Integer(theValue);
3152 }
3153
3154
getType() const3155 store::Item* ByteItem::getType() const
3156 {
3157 return GET_STORE().theSchemaTypeNames[store::XS_BYTE];
3158 }
3159
3160
getEBV() const3161 bool ByteItem::getEBV() const
3162 {
3163 return (theValue != 0);
3164 }
3165
3166
getStringValue() const3167 zstring ByteItem::getStringValue() const
3168 {
3169 zstring result;
3170 ztd::to_string(theValue, &result);
3171 return result;
3172 }
3173
3174
getStringValue2(zstring & val) const3175 void ByteItem::getStringValue2(zstring& val) const
3176 {
3177 ztd::to_string(theValue, &val);
3178 }
3179
3180
appendStringValue(zstring & buf) const3181 void ByteItem::appendStringValue(zstring& buf) const
3182 {
3183 zstring temp;
3184 ztd::to_string(theValue, &temp);
3185 buf += temp;
3186 }
3187
3188
show() const3189 zstring ByteItem::show() const
3190 {
3191 zstring res("xs:byte(");
3192 appendStringValue(res);
3193 res += ")";
3194 return res;
3195 }
3196
3197
3198 /*******************************************************************************
3199 class UnsignedLongItem
3200 ********************************************************************************/
getDecimalValue() const3201 xs_decimal UnsignedLongItem::getDecimalValue() const
3202 {
3203 return xs_decimal(theValue);
3204 }
3205
3206
getIntegerValue() const3207 xs_integer UnsignedLongItem::getIntegerValue() const
3208 {
3209 return xs_integer(theValue);
3210 }
3211
3212
getUnsignedIntegerValue() const3213 xs_nonNegativeInteger UnsignedLongItem::getUnsignedIntegerValue() const
3214 {
3215 return xs_nonNegativeInteger(theValue);
3216 }
3217
3218
getType() const3219 store::Item* UnsignedLongItem::getType() const
3220 {
3221 return GET_STORE().theSchemaTypeNames[store::XS_UNSIGNED_LONG];
3222 }
3223
3224
getEBV() const3225 bool UnsignedLongItem::getEBV() const
3226 {
3227 return (theValue != 0);
3228 }
3229
3230
getStringValue() const3231 zstring UnsignedLongItem::getStringValue() const
3232 {
3233 zstring result;
3234 ztd::to_string(theValue, &result);
3235 return result;
3236 }
3237
3238
getStringValue2(zstring & val) const3239 void UnsignedLongItem::getStringValue2(zstring& val) const
3240 {
3241 ztd::to_string(theValue, &val);
3242 }
3243
3244
appendStringValue(zstring & buf) const3245 void UnsignedLongItem::appendStringValue(zstring& buf) const
3246 {
3247 zstring temp;
3248 ztd::to_string(theValue, &temp);
3249 buf += temp;
3250 }
3251
3252
show() const3253 zstring UnsignedLongItem::show() const
3254 {
3255 zstring res("xs:unsignedLong(");
3256 appendStringValue(res);
3257 res += ")";
3258 return res;
3259 }
3260
3261
3262 /*******************************************************************************
3263 class UnsignedIntItem
3264 ********************************************************************************/
getDecimalValue() const3265 xs_decimal UnsignedIntItem::getDecimalValue() const
3266 {
3267 return xs_decimal(theValue);
3268 }
3269
3270
getIntegerValue() const3271 xs_integer UnsignedIntItem::getIntegerValue() const
3272 {
3273 return Integer(theValue);
3274 }
3275
3276
getUnsignedIntegerValue() const3277 xs_nonNegativeInteger UnsignedIntItem::getUnsignedIntegerValue() const
3278 {
3279 return xs_nonNegativeInteger(theValue);
3280 }
3281
3282
getType() const3283 store::Item* UnsignedIntItem::getType() const
3284 {
3285 return GET_STORE().theSchemaTypeNames[store::XS_UNSIGNED_INT];
3286 }
3287
3288
getEBV() const3289 bool UnsignedIntItem::getEBV() const
3290 {
3291 return (theValue != 0);
3292 }
3293
3294
getStringValue() const3295 zstring UnsignedIntItem::getStringValue() const
3296 {
3297 zstring result;
3298 ztd::to_string(theValue, &result);
3299 return result;
3300 }
3301
3302
getStringValue2(zstring & val) const3303 void UnsignedIntItem::getStringValue2(zstring& val) const
3304 {
3305 ztd::to_string(theValue, &val);
3306 }
3307
3308
appendStringValue(zstring & buf) const3309 void UnsignedIntItem::appendStringValue(zstring& buf) const
3310 {
3311 zstring temp;
3312 ztd::to_string(theValue, &temp);
3313 buf += temp;
3314 }
3315
3316
show() const3317 zstring UnsignedIntItem::show() const
3318 {
3319 zstring res("xs:unsignedInt(");
3320 appendStringValue(res);
3321 res += ")";
3322 return res;
3323 }
3324
3325
3326 /*******************************************************************************
3327 class UnsignedShortItem
3328 ********************************************************************************/
getDecimalValue() const3329 xs_decimal UnsignedShortItem::getDecimalValue() const
3330 {
3331 return xs_decimal(theValue);
3332 }
3333
3334
getIntegerValue() const3335 xs_integer UnsignedShortItem::getIntegerValue() const
3336 {
3337 return Integer(theValue);
3338 }
3339
3340
getUnsignedIntegerValue() const3341 xs_nonNegativeInteger UnsignedShortItem::getUnsignedIntegerValue() const
3342 {
3343 return xs_nonNegativeInteger(theValue);
3344 }
3345
3346
getType() const3347 store::Item* UnsignedShortItem::getType() const
3348 {
3349 return GET_STORE().theSchemaTypeNames[store::XS_UNSIGNED_SHORT];
3350 }
3351
3352
getEBV() const3353 bool UnsignedShortItem::getEBV() const
3354 {
3355 return (theValue != 0);
3356 }
3357
3358
getStringValue() const3359 zstring UnsignedShortItem::getStringValue() const
3360 {
3361 zstring result;
3362 ztd::to_string(theValue, &result);
3363 return result;
3364 }
3365
3366
getStringValue2(zstring & val) const3367 void UnsignedShortItem::getStringValue2(zstring& val) const
3368 {
3369 ztd::to_string(theValue, &val);
3370 }
3371
3372
appendStringValue(zstring & buf) const3373 void UnsignedShortItem::appendStringValue(zstring& buf) const
3374 {
3375 zstring temp;
3376 ztd::to_string(theValue, &temp);
3377 buf += temp;
3378 }
3379
3380
show() const3381 zstring UnsignedShortItem::show() const
3382 {
3383 zstring res("xs:unsignedShort(");
3384 appendStringValue(res);
3385 res += ")";
3386 return res;
3387 }
3388
3389
3390 /*******************************************************************************
3391 class UnsignedByteItem
3392 ********************************************************************************/
getDecimalValue() const3393 xs_decimal UnsignedByteItem::getDecimalValue() const
3394 {
3395 return xs_decimal(theValue);
3396 }
3397
3398
getIntegerValue() const3399 xs_integer UnsignedByteItem::getIntegerValue() const
3400 {
3401 return xs_integer((uint32_t)theValue);
3402 }
3403
3404
getUnsignedIntegerValue() const3405 xs_nonNegativeInteger UnsignedByteItem::getUnsignedIntegerValue() const
3406 {
3407 return xs_nonNegativeInteger(theValue);
3408 }
3409
3410
getType() const3411 store::Item* UnsignedByteItem::getType() const
3412 {
3413 return GET_STORE().theSchemaTypeNames[store::XS_UNSIGNED_BYTE];
3414 }
3415
3416
getEBV() const3417 bool UnsignedByteItem::getEBV() const
3418 {
3419 return (theValue != 0);
3420 }
3421
3422
getStringValue() const3423 zstring UnsignedByteItem::getStringValue() const
3424 {
3425 zstring result;
3426 ztd::to_string(theValue, &result);
3427 return result;
3428 }
3429
3430
getStringValue2(zstring & val) const3431 void UnsignedByteItem::getStringValue2(zstring& val) const
3432 {
3433 ztd::to_string(theValue, &val);
3434 }
3435
3436
appendStringValue(zstring & buf) const3437 void UnsignedByteItem::appendStringValue(zstring& buf) const
3438 {
3439 zstring temp;
3440 ztd::to_string(theValue, &temp);
3441 buf += temp;
3442 }
3443
3444
show() const3445 zstring UnsignedByteItem::show() const
3446 {
3447 zstring res("xs:unsignedByte(");
3448 appendStringValue(res);
3449 res += ")";
3450 return res;
3451 }
3452
3453
3454 /*******************************************************************************
3455 class BooleanItem
3456 ********************************************************************************/
getType() const3457 store::Item* BooleanItem::getType() const
3458 {
3459 return GET_STORE().theSchemaTypeNames[store::XS_BOOLEAN];
3460 }
3461
3462
hash(long timezone,const XQPCollator * aCollation) const3463 uint32_t BooleanItem::hash(long timezone, const XQPCollator* aCollation) const
3464 {
3465 return theValue ? 0 : 1;
3466 }
3467
3468
getEBV() const3469 bool BooleanItem::getEBV() const
3470 {
3471 return theValue;
3472 }
3473
3474
getStringValue() const3475 zstring BooleanItem::getStringValue() const
3476 {
3477 if (theValue)
3478 return "true";
3479 else
3480 return "false";
3481 }
3482
3483
getStringValue2(zstring & val) const3484 void BooleanItem::getStringValue2(zstring& val) const
3485 {
3486 if (theValue)
3487 val = "true";
3488 else
3489 val = "false";
3490 }
3491
3492
appendStringValue(zstring & buf) const3493 void BooleanItem::appendStringValue(zstring& buf) const
3494 {
3495 if (theValue)
3496 buf += "true";
3497 else
3498 buf += "false";
3499 }
3500
3501
show() const3502 zstring BooleanItem::show() const
3503 {
3504 zstring res("xs:boolean(");
3505 appendStringValue(res);
3506 res += ")";
3507 return res;
3508 }
3509
3510
3511 /*******************************************************************************
3512 class Base64BinaryItem
3513 ********************************************************************************/
3514 bool
equals(const store::Item * other,long timezone,const XQPCollator * aCollation) const3515 Base64BinaryItem::equals(
3516 const store::Item* other,
3517 long timezone,
3518 const XQPCollator* aCollation) const
3519 {
3520 if (isEncoded() == other->isEncoded())
3521 {
3522 size_t this_size, other_size;
3523 const char* this_data = getBase64BinaryValue(this_size);
3524 const char* other_data = other->getBase64BinaryValue(other_size);
3525 return this_size == other_size &&
3526 memcmp(this_data, other_data, this_size) == 0;
3527 }
3528 else
3529 {
3530 return getStringValue().compare(other->getStringValue()) == 0;
3531 }
3532 }
3533
3534
3535 uint32_t
hash(long timezone,const XQPCollator * aCollation) const3536 Base64BinaryItem::hash(long timezone, const XQPCollator* aCollation) const
3537 {
3538 // always need to hash on the string-value because otherwise
3539 // a base64 item that is encoded would have a different hash-value
3540 // as a base64 item that is decoded but represents the same binary content
3541 return utf8::hash(getStringValue(), aCollation);
3542 }
3543
3544
3545 const char*
getBase64BinaryValue(size_t & size) const3546 Base64BinaryItem::getBase64BinaryValue(size_t& size) const
3547 {
3548 size = theValue.size();
3549 return size > 0 ? &theValue[0] : "";
3550 }
3551
3552
getType() const3553 store::Item* Base64BinaryItem::getType() const
3554 {
3555 return GET_STORE().theSchemaTypeNames[store::XS_BASE64BINARY];
3556 }
3557
3558
getStringValue() const3559 zstring Base64BinaryItem::getStringValue() const
3560 {
3561 zstring lRes;
3562 getStringValue2(lRes);
3563 return lRes;
3564 }
3565
3566
getStringValue2(zstring & val) const3567 void Base64BinaryItem::getStringValue2(zstring& val) const
3568 {
3569 val.clear();
3570 appendStringValue(val);
3571 }
3572
3573
appendStringValue(zstring & buf) const3574 void Base64BinaryItem::appendStringValue(zstring& buf) const
3575 {
3576 if (theValue.empty())
3577 {
3578 return;
3579 }
3580 if (theIsEncoded)
3581 {
3582 buf.insert(buf.size(), &theValue[0], theValue.size());
3583 }
3584 else
3585 {
3586 std::vector<char> encoded;
3587 encoded.reserve(theValue.size());
3588 Base64::encode(theValue, encoded);
3589 buf.insert(buf.size(), &encoded[0], encoded.size());
3590 }
3591 }
3592
3593
show() const3594 zstring Base64BinaryItem::show() const
3595 {
3596 zstring res("xs:base64Binary(");
3597 appendStringValue(res);
3598 res += ")";
3599 return res;
3600 }
3601
3602
3603 /*******************************************************************************
3604 class StreamableStringItem
3605 ********************************************************************************/
getStringValue() const3606 zstring StreamableBase64BinaryItem::getStringValue() const
3607 {
3608 if (!theIsMaterialized)
3609 {
3610 materialize();
3611 }
3612 return Base64BinaryItem::getStringValue();
3613 }
3614
3615
getStringValue2(zstring & val) const3616 void StreamableBase64BinaryItem::getStringValue2(zstring& val) const
3617 {
3618 if (!theIsMaterialized)
3619 {
3620 materialize();
3621 }
3622 Base64BinaryItem::getStringValue2(val);
3623 }
3624
3625
appendStringValue(zstring & buf) const3626 void StreamableBase64BinaryItem::appendStringValue(zstring& buf) const
3627 {
3628 if (!theIsMaterialized)
3629 {
3630 materialize();
3631 }
3632 Base64BinaryItem::appendStringValue(buf);
3633 }
3634
3635
show() const3636 zstring StreamableBase64BinaryItem::show() const
3637 {
3638 if (!theIsMaterialized)
3639 {
3640 materialize();
3641 }
3642 zstring res("xs:base64Binary(");
3643 appendStringValue(res);
3644 res += ")";
3645 return res;
3646 }
3647
3648
3649 uint32_t
hash(long timezone,const XQPCollator * aCollation) const3650 StreamableBase64BinaryItem::hash(long timezone, const XQPCollator* aCollation) const
3651 {
3652 if (!theIsMaterialized)
3653 {
3654 materialize();
3655 }
3656 return Base64BinaryItem::hash(timezone, aCollation);
3657 }
3658
3659
3660 const char*
getBase64BinaryValue(size_t & s) const3661 StreamableBase64BinaryItem::getBase64BinaryValue(size_t& s) const
3662 {
3663 if (!theIsMaterialized)
3664 {
3665 materialize();
3666 }
3667 return Base64BinaryItem::getBase64BinaryValue(s);
3668 }
3669
3670
isStreamable() const3671 bool StreamableBase64BinaryItem::isStreamable() const
3672 {
3673 return true;
3674 }
3675
3676
isSeekable() const3677 bool StreamableBase64BinaryItem::isSeekable() const
3678 {
3679 return theIsSeekable;
3680 }
3681
3682
getStreamReleaser()3683 StreamReleaser StreamableBase64BinaryItem::getStreamReleaser()
3684 {
3685 return theStreamReleaser;
3686 }
3687
3688
setStreamReleaser(StreamReleaser aReleaser)3689 void StreamableBase64BinaryItem::setStreamReleaser(StreamReleaser aReleaser)
3690 {
3691 theStreamReleaser = aReleaser;
3692 }
3693
3694
getStream()3695 std::istream& StreamableBase64BinaryItem::getStream()
3696 {
3697 // a non-seekable stream can only be consumed once
3698 // we raise an error if getStream is called twice
3699 // if a query requires a stream to be consumed more than once,
3700 // the query needs to make sure that the stream is explicitly
3701 // materialized before
3702 if (!theIsSeekable && theIsConsumed)
3703 {
3704 throw ZORBA_EXCEPTION( zerr::ZSTR0055_STREAMABLE_STRING_CONSUMED );
3705 }
3706 else
3707 {
3708 // if the stream is seekable, we seek to the beginning.
3709 // We are not using theIstream.seekg because the USER_ERROR that is thrown
3710 // by Zorba is lost possibly in an internal try/catch of the seekg
3711 std::streambuf * pbuf;
3712 pbuf = theIstream.rdbuf();
3713 pbuf->pubseekoff(0, std::ios::beg);
3714 }
3715 theIsConsumed = true;
3716 return theIstream;
3717 }
3718
3719
materialize() const3720 void StreamableBase64BinaryItem::materialize() const
3721 {
3722 StreamableBase64BinaryItem* const s
3723 = const_cast<StreamableBase64BinaryItem*>(this);
3724 std::istream& lStream = s->getStream();
3725
3726 s->theIsMaterialized = true;
3727 s->theIsConsumed = true;
3728
3729 if (isSeekable())
3730 {
3731 lStream.seekg(0, std::ios::end);
3732 std::streampos len = lStream.tellg();
3733 lStream.seekg(0, std::ios::beg);
3734 if (len < std::streampos(0))
3735 {
3736 throw ZORBA_EXCEPTION( zerr::ZOSE0003_STREAM_READ_FAILURE );
3737 }
3738 if (len == std::streampos(0))
3739 {
3740 return;
3741 }
3742 s->theValue.reserve(len);
3743 char buf[1024];
3744 while (lStream.good())
3745 {
3746 lStream.read(buf, 1024);
3747 s->theValue.insert(s->theValue.end(), buf, buf + lStream.gcount());
3748 }
3749 }
3750 else
3751 {
3752 char buf[4048];
3753 while (lStream.good())
3754 {
3755 lStream.read(buf, 4048);
3756 if (lStream.gcount() > 0)
3757 {
3758 s->theValue.reserve(s->theValue.size() + lStream.gcount());
3759 s->theValue.insert(s->theValue.end(), buf, buf + lStream.gcount());
3760 }
3761 }
3762 }
3763 }
3764
3765
3766 /*******************************************************************************
3767 class HexBinaryItem
3768 ********************************************************************************/
getType() const3769 store::Item* HexBinaryItem::getType() const
3770 {
3771 return GET_STORE().theSchemaTypeNames[store::XS_HEXBINARY];
3772 }
3773
3774
getStringValue() const3775 zstring HexBinaryItem::getStringValue() const
3776 {
3777 return theValue.str();
3778 }
3779
3780
getStringValue2(zstring & val) const3781 void HexBinaryItem::getStringValue2(zstring& val) const
3782 {
3783 val = theValue.str();
3784 }
3785
3786
appendStringValue(zstring & buf) const3787 void HexBinaryItem::appendStringValue(zstring& buf) const
3788 {
3789 buf += theValue.str();
3790 }
3791
3792
show() const3793 zstring HexBinaryItem::show() const
3794 {
3795 zstring res("xs:hexBinary(");
3796 appendStringValue(res);
3797 res += ")";
3798 return res;
3799 }
3800
3801
hash(long timezone,const XQPCollator * aCollation) const3802 uint32_t HexBinaryItem::hash(long timezone, const XQPCollator* aCollation) const
3803 {
3804 return theValue.hash();
3805 }
3806
3807
3808 /*******************************************************************************
3809 class ErrorItem
3810 ********************************************************************************/
~ErrorItem()3811 ErrorItem::~ErrorItem()
3812 {
3813 if (theError)
3814 {
3815 delete theError;
3816 theError = NULL;
3817 }
3818 }
3819
3820
show() const3821 zstring ErrorItem::show() const
3822 {
3823 return theError->what();
3824 }
3825
3826
3827 #ifndef ZORBA_NO_FULL_TEXT
3828
3829 /*******************************************************************************
3830 class AtomicItemTokenizerCallback
3831 ********************************************************************************/
3832
AtomicItemTokenizerCallback(container_type & tokens)3833 AtomicItemTokenizerCallback::AtomicItemTokenizerCallback(
3834 container_type &tokens
3835 ) :
3836 tokens_( tokens )
3837 {
3838 }
3839
token(char const * utf8_s,size_type utf8_len,iso639_1::type lang,size_type token_no,size_type sent_no,size_type para_no,Item const *)3840 void AtomicItemTokenizerCallback::token(
3841 char const *utf8_s,
3842 size_type utf8_len,
3843 iso639_1::type lang,
3844 size_type token_no,
3845 size_type sent_no,
3846 size_type para_no,
3847 Item const*
3848 ) {
3849 FTToken const t( utf8_s, utf8_len, token_no, lang );
3850 tokens_.push_back( t );
3851 }
3852
3853 #endif /* ZORBA_NO_FULL_TEXT */
3854
3855
3856 } // namespace simplestore
3857 } // namespace zorba
3858 /* vim:set et sw=2 ts=2: */
3859