1 /*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "stdafx.h"
17
18 #include "zorbamisc/config/platform.h"
19
20 #include "diagnostics/xquery_diagnostics.h"
21 #include "diagnostics/assert.h"
22 #include "diagnostics/util_macros.h"
23
24 #include "store/api/copymode.h"
25
26 #include "store_defs.h"
27 #include "simple_store.h"
28 #include "simple_item_factory.h"
29 #include "atomic_items.h"
30 #include "node_items.h"
31 #include "node_iterators.h"
32 #include "simple_temp_seq.h"
33 #include "simple_pul.h"
34 #include "qname_pool.h"
35 #include "string_pool.h"
36 #include "node_factory.h"
37 #include "tree_id.h"
38
39 #ifdef ZORBA_WITH_JSON
40 # include "json_items.h"
41 #endif
42
43 #include "util/ascii_util.h"
44
45
46 namespace zorba { namespace simplestore {
47
48
BasicItemFactory(UriPool * uriPool,QNamePool * qnPool)49 BasicItemFactory::BasicItemFactory(UriPool* uriPool, QNamePool* qnPool)
50 :
51 theUriPool(uriPool),
52 theQNamePool(qnPool),
53 theTrueItem(new BooleanItem(true)),
54 theFalseItem(new BooleanItem(false))
55 #ifdef ZORBA_WITH_JSON
56 ,theNullItem(new json::JSONNull())
57 #endif
58 {
59 }
60
61
~BasicItemFactory()62 BasicItemFactory::~BasicItemFactory()
63 {
64 theFalseItem = NULL;
65 theTrueItem = NULL;
66 theQNamePool = NULL;
67 theUriPool = NULL;
68 }
69
70
createUserTypedAtomicItem(store::Item_t & result,store::Item_t & baseItem,store::Item_t & typeName)71 bool BasicItemFactory::createUserTypedAtomicItem(
72 store::Item_t& result,
73 store::Item_t& baseItem,
74 store::Item_t& typeName)
75 {
76 result = new UserTypedAtomicItem(baseItem, typeName);
77 return true;
78 }
79
80
createQName(store::Item_t & result,const zstring & ns,const zstring & pre,const zstring & local)81 bool BasicItemFactory::createQName(
82 store::Item_t& result,
83 const zstring& ns,
84 const zstring& pre,
85 const zstring& local)
86 {
87 result = theQNamePool->insert(ns, pre, local);
88 return true;
89 }
90
91
createQName(store::Item_t & result,const char * ns,const char * pre,const char * ln)92 bool BasicItemFactory::createQName(
93 store::Item_t& result,
94 const char* ns,
95 const char* pre,
96 const char* ln)
97 {
98 result = theQNamePool->insert(ns, pre, ln);
99 return true;
100 }
101
102
103
createAnyURI(store::Item_t & result,zstring & value)104 bool BasicItemFactory::createAnyURI(store::Item_t& result, zstring& value)
105 {
106 zstring str = value;
107 theUriPool->insert(str);
108 result = new AnyUriItem(str);
109 return true;
110 }
111
112
createAnyURI(store::Item_t & result,const char * value)113 bool BasicItemFactory::createAnyURI(store::Item_t& result, const char* value)
114 {
115 zstring str;
116 theUriPool->insertc(value, str);
117 result = new AnyUriItem(str);
118 return true;
119 }
120
121
createStructuralAnyURI(store::Item_t & result,zstring & value)122 bool BasicItemFactory::createStructuralAnyURI(
123 store::Item_t& result,
124 zstring& value)
125 {
126 result = new StructuralAnyUriItem(value);
127 return true;
128 }
129
130
createStructuralAnyURI(store::Item_t & result,ulong collectionId,const TreeId & treeId,store::StoreConsts::NodeKind nodeKind,const OrdPath & ordPath)131 bool BasicItemFactory::createStructuralAnyURI(
132 store::Item_t& result,
133 ulong collectionId,
134 const TreeId& treeId,
135 store::StoreConsts::NodeKind nodeKind,
136 const OrdPath& ordPath)
137 {
138 ZORBA_FATAL(nodeKind,"Unexpected node kind");
139 result = new StructuralAnyUriItem(collectionId, treeId, nodeKind, ordPath);
140 return true;
141 }
142
143
createString(store::Item_t & result,zstring & value)144 bool BasicItemFactory::createString(store::Item_t& result, zstring& value)
145 {
146 result = new StringItem(value);
147 return true;
148 }
149
150
createStreamableString(store::Item_t & result,std::istream & stream,StreamReleaser streamReleaser,bool seekable)151 bool BasicItemFactory::createStreamableString(
152 store::Item_t& result,
153 std::istream &stream,
154 StreamReleaser streamReleaser,
155 bool seekable)
156 {
157 result = new StreamableStringItem( stream, streamReleaser, seekable );
158 return true;
159 }
160
createSharedStreamableString(store::Item_t & result,store::Item_t & streamable_dependent)161 bool BasicItemFactory::createSharedStreamableString(
162 store::Item_t &result,
163 store::Item_t &streamable_dependent)
164 {
165 result = new StreamableStringItem( streamable_dependent );
166 return true;
167 }
168
169
createNormalizedString(store::Item_t & result,zstring & value)170 bool BasicItemFactory::createNormalizedString(store::Item_t& result, zstring& value)
171 {
172 result = new NormalizedStringItem(value);
173 return true;
174 }
175
176
createToken(store::Item_t & result,zstring & value)177 bool BasicItemFactory::createToken(store::Item_t& result, zstring& value )
178 {
179 result = new TokenItem(value);
180 return true;
181 }
182
183
createLanguage(store::Item_t & result,zstring & value)184 bool BasicItemFactory::createLanguage(store::Item_t& result, zstring& value )
185 {
186 result = new LanguageItem(value);
187 return true;
188 }
189
190
createNMTOKEN(store::Item_t & result,zstring & value)191 bool BasicItemFactory::createNMTOKEN(store::Item_t& result, zstring& value )
192 {
193 result = new NMTOKENItem(value);
194 return true;
195 }
196
197
createNMTOKENS(store::Item_t & result,zstring & value)198 bool BasicItemFactory::createNMTOKENS(store::Item_t& result, zstring& value )
199 {
200 // split value string into tokens
201 std::vector<zstring> atomicTextValues;
202 splitToAtomicTextValues(value, atomicTextValues);
203
204 //create VectorItem with all tokens
205 std::vector<store::Item_t> typedValues;
206 for ( unsigned int i = 0; i < atomicTextValues.size() ; i++)
207 {
208 store::Item_t resultItem;
209 if ( createNMTOKEN(resultItem, atomicTextValues[i]) )
210 {
211 typedValues.push_back(resultItem.getp());
212 }
213 }
214
215 result = new ItemVector(typedValues);
216 return true;
217 }
218
219
createName(store::Item_t & result,zstring & value)220 bool BasicItemFactory::createName(store::Item_t& result, zstring& value )
221 {
222 result = new NameItem(value);
223 return true;
224 }
225
226
createNCName(store::Item_t & result,zstring & value)227 bool BasicItemFactory::createNCName(store::Item_t& result, zstring& value )
228 {
229 result = new NCNameItem(value);
230 return true;
231 }
232
233
createID(store::Item_t & result,zstring & value)234 bool BasicItemFactory::createID(store::Item_t& result, zstring& value )
235 {
236 result = new IDItem(value);
237 return true;
238 }
239
240
createIDREF(store::Item_t & result,zstring & value)241 bool BasicItemFactory::createIDREF(store::Item_t& result, zstring& value)
242 {
243 result = new IDREFItem(value);
244 return true;
245 }
246
247
createIDREFS(store::Item_t & result,zstring & value)248 bool BasicItemFactory::createIDREFS(store::Item_t& result, zstring& value )
249 {
250 // split value string into tokens
251 std::vector<zstring> atomicTextValues;
252 splitToAtomicTextValues(value, atomicTextValues);
253
254 //create VectorItem with all tokens
255 std::vector<store::Item_t> typedValues;
256 for ( unsigned int i = 0; i < atomicTextValues.size() ; i++)
257 {
258 store::Item_t resultItem;
259 if ( createIDREF(resultItem, atomicTextValues[i]) )
260 {
261 typedValues.push_back(resultItem.getp());
262 }
263 }
264
265 result = new ItemVector(typedValues);
266 return true;
267 }
268
269
createENTITY(store::Item_t & result,zstring & value)270 bool BasicItemFactory::createENTITY(store::Item_t& result, zstring& value )
271 {
272 result = new ENTITYItem(value);
273 return true;
274 }
275
276
createENTITIES(store::Item_t & result,zstring & value)277 bool BasicItemFactory::createENTITIES(store::Item_t& result, zstring& value)
278 {
279 // split value string into tokens
280 std::vector<zstring> atomicTextValues;
281 splitToAtomicTextValues(value, atomicTextValues);
282
283 //create VectorItem with all tokens
284 std::vector<store::Item_t> typedValues;
285 for ( unsigned int i = 0; i < atomicTextValues.size() ; i++)
286 {
287 store::Item_t resultItem;
288 if ( createENTITY(resultItem, atomicTextValues[i]) )
289 {
290 typedValues.push_back(resultItem.getp());
291 }
292 }
293
294 result = new ItemVector(typedValues);
295 return true;
296 }
297
298
createUntypedAtomic(store::Item_t & result,zstring & value)299 bool BasicItemFactory::createUntypedAtomic(store::Item_t& result, zstring& value)
300 {
301 result = new UntypedAtomicItem(value);
302 return true;
303 }
304
305
createDouble(store::Item_t & result,const xs_double & value)306 bool BasicItemFactory::createDouble(
307 store::Item_t& result,
308 const xs_double& value)
309 {
310 result = new DoubleItem(value);
311 return true;
312 }
313
314
createFloat(store::Item_t & result,const xs_float & value)315 bool BasicItemFactory::createFloat(store::Item_t& result, const xs_float& value)
316 {
317 result = new FloatItem(value);
318 return true;
319 }
320
321
createDecimal(store::Item_t & result,const xs_decimal & value)322 bool BasicItemFactory::createDecimal(store::Item_t& result, const xs_decimal& value)
323 {
324 result = new DecimalItem(value);
325 return true;
326 }
327
328
createInteger(store::Item_t & result,const xs_integer & value)329 bool BasicItemFactory::createInteger(store::Item_t& result, const xs_integer& value)
330 {
331 result = new IntegerItemImpl( value );
332 return true;
333 }
334
335
createNonPositiveInteger(store::Item_t & result,const xs_integer & value)336 bool BasicItemFactory::createNonPositiveInteger(
337 store::Item_t& result,
338 const xs_integer& value)
339 {
340 ZORBA_ASSERT(value.sign() <= 0);
341 result = new NonPositiveIntegerItem( value );
342 return true;
343 }
344
345
createNegativeInteger(store::Item_t & result,const xs_integer & value)346 bool BasicItemFactory::createNegativeInteger(
347 store::Item_t& result,
348 const xs_integer& value)
349 {
350 ZORBA_ASSERT(value.sign() < 0);
351 result = new NegativeIntegerItem(value);
352 return true;
353 }
354
355
createNonNegativeInteger(store::Item_t & result,const xs_nonNegativeInteger & value)356 bool BasicItemFactory::createNonNegativeInteger(
357 store::Item_t& result,
358 const xs_nonNegativeInteger& value )
359 {
360 result = new NonNegativeIntegerItem( value );
361 return true;
362 }
363
364
365
createPositiveInteger(store::Item_t & result,const xs_positiveInteger & value)366 bool BasicItemFactory::createPositiveInteger(
367 store::Item_t& result,
368 const xs_positiveInteger& value)
369 {
370 ZORBA_ASSERT(value.sign() > 0);
371 result = new PositiveIntegerItem( value );
372 return true;
373 }
374
375
createLong(store::Item_t & result,xs_long value)376 bool BasicItemFactory::createLong(store::Item_t& result, xs_long value)
377 {
378 result = new LongItem(value);
379 return true;
380 }
381
382
createInt(store::Item_t & result,xs_int value)383 bool BasicItemFactory::createInt(store::Item_t& result, xs_int value)
384 {
385 result = new IntItem(value);
386 return true;
387 }
388
389
createShort(store::Item_t & result,xs_short value)390 bool BasicItemFactory::createShort(store::Item_t& result, xs_short value)
391 {
392 result = new ShortItem(value);
393 return true;
394 }
395
396
createByte(store::Item_t & result,xs_byte value)397 bool BasicItemFactory::createByte(store::Item_t& result, xs_byte value)
398 {
399 result = new ByteItem(value);
400 return true;
401 }
402
403
createUnsignedLong(store::Item_t & result,xs_unsignedLong value)404 bool BasicItemFactory::createUnsignedLong(store::Item_t& result,
405 xs_unsignedLong value)
406 {
407 result = new UnsignedLongItem(value);
408 return true;
409 }
410
411
createUnsignedInt(store::Item_t & result,xs_unsignedInt value)412 bool BasicItemFactory::createUnsignedInt(store::Item_t& result,
413 xs_unsignedInt value)
414 {
415 result = new UnsignedIntItem(value);
416 return true;
417 }
418
419
createUnsignedShort(store::Item_t & result,xs_unsignedShort value)420 bool BasicItemFactory::createUnsignedShort(store::Item_t& result,
421 xs_unsignedShort value)
422 {
423 result = new UnsignedShortItem(value);
424 return true;
425 }
426
427
createUnsignedByte(store::Item_t & result,xs_unsignedByte value)428 bool BasicItemFactory::createUnsignedByte(store::Item_t& result,
429 xs_unsignedByte value)
430 {
431 result = new UnsignedByteItem(value);
432 return true;
433 }
434
435
createBoolean(store::Item_t & result,xs_boolean value)436 bool BasicItemFactory::createBoolean(store::Item_t& result, xs_boolean value)
437 {
438 result = value?theTrueItem:theFalseItem;
439 return true;
440 }
441
442
createDateTime(store::Item_t & result,const xs_dateTime * value)443 bool BasicItemFactory::createDateTime(store::Item_t& result, const xs_dateTime* value)
444 {
445 result = new DateTimeItem(value);
446 return true;
447 }
448
createDateTime(store::Item_t & result,const xs_date * date,const xs_time * time)449 bool BasicItemFactory::createDateTime(
450 store::Item_t& result,
451 const xs_date* date,
452 const xs_time* time)
453 {
454 std::auto_ptr<DateTimeItem> dtin(new DateTimeItem());
455 int err = DateTime::createDateTime(date, time, dtin->theValue);
456 if (err == 0)
457 {
458 result = dtin.get();
459 dtin.release();
460 } // destroy object if error occured
461 return err == 0;
462 }
463
createDateTime(store::Item_t & result,short year,short month,short day,short hour,short minute,double second)464 bool BasicItemFactory::createDateTime(
465 store::Item_t& result,
466 short year,
467 short month,
468 short day,
469 short hour,
470 short minute,
471 double second)
472 {
473 DateTime dt;
474 TimeZone tz;
475
476 if(DateTime::createDateTime(year, month, day, hour, minute, second, &tz, dt) == 0)
477 {
478 result = new DateTimeItem(&dt);
479 return true;
480 }
481 else
482 {
483 result = NULL;
484 return false;
485 }
486 }
487
488
createDateTime(store::Item_t & result,short year,short month,short day,short hour,short minute,double second,short timeZone_hours)489 bool BasicItemFactory::createDateTime(
490 store::Item_t& result,
491 short year ,
492 short month,
493 short day,
494 short hour,
495 short minute,
496 double second,
497 short timeZone_hours)
498 {
499 DateTime dt;
500 TimeZone tz(timeZone_hours);
501
502 if (DateTime::createDateTime(year, month, day, hour, minute, second, &tz, dt) == 0)
503 {
504 result = new DateTimeItem(&dt);
505 return true;
506 }
507 else
508 {
509 result = NULL;
510 return false;
511 }
512 }
513
514
createDateTime(store::Item_t & result,const char * str,ulong strlen)515 bool BasicItemFactory::createDateTime(
516 store::Item_t& result,
517 const char* str,
518 ulong strlen)
519 {
520 DateTime dt;
521
522 if (DateTime::parseDateTime(str, strlen, dt) == 0)
523 {
524 result = new DateTimeItem(&dt);
525 return true;
526 }
527 else
528 {
529 result = NULL;
530 return false;
531 }
532 }
533
534
createDateTime(store::Item_t & result,const store::Item_t & date,const store::Item_t & time)535 bool BasicItemFactory::createDateTime(
536 store::Item_t& result,
537 const store::Item_t& date,
538 const store::Item_t& time)
539 {
540 if (date.isNull() || time.isNull())
541 {
542 result = NULL;
543 return false;
544 }
545 else
546 {
547 xs_date const &d = date->getDateValue();
548 xs_time const &t = time->getTimeValue();
549 if (! createDateTime(result, &d, &t))
550 throw XQUERY_EXCEPTION( err::FORG0008, ERROR_PARAMS( d, t ) );
551
552 return true;
553 }
554 }
555
556
createDate(store::Item_t & result,const xs_date * value)557 bool BasicItemFactory::createDate(store::Item_t& result, const xs_date* value)
558 {
559 result = new DateTimeItem(value);
560 return true;
561 }
562
563
createDate(store::Item_t & result,short year,short month,short day)564 bool BasicItemFactory::createDate(
565 store::Item_t& result,
566 short year,
567 short month,
568 short day )
569 {
570 DateTime dt;
571 TimeZone tz;
572
573 if(DateTime::createDate(year, month, day, &tz, dt) == 0)
574 {
575 result = new DateTimeItem(&dt);
576 return true;
577 }
578 else
579 {
580 result = NULL;
581 return false;
582 }
583 }
584
585
createDate(store::Item_t & result,const char * str,ulong strlen)586 bool BasicItemFactory::createDate(
587 store::Item_t& result,
588 const char* str,
589 ulong strlen)
590 {
591 DateTime dt;
592
593 if (DateTime::parseDate(str, strlen, dt) == 0)
594 {
595 result = new DateTimeItem(&dt);
596 return true;
597 }
598 else
599 {
600 result = NULL;
601 return false;
602 }
603 }
604
605
createTime(store::Item_t & result,const xs_time * value)606 bool BasicItemFactory::createTime(store::Item_t& result, const xs_time* value)
607 {
608 result = new DateTimeItem(value);
609 return true;
610 }
611
612
createTime(store::Item_t & result,const char * str,ulong strlen)613 bool BasicItemFactory::createTime(
614 store::Item_t& result,
615 const char* str,
616 ulong strlen)
617 {
618 DateTime dt;
619
620 if( DateTime::parseTime(str, strlen, dt) == 0)
621 {
622 result = new DateTimeItem(&dt);
623 return true;
624 }
625 else
626 {
627 result = NULL;
628 return false;
629 }
630 }
631
632
createTime(store::Item_t & result,short hour,short minute,double second)633 bool BasicItemFactory::createTime(
634 store::Item_t& result,
635 short hour,
636 short minute,
637 double second)
638 {
639 DateTime dt;
640 TimeZone tz;
641
642 if( DateTime::createTime(hour, minute, second, &tz, dt) == 0 )
643 {
644 result = new DateTimeItem(&dt);
645 return true;
646 }
647 else
648 {
649 result = NULL;
650 return false;
651 }
652 }
653
654
createTime(store::Item_t & result,short hour,short minute,double second,short timeZone_hours)655 bool BasicItemFactory::createTime(
656 store::Item_t& result,
657 short hour,
658 short minute,
659 double second,
660 short timeZone_hours)
661 {
662 DateTime dt;
663 TimeZone tz(timeZone_hours);
664
665 if(DateTime::createTime(hour, minute, second, &tz, dt) == 0)
666 {
667 result = new DateTimeItem(&dt);
668 return true;
669 }
670 else
671 {
672 result = NULL;
673 return false;
674 }
675 }
676
677
createGDay(store::Item_t & result,const xs_gDay * value)678 bool BasicItemFactory::createGDay(store::Item_t& result, const xs_gDay* value)
679 {
680 result = new DateTimeItem(value);
681 return true;
682 }
683
684
createGDay(store::Item_t & result,const char * str,ulong strlen)685 bool BasicItemFactory::createGDay(
686 store::Item_t& result,
687 const char* str,
688 ulong strlen)
689 {
690 DateTime dt;
691
692 if (DateTime::parseGDay(str, strlen, dt) == 0)
693 {
694 result = new DateTimeItem(&dt);
695 return true;
696 }
697 else
698 {
699 result = NULL;
700 return false;
701 }
702 }
703
704
createGDay(store::Item_t & result,short day)705 bool BasicItemFactory::createGDay(store::Item_t& result, short day)
706 {
707 DateTime dt;
708
709 if (DateTime::createGDay(day, dt) == 0)
710 {
711 result = new DateTimeItem(&dt);
712 return true;
713 }
714 else
715 {
716 result = NULL;
717 return false;
718 }
719 }
720
721
createGMonth(store::Item_t & result,const xs_gMonth * value)722 bool BasicItemFactory::createGMonth(store::Item_t& result, const xs_gMonth* value)
723 {
724 result = new DateTimeItem(value);
725 return true;
726 }
727
728
createGMonth(store::Item_t & result,const char * str,ulong strlen)729 bool BasicItemFactory::createGMonth(
730 store::Item_t& result,
731 const char* str,
732 ulong strlen)
733 {
734 DateTime dt;
735
736 if (DateTime::parseGMonth(str, strlen, dt) == 0)
737 {
738 result = new DateTimeItem(&dt);
739 return true;
740 }
741 else
742 {
743 result = NULL;
744 return false;
745 }
746 }
747
748
createGMonth(store::Item_t & result,short month)749 bool BasicItemFactory::createGMonth(store::Item_t& result, short month)
750 {
751 DateTime dt;
752
753 if(DateTime::createGMonth(month, dt) == 0)
754 {
755 result = new DateTimeItem(&dt);
756 return true;
757 }
758 else
759 {
760 result = NULL;
761 return false;
762 }
763 }
764
765
createGMonthDay(store::Item_t & result,const xs_gMonthDay * value)766 bool BasicItemFactory::createGMonthDay(
767 store::Item_t& result,
768 const xs_gMonthDay* value)
769 {
770 result = new DateTimeItem(value);
771 return true;
772 }
773
774
createGMonthDay(store::Item_t & result,const char * str,ulong strlen)775 bool BasicItemFactory::createGMonthDay(
776 store::Item_t& result,
777 const char* str,
778 ulong strlen)
779 {
780 DateTime dt;
781
782 if (DateTime::parseGMonthDay(str, strlen, dt) == 0)
783 {
784 result = new DateTimeItem(&dt);
785 return true;
786 }
787 else
788 {
789 result = NULL;
790 return false;
791 }
792 }
793
794
createGMonthDay(store::Item_t & result,short month,short day)795 bool BasicItemFactory::createGMonthDay(store::Item_t& result, short month, short day)
796 {
797 DateTime dt;
798
799 if(DateTime::createGMonthDay(month, day, dt) == 0)
800 {
801 result = new DateTimeItem(&dt);
802 return true;
803 } else {
804 result = NULL;
805 return false;
806 }
807 }
808
809
createGYear(store::Item_t & result,const xs_gYear * value)810 bool BasicItemFactory::createGYear(store::Item_t& result, const xs_gYear* value)
811 {
812 result = new DateTimeItem(value);
813 return true;
814 }
815
816
createGYear(store::Item_t & result,const char * str,ulong strlen)817 bool BasicItemFactory::createGYear(
818 store::Item_t& result,
819 const char* str,
820 ulong strlen)
821 {
822 DateTime dt;
823
824 if (DateTime::parseGYear(str, strlen, dt) == 0)
825 {
826 result = new DateTimeItem(&dt);
827 return true;
828 }
829 else
830 {
831 result = NULL;
832 return false;
833 }
834 }
835
836
createGYear(store::Item_t & result,short year)837 bool BasicItemFactory::createGYear(store::Item_t& result, short year)
838 {
839 DateTime dt;
840
841 if(DateTime::createGYear(year, dt) == 0)
842 {
843 result = new DateTimeItem(&dt);
844 return true;
845 }
846 else
847 {
848 result = NULL;
849 return false;
850 }
851 }
852
853
createGYearMonth(store::Item_t & result,const xs_gYearMonth * value)854 bool BasicItemFactory::createGYearMonth(
855 store::Item_t& result,
856 const xs_gYearMonth* value)
857 {
858 result = new DateTimeItem(value);
859 return true;
860 }
861
862
createGYearMonth(store::Item_t & result,const char * str,ulong strlen)863 bool BasicItemFactory::createGYearMonth(
864 store::Item_t& result,
865 const char* str,
866 ulong strlen)
867 {
868 DateTime dt;
869
870 if (DateTime::parseGYearMonth(str, strlen, dt) == 0)
871 {
872 result = new DateTimeItem(&dt);
873 return true;
874 }
875 else
876 {
877 result = NULL;
878 return false;
879 }
880 }
881
882
createGYearMonth(store::Item_t & result,short year,short month)883 bool BasicItemFactory::createGYearMonth(
884 store::Item_t& result,
885 short year,
886 short month)
887 {
888 DateTime dt;
889
890 if(DateTime::createGYearMonth(year, month, dt) == 0)
891 {
892 result = new DateTimeItem(&dt);
893 return true;
894 }
895 else
896 {
897 result = NULL;
898 return false;
899 }
900 }
901
902
createDuration(store::Item_t & result,xs_duration * value)903 bool BasicItemFactory::createDuration(
904 store::Item_t& result,
905 xs_duration* value)
906 {
907 result = new DurationItem(value);
908 return true;
909 }
910
911
createDuration(store::Item_t & result,const char * str,ulong strlen)912 bool BasicItemFactory::createDuration(
913 store::Item_t& result,
914 const char* str,
915 ulong strlen)
916 {
917 Duration d;
918 if (Duration::parseDuration(str, strlen, d) == 0)
919 {
920 result = new DurationItem(&d);
921 return true;
922 }
923
924 result = NULL;
925 return false;
926 }
927
928
createDuration(store::Item_t & result,short years,short months,short days,short hours,short minutes,double seconds)929 bool BasicItemFactory::createDuration(
930 store::Item_t& result,
931 short years,
932 short months,
933 short days,
934 short hours,
935 short minutes,
936 double seconds)
937 {
938 Duration d(Duration::DURATION_FACET, years, months, days, hours, minutes, seconds);
939 result = new DurationItem(&d);
940 return true;
941 }
942
943
createYearMonthDuration(store::Item_t & result,xs_yearMonthDuration * value)944 bool BasicItemFactory::createYearMonthDuration(
945 store::Item_t& result,
946 xs_yearMonthDuration* value )
947 {
948 result = new DurationItem(value);
949 return true;
950 }
951
createYearMonthDuration(store::Item_t & result,const char * str,ulong strlen)952 bool BasicItemFactory::createYearMonthDuration(
953 store::Item_t& result,
954 const char* str,
955 ulong strlen)
956 {
957 Duration d;
958 if (Duration::parseYearMonthDuration(str, strlen, d) == 0)
959 {
960 result = new DurationItem(&d);
961 return true;
962 }
963
964 result = NULL;
965 return false;
966 }
967
968
createDayTimeDuration(store::Item_t & result,xs_dayTimeDuration * value)969 bool BasicItemFactory::createDayTimeDuration(
970 store::Item_t& result,
971 xs_dayTimeDuration* value)
972 {
973 result = new DurationItem(value);
974 return true;
975 }
976
977
createDayTimeDuration(store::Item_t & result,const char * str,ulong strlen)978 bool BasicItemFactory::createDayTimeDuration(
979 store::Item_t& result,
980 const char* str,
981 ulong strlen)
982 {
983 Duration d;
984 if (Duration::parseDayTimeDuration(str, strlen, d) == 0)
985 {
986 result = new DurationItem(&d);
987 return true;
988 }
989
990 result = NULL;
991 return false;
992 }
993
994
createBase64Binary(store::Item_t & result,xs_base64Binary value)995 bool BasicItemFactory::createBase64Binary(
996 store::Item_t& result,
997 xs_base64Binary value)
998 {
999 const std::vector<char>& data = value.getData();
1000 result = new Base64BinaryItem(data.size()!=0?&data[0]:0, data.size(), true);
1001 return true;
1002 }
1003
createBase64Binary(store::Item_t & result,const char * value,size_t size,bool encoded)1004 bool BasicItemFactory::createBase64Binary(
1005 store::Item_t& result,
1006 const char* value,
1007 size_t size,
1008 bool encoded)
1009 {
1010 result = new Base64BinaryItem(value, size, encoded);
1011 return true;
1012 }
1013
1014
createStreamableBase64Binary(store::Item_t & result,std::istream & aStream,StreamReleaser aReleaser,bool seekable,bool encoded)1015 bool BasicItemFactory::createStreamableBase64Binary(
1016 store::Item_t& result,
1017 std::istream& aStream,
1018 StreamReleaser aReleaser,
1019 bool seekable,
1020 bool encoded)
1021 {
1022 result = new StreamableBase64BinaryItem(
1023 aStream, aReleaser, seekable, encoded
1024 );
1025 return true;
1026 }
1027
1028
createHexBinary(store::Item_t & result,xs_hexBinary value)1029 bool BasicItemFactory::createHexBinary(store::Item_t& result, xs_hexBinary value)
1030 {
1031 result = new HexBinaryItem(value);
1032 return true;
1033 }
1034
createNOTATION(store::Item_t & result,zstring & ns,zstring & prefix,zstring & local)1035 bool BasicItemFactory::createNOTATION(
1036 store::Item_t& result,
1037 zstring& ns,
1038 zstring& prefix,
1039 zstring& local)
1040 {
1041 result = new NotationItem(ns, prefix, local);
1042 return true;
1043 }
1044
createNOTATION(store::Item_t & result,zstring & str)1045 bool BasicItemFactory::createNOTATION(
1046 store::Item_t& result,
1047 zstring& str)
1048 {
1049 zstring nsuri;
1050 zstring prefix;
1051 zstring local;
1052
1053 ascii::trim_whitespace(str);
1054 zstring::size_type pos = str.rfind(":", str.size(), 1);
1055
1056 if (pos != zstring::npos)
1057 {
1058 nsuri = str.substr(0, pos);
1059 local = str.substr(pos+1, str.size());
1060 }
1061 else
1062 local = str;
1063
1064 result = new NotationItem(nsuri, prefix, local);
1065 return true;
1066 }
1067
1068
createNOTATION(store::Item_t & result,store::Item_t & qname)1069 bool BasicItemFactory::createNOTATION(store::Item_t& result, store::Item_t& qname)
1070 {
1071 result = new NotationItem(qname);
1072 return true;
1073 }
1074
1075
1076 /*******************************************************************************
1077 Create a new document node N and make it the root (and single node) of a new
1078 XML tree.
1079
1080 baseUri : The base-uri property of N. It may be NULL.
1081 docUri : The document-uri property of N. It may be NULL.
1082 ********************************************************************************/
createDocumentNode(store::Item_t & result,zstring & baseUri,zstring & docUri)1083 bool BasicItemFactory::createDocumentNode(
1084 store::Item_t& result,
1085 zstring& baseUri,
1086 zstring& docUri)
1087 {
1088 XmlTree* xmlTree = NULL;
1089 DocumentNode* n = NULL;
1090
1091 try
1092 {
1093 xmlTree = GET_STORE().getNodeFactory().createXmlTree();
1094
1095 n = GET_STORE().getNodeFactory().createDocumentNode(xmlTree, baseUri, docUri);
1096 }
1097 catch (...)
1098 {
1099 delete xmlTree;
1100 throw;
1101 }
1102
1103 result = n;
1104 return n != NULL;
1105 }
1106
1107
1108 /*******************************************************************************
1109 Create a new element node N and place it as the pos-th child of a given parent
1110 node. If no parent is given, N becomes the root (and single node) of a new XML
1111 tree.
1112
1113 parent : The parent P of the new element node; may be NULL.
1114 pos : The position, among the children of P, that N will occupy.
1115 If pos == current number of P's children, then N is appended
1116 to the list of children.
1117 nodeName : The node-name property of N.
1118 typeName : The type-name property of N.
1119 Not allowed to be NULL, use xsd:untyped instead.
1120 haveTypedValue: Whether the node has a typed value or not (element nodes with
1121 complex type and element-only content do not have typed value).
1122 haveEmptyValue: True if the typed value of the node is the empty sequence.
1123 This is the case if the element has a complex type with empty
1124 content.
1125 isId :
1126 isIdRefs :
1127 localBindings : A set S1 of namespace bindings. The namespaces property of N
1128 is set to S1, plus the ns binding implied by N's qname, plus
1129 all the ns bindings of P that are not overwritten by S1 or the
1130 ns binding implied by N's qname. Note: when called from an
1131 element constructor iterator, S1 is the set of ns bindings
1132 defined by ns decalration attrs that appear inside the
1133 constructor expr itself.
1134 baseUri : The base-uri property of N. It may be NULL, in which case,
1135 the base-uri property of N is the same as that of P. If P
1136 is NULL, then baseUri will NOT be null (see
1137 runtime/core/constructors.cpp).
1138
1139 The haveTypedValue and haveEmptyValue properties are actually a function of
1140 the node's type. However, since the store stores only the name of the type
1141 and does not know anything about the definition of that type, the caller
1142 of this method must provide the value for these two properties, which are
1143 needed to implement the getTypedValue() method.
1144 ********************************************************************************/
createElementNode(store::Item_t & result,store::Item * parent,ulong pos,store::Item_t & nodeName,store::Item_t & typeName,bool haveTypedValue,bool haveEmptyValue,const store::NsBindings & localBindings,zstring & baseUri,bool isInSubstitutionGroup)1145 bool BasicItemFactory::createElementNode(
1146 store::Item_t& result,
1147 store::Item* parent,
1148 ulong pos,
1149 store::Item_t& nodeName,
1150 store::Item_t& typeName,
1151 bool haveTypedValue,
1152 bool haveEmptyValue,
1153 const store::NsBindings& localBindings,
1154 zstring& baseUri,
1155 bool isInSubstitutionGroup)
1156 {
1157 XmlTree* xmlTree = NULL;
1158 ElementNode* n = NULL;
1159
1160 if ( typeName == NULL )
1161 throw ZORBA_EXCEPTION(zerr::ZAPI0014_INVALID_ARGUMENT,
1162 ERROR_PARAMS("null", ZED( NotAllowedForTypeName)));
1163
1164 assert(parent == NULL ||
1165 parent->getNodeKind() == store::StoreConsts::elementNode ||
1166 parent->getNodeKind() == store::StoreConsts::documentNode);
1167
1168 InternalNode* pnode = reinterpret_cast<InternalNode*>(parent);
1169
1170 try
1171 {
1172 if (parent == NULL)
1173 xmlTree = GET_STORE().getNodeFactory().createXmlTree();
1174
1175 n = GET_STORE().getNodeFactory().createElementNode(
1176 xmlTree,
1177 pnode,
1178 false,
1179 pos,
1180 nodeName,
1181 typeName,
1182 haveTypedValue,
1183 haveEmptyValue,
1184 isInSubstitutionGroup,
1185 &localBindings,
1186 baseUri);
1187 }
1188 catch (...)
1189 {
1190 delete xmlTree;
1191 throw;
1192 }
1193
1194 result = n;
1195 return n != NULL;
1196 }
1197
1198
1199 /*******************************************************************************
1200 Create a new element node N and place it as the last child of a given parent
1201 node. If no parent is given, N becomes the root (and single node) of a new XML
1202 tree.
1203
1204 Note: This method should be used only while constructing a new xml tree. More
1205 specifically, it should not be used if the parent node had a child/attribute
1206 that was deleted some time before the invcation of this method (see comment
1207 in method XmlNode::XmlNode).
1208
1209 parent : The parent P of the new element node; may be NULL.
1210 nodeName : The node-name property of N.
1211 typeName : The type-name property of N.
1212 Not allowed to be NULL, use xsd:untyped instead.
1213 haveTypedValue: Whether the node has a typed value or not (element nodes with
1214 complex type and element-only content do not have typed value).
1215 haveEmptyValue: True if the typed value of the node is the empty sequence.
1216 This is the case if the element has a complex type with empty
1217 content.
1218 isId :
1219 isIdRefs :
1220 localBindings : A set S1 of namespace bindings. The namespaces property of N
1221 is set to S1, plus the ns binding implied by N's qname, plus
1222 all the ns bindings of P that are not overwritten by S1 or the
1223 ns binding implied by N's qname. Note: when called from an
1224 element constructor iterator, S1 is the set of ns bindings
1225 defined by ns decalration attrs that appear inside the
1226 constructor expr itself.
1227 baseUri : The base-uri property of N. It may be NULL, in which case,
1228 the base-uri property of N is the same as that of P. If P
1229 is NULL, then baseUri will NOT be null (see
1230 runtime/core/constructors.cpp).
1231
1232 The haveTypedValue and haveEmptyValue properties are actually a function of
1233 the node's type. However, since the store stores only the name of the type
1234 and does not know anything about the definition of that type, the caller
1235 of this method must provide the value for these two properties, which are
1236 needed to implement the getTypedValue() method.
1237 ********************************************************************************/
createElementNode(store::Item_t & result,store::Item * parent,store::Item_t & nodeName,store::Item_t & typeName,bool haveTypedValue,bool haveEmptyValue,const store::NsBindings & localBindings,zstring & baseUri,bool isInSubstitutionGroup)1238 bool BasicItemFactory::createElementNode(
1239 store::Item_t& result,
1240 store::Item* parent,
1241 store::Item_t& nodeName,
1242 store::Item_t& typeName,
1243 bool haveTypedValue,
1244 bool haveEmptyValue,
1245 const store::NsBindings& localBindings,
1246 zstring& baseUri,
1247 bool isInSubstitutionGroup)
1248 {
1249 XmlTree* xmlTree = NULL;
1250 ElementNode* n = NULL;
1251
1252 if ( typeName == NULL )
1253 throw ZORBA_EXCEPTION(
1254 zerr::ZAPI0014_INVALID_ARGUMENT,
1255 ERROR_PARAMS( "null", ZED( NotAllowedForTypeName ) )
1256 );
1257
1258 assert(parent == NULL ||
1259 parent->getNodeKind() == store::StoreConsts::elementNode ||
1260 parent->getNodeKind() == store::StoreConsts::documentNode);
1261
1262 InternalNode* pnode = reinterpret_cast<InternalNode*>(parent);
1263
1264 try
1265 {
1266 if (parent == NULL)
1267 xmlTree = GET_STORE().getNodeFactory().createXmlTree();
1268
1269 n = GET_STORE().getNodeFactory().createElementNode(
1270 xmlTree,
1271 pnode,
1272 true,
1273 0,
1274 nodeName,
1275 typeName,
1276 haveTypedValue,
1277 haveEmptyValue,
1278 isInSubstitutionGroup,
1279 &localBindings,
1280 baseUri);
1281 }
1282 catch (...)
1283 {
1284 delete xmlTree;
1285 throw;
1286 }
1287
1288 result = n;
1289 return n != NULL;
1290 }
1291
1292
1293 /*******************************************************************************
1294 Create a new attribute node N and place it as the pos-th attribute of a given
1295 parent node. If no parent is given, N becomes the root (and single node) of a
1296 new XML tree.
1297
1298 parent : The parent P of the new attribute node; may be NULL.
1299 pos : The position, among the attributes of P, that N will occupy.
1300 If pos == current number of P's attributes, then N is appended
1301 to the list of attributes.
1302 nodeName : The node-name property of N.
1303 typeName : The type-name property of N.
1304 typedValue : The typed-value property of N, for the case where the
1305 typed-value is a single atomic value.
1306 ********************************************************************************/
createAttributeNode(store::Item_t & result,store::Item * parent,ulong pos,store::Item_t & nodeName,store::Item_t & typeName,store::Item_t & typedValue)1307 bool BasicItemFactory::createAttributeNode(
1308 store::Item_t& result,
1309 store::Item* parent,
1310 ulong pos,
1311 store::Item_t& nodeName,
1312 store::Item_t& typeName,
1313 store::Item_t& typedValue)
1314 {
1315 XmlTree* xmlTree = NULL;
1316 AttributeNode* n = NULL;
1317
1318 assert(parent == NULL ||
1319 parent->getNodeKind() == store::StoreConsts::elementNode);
1320
1321 ElementNode* pnode = reinterpret_cast<ElementNode*>(parent);
1322
1323 try
1324 {
1325 if (parent == NULL)
1326 {
1327 xmlTree = GET_STORE().getNodeFactory().createXmlTree();
1328 }
1329 else
1330 {
1331 pnode->checkUniqueAttr(nodeName.getp());
1332 }
1333
1334 n = GET_STORE().getNodeFactory().createAttributeNode(
1335 xmlTree,
1336 pnode,
1337 false,
1338 pos,
1339 nodeName,
1340 typeName,
1341 typedValue,
1342 false, // isListValue
1343 false); // hidden
1344 }
1345 catch (...)
1346 {
1347 delete xmlTree;
1348 throw;
1349 }
1350
1351 result = n;
1352 return n != NULL;
1353 }
1354
1355
1356 /*******************************************************************************
1357 Create a new attribute node N and place it as the last attribute of a given
1358 parent node. If no parent is given, N becomes the root (and single node) of a
1359 new XML tree.
1360
1361 Note: This method should be used only while constructing a new xml tree. More
1362 specifically, it should not be used if the parent node had a child/attribute
1363 that was deleted some time before the invcation of this method (see comment
1364 in method XmlNode::XmlNode).
1365
1366 parent : The parent P of the new attribute node; may be NULL.
1367 nodeName : The node-name property of N.
1368 typeName : The type-name property of N.
1369 typedValue : The typed-value property of N, for the case where the
1370 typed-value is a single atomic value.
1371 ********************************************************************************/
createAttributeNode(store::Item_t & result,store::Item * parent,store::Item_t & nodeName,store::Item_t & typeName,store::Item_t & typedValue)1372 bool BasicItemFactory::createAttributeNode(
1373 store::Item_t& result,
1374 store::Item* parent,
1375 store::Item_t& nodeName,
1376 store::Item_t& typeName,
1377 store::Item_t& typedValue)
1378 {
1379 XmlTree* xmlTree = NULL;
1380 AttributeNode* n = NULL;
1381
1382 assert(parent == NULL ||
1383 parent->getNodeKind() == store::StoreConsts::elementNode);
1384
1385 ElementNode* pnode = reinterpret_cast<ElementNode*>(parent);
1386
1387 try
1388 {
1389 if (parent == NULL)
1390 {
1391 xmlTree = GET_STORE().getNodeFactory().createXmlTree();
1392 }
1393 else
1394 {
1395 pnode->checkUniqueAttr(nodeName.getp());
1396 }
1397
1398 n = GET_STORE().getNodeFactory().createAttributeNode(
1399 xmlTree,
1400 pnode,
1401 true,
1402 0,
1403 nodeName,
1404 typeName,
1405 typedValue,
1406 false, // isListValue
1407 false); // hidden
1408 }
1409 catch (...)
1410 {
1411 delete xmlTree;
1412 throw;
1413 }
1414
1415 result = n;
1416 return n != NULL;
1417 }
1418
1419
1420 /*******************************************************************************
1421 Create a new attribute node N and place it as the pos-th attribute of a given
1422 parent node. If no parent is given, N becomes the root (and single node) of a
1423 new XML tree.
1424
1425 parent : The parent P of the new attribute node; may be NULL.
1426 pos : The position, among the attributes of P, that N will occupy.
1427 If pos == current number of P's attributes, then N is appended
1428 to the list of attributes.
1429 nodeName : The node-name property of N.
1430 typeName : The type-name property of N.
1431 typedValueV : The typed-value property of N, for the case where the
1432 typed-value is a sequence of atomic values.
1433 ********************************************************************************/
createAttributeNode(store::Item_t & result,store::Item * parent,ulong pos,store::Item_t & nodeName,store::Item_t & typeName,std::vector<store::Item_t> & typedValueV)1434 bool BasicItemFactory::createAttributeNode(
1435 store::Item_t& result,
1436 store::Item* parent,
1437 ulong pos,
1438 store::Item_t& nodeName,
1439 store::Item_t& typeName,
1440 std::vector<store::Item_t>& typedValueV)
1441 {
1442 XmlTree* xmlTree = NULL;
1443 AttributeNode* node = NULL;
1444
1445 ElementNode* pnode = reinterpret_cast<ElementNode*>(parent);
1446
1447 try
1448 {
1449 if (parent == NULL)
1450 {
1451 xmlTree = GET_STORE().getNodeFactory().createXmlTree();
1452 }
1453 else
1454 {
1455 pnode->checkUniqueAttr(nodeName.getp());
1456 }
1457
1458 store::Item_t typedValue = new ItemVector(typedValueV);
1459
1460 node = GET_STORE().getNodeFactory().createAttributeNode(
1461 xmlTree,
1462 pnode,
1463 false,
1464 pos,
1465 nodeName,
1466 typeName,
1467 typedValue,
1468 true, // isListValue
1469 false); // hidden
1470 }
1471 catch (...)
1472 {
1473 delete xmlTree;
1474 throw;
1475 }
1476
1477 result = node;
1478 return node != NULL;
1479 }
1480
1481
1482 /*******************************************************************************
1483 Create a new attribute node N and place it as the last attribute of a given
1484 parent node. If no parent is given, N becomes the root (and single node) of a
1485 new XML tree.
1486
1487 Note: This method should be used only while constructing a new xml tree. More
1488 specifically, it should not be used if the parent node had a child/attribute
1489 that was deleted some time before the invcation of this method (see comment
1490 in method XmlNode::XmlNode).
1491
1492 parent : The parent P of the new attribute node; may be NULL.
1493 pos : The position, among the attributes of P, that N will occupy.
1494 If pos == current number of P's attributes, then N is appended
1495 to the list of attributes.
1496 nodeName : The node-name property of N.
1497 typeName : The type-name property of N.
1498 typedValueV : The typed-value property of N, for the case where the
1499 typed-value is a sequence of atomic values.
1500 ********************************************************************************/
createAttributeNode(store::Item_t & result,store::Item * parent,store::Item_t & nodeName,store::Item_t & typeName,std::vector<store::Item_t> & typedValueV)1501 bool BasicItemFactory::createAttributeNode(
1502 store::Item_t& result,
1503 store::Item* parent,
1504 store::Item_t& nodeName,
1505 store::Item_t& typeName,
1506 std::vector<store::Item_t>& typedValueV)
1507 {
1508 XmlTree* xmlTree = NULL;
1509 AttributeNode* node = NULL;
1510
1511 ElementNode* pnode = reinterpret_cast<ElementNode*>(parent);
1512
1513 try
1514 {
1515 if (parent == NULL)
1516 {
1517 xmlTree = GET_STORE().getNodeFactory().createXmlTree();
1518 }
1519 else
1520 {
1521 pnode->checkUniqueAttr(nodeName.getp());
1522 }
1523
1524 store::Item_t typedValue = new ItemVector(typedValueV);
1525
1526 node = GET_STORE().getNodeFactory().createAttributeNode(
1527 xmlTree,
1528 pnode,
1529 true,
1530 0,
1531 nodeName,
1532 typeName,
1533 typedValue,
1534 true, // isListValue
1535 false); // hidden
1536 }
1537 catch (...)
1538 {
1539 delete xmlTree;
1540 throw;
1541 }
1542
1543 result = node;
1544 return node != NULL;
1545 }
1546
1547
1548 /*******************************************************************************
1549 Create a new text node N and place it as the pos-th child of a given parent
1550 node. If no parent is given, N becomes the root (and single node) of a
1551 new XML tree. If N is going to be placed next to an existing text node T,
1552 then no new text node is actually created, but instead the givan content
1553 is concatanated with the content of T.
1554
1555 parent : The parent P of the new text node; may be NULL.
1556 pos : The position, among the children of P, that N will occupy.
1557 If pos == current number of P's children, then N is appended
1558 to the list of children.
1559 content : The content property of N.
1560 ********************************************************************************/
createTextNode(store::Item_t & result,store::Item * parent,ulong pos,zstring & content)1561 bool BasicItemFactory::createTextNode(
1562 store::Item_t& result,
1563 store::Item* parent,
1564 ulong pos,
1565 zstring& content)
1566 {
1567 NodeFactory& factory = GET_NODE_FACTORY();
1568 XmlTree* xmlTree = NULL;
1569 TextNode* n = NULL;
1570
1571 InternalNode* pnode = static_cast<InternalNode*>(parent);
1572
1573 try
1574 {
1575 if (parent == NULL)
1576 {
1577 xmlTree = factory.createXmlTree();
1578
1579 n = factory.createTextNode(xmlTree, pnode, false, pos, content);
1580 }
1581 else
1582 {
1583 csize numChildren = pnode->numChildren();
1584
1585 XmlNode* lsib = (pos > 0 ? pnode->getChild(pos-1) : NULL);
1586 XmlNode* rsib = (pos + 1 < numChildren ? pnode->getChild(pos) : NULL);
1587
1588 if (lsib != NULL && lsib->getNodeKind() == store::StoreConsts::textNode)
1589 {
1590 TextNode* textSibling = reinterpret_cast<TextNode*>(lsib);
1591
1592 ZORBA_ASSERT(!textSibling->isTyped());
1593
1594 zstring content2;
1595 content2.reserve(textSibling->getText().size() + content.size());
1596 content2 = textSibling->getText();
1597 content2 += content;
1598
1599 textSibling->setText(content2);
1600
1601 result = lsib;
1602 return result != NULL;
1603 }
1604 else if (rsib != NULL && rsib->getNodeKind() == store::StoreConsts::textNode)
1605 {
1606 TextNode* textSibling = reinterpret_cast<TextNode*>(rsib);
1607
1608 ZORBA_ASSERT(!textSibling->isTyped());
1609
1610 zstring content2;
1611 content2.take(content);
1612 content2 += textSibling->getText();
1613 textSibling->setText(content2);
1614
1615 result = rsib;
1616 return result != NULL;
1617 }
1618 else
1619 {
1620 n = factory.createTextNode(xmlTree, pnode, false, pos, content);
1621 }
1622 }
1623 }
1624 catch (...)
1625 {
1626 delete xmlTree;
1627 throw;
1628 }
1629
1630 result = n;
1631 return n != NULL;
1632 }
1633
1634
1635 /*******************************************************************************
1636 Create a new text node N and place it as the last child of a given parent
1637 node. If no parent is given, N becomes the root (and single node) of a
1638 new XML tree. If N is going to be placed next to an existing text node T,
1639 then no new text node is actually created, but instead the givan content
1640 is concatanated with the content of T.
1641
1642 Note: This method should be used only while constructing a new xml tree. More
1643 specifically, it should not be used if the parent node had a child/attribute
1644 that was deleted some time before the invcation of this method (see comment
1645 in method XmlNode::XmlNode).
1646
1647 parent : The parent P of the new text node; may be NULL.
1648 content : The content property of N.
1649 ********************************************************************************/
createTextNode(store::Item_t & result,store::Item * parent,zstring & content)1650 bool BasicItemFactory::createTextNode(
1651 store::Item_t& result,
1652 store::Item* parent,
1653 zstring& content)
1654 {
1655 NodeFactory& factory = GET_NODE_FACTORY();
1656 XmlTree* xmlTree = NULL;
1657 TextNode* n = NULL;
1658
1659 InternalNode* pnode = static_cast<InternalNode*>(parent);
1660
1661 try
1662 {
1663 if (parent == NULL)
1664 {
1665 xmlTree = factory.createXmlTree();
1666
1667 n = factory.createTextNode(xmlTree, pnode, false, 0, content);
1668 }
1669 else
1670 {
1671 csize pos = pnode->numChildren();
1672
1673 XmlNode* lsib = ( pos > 0 ? pnode->getChild(pos-1) : NULL);
1674
1675 if (lsib != NULL && lsib->getNodeKind() == store::StoreConsts::textNode)
1676 {
1677 TextNode* textSibling = reinterpret_cast<TextNode*>(lsib);
1678
1679 ZORBA_ASSERT(!textSibling->isTyped());
1680
1681 zstring content2;
1682 content2.reserve(textSibling->getText().size() + content.size());
1683 content2 = textSibling->getText();
1684 content2 += content;
1685
1686 textSibling->setText(content2);
1687
1688 result = lsib;
1689 return result != NULL;
1690 }
1691 else
1692 {
1693 n = factory.createTextNode(xmlTree, pnode, true, 0, content);
1694 }
1695 }
1696 }
1697 catch (...)
1698 {
1699 delete xmlTree;
1700 throw;
1701 }
1702
1703 result = n;
1704 return n != NULL;
1705 }
1706
1707
1708 /*******************************************************************************
1709 Create a new text node N to store the typed value of a given element node P
1710 (the parent of N) that has simple type or complex type with simple content.
1711
1712 The typed value of P consists of a single atomic value.
1713
1714 P is not allowed to have any other text or element children.
1715
1716 parent : The parent P of the new text node; must not be NULL.
1717 content : The typed value of P.
1718 ********************************************************************************/
createTextNode(store::Item_t & result,store::Item * parent,store::Item_t & content)1719 bool BasicItemFactory::createTextNode(
1720 store::Item_t& result,
1721 store::Item* parent,
1722 store::Item_t& content)
1723 {
1724 assert(parent != NULL);
1725 ElementNode* pnode = reinterpret_cast<ElementNode*>(parent);
1726
1727 // Note: the TextNode constructor asserts that the parent has 0 children
1728 result = GET_NODE_FACTORY().createTextNode(pnode, content, false);
1729 return true;
1730 }
1731
1732
1733 /*******************************************************************************
1734 Create a new text node N to store the typed value of a given element node P
1735 (the parent of N) that has simple type or complex type with simple content.
1736
1737 The typed value of P is a list of atomic values.
1738
1739 P is not allowed to have any other text or element children.
1740
1741 parent : The parent P of the new text node; must not be NULL.
1742 content : The typed value of P.
1743 ********************************************************************************/
createTextNode(store::Item_t & result,store::Item * parent,std::vector<store::Item_t> & content)1744 bool BasicItemFactory::createTextNode(
1745 store::Item_t& result,
1746 store::Item* parent,
1747 std::vector<store::Item_t>& content)
1748 {
1749 assert(parent != NULL);
1750 ElementNode* pnode = reinterpret_cast<ElementNode*>(parent);
1751
1752 store::Item_t typedValue = new ItemVector(content);
1753 result = GET_NODE_FACTORY().createTextNode(pnode, typedValue, true);
1754 return true;
1755 }
1756
1757
1758 /*******************************************************************************
1759 Create a new pi node N and place it as the pos-th child of a given parent
1760 node. If no parent is given, N becomes the root (and single node) of a
1761 new XML tree.
1762
1763 parent : The parent P of the new pi node; may be NULL.
1764 pos : The position, among the children of P, that N will occupy.
1765 If pos == current number of P's children, then N is appended
1766 to the list of children.
1767 target : The target property of N.
1768 content : The content property of N.
1769 baseUri : The base-uri property of N.
1770 ********************************************************************************/
createPiNode(store::Item_t & result,store::Item * parent,ulong pos,zstring & target,zstring & content,zstring & baseUri)1771 bool BasicItemFactory::createPiNode(
1772 store::Item_t& result,
1773 store::Item* parent,
1774 ulong pos,
1775 zstring& target,
1776 zstring& content,
1777 zstring& baseUri)
1778 {
1779 XmlTree* xmlTree = NULL;
1780 PiNode* n = NULL;
1781
1782 assert(parent == NULL ||
1783 parent->getNodeKind() == store::StoreConsts::elementNode ||
1784 parent->getNodeKind() == store::StoreConsts::documentNode);
1785
1786 InternalNode* pnode = reinterpret_cast<InternalNode*>(parent);
1787
1788 try
1789 {
1790 if (parent == NULL)
1791 xmlTree = GET_NODE_FACTORY().createXmlTree();
1792
1793 n = GET_NODE_FACTORY().createPiNode(xmlTree, pnode, false, pos, target, content);
1794 }
1795 catch (...)
1796 {
1797 delete xmlTree;
1798 throw;
1799 }
1800
1801 result = n;
1802 return n != NULL;
1803 }
1804
1805
1806 /*******************************************************************************
1807 Create a new pi node N and place it as the last child of a given parent
1808 node. If no parent is given, N becomes the root (and single node) of a
1809 new XML tree.
1810
1811 Note: This method should be used only while constructing a new xml tree. More
1812 specifically, it should not be used if the parent node had a child/attribute
1813 that was deleted some time before the invcation of this method (see comment
1814 in method XmlNode::XmlNode).
1815
1816 parent : The parent P of the new pi node; may be NULL.
1817 pos : The position, among the children of P, that N will occupy.
1818 If pos == current number of P's children, then N is appended
1819 to the list of children.
1820 target : The target property of N.
1821 content : The content property of N.
1822 baseUri : The base-uri property of N.
1823 ********************************************************************************/
createPiNode(store::Item_t & result,store::Item * parent,zstring & target,zstring & content,zstring & baseUri)1824 bool BasicItemFactory::createPiNode(
1825 store::Item_t& result,
1826 store::Item* parent,
1827 zstring& target,
1828 zstring& content,
1829 zstring& baseUri)
1830 {
1831 XmlTree* xmlTree = NULL;
1832 PiNode* n = NULL;
1833
1834 assert(parent == NULL ||
1835 parent->getNodeKind() == store::StoreConsts::elementNode ||
1836 parent->getNodeKind() == store::StoreConsts::documentNode);
1837
1838 InternalNode* pnode = reinterpret_cast<InternalNode*>(parent);
1839
1840 try
1841 {
1842 if (parent == NULL)
1843 xmlTree = GET_NODE_FACTORY().createXmlTree();
1844
1845 n = GET_NODE_FACTORY().createPiNode(xmlTree, pnode, true, 0, target, content);
1846 }
1847 catch (...)
1848 {
1849 delete xmlTree;
1850 throw;
1851 }
1852
1853 result = n;
1854 return n != NULL;
1855 }
1856
1857
1858 /*******************************************************************************
1859 Create a new comment node N and place it as the pos-th child of a given parent
1860 node. If no parent is given, N becomes the root (and single node) of a
1861 new XML tree.
1862
1863 parent : The parent P of the new comment node; may be NULL.
1864 pos : The position, among the children of P, that N will occupy.
1865 If pos == current number of P's children, then N is appended
1866 to the list of children.
1867 content : The content property of N.
1868 ********************************************************************************/
createCommentNode(store::Item_t & result,store::Item * parent,ulong pos,zstring & content)1869 bool BasicItemFactory::createCommentNode(
1870 store::Item_t& result,
1871 store::Item* parent,
1872 ulong pos,
1873 zstring& content)
1874 {
1875 XmlTree* xmlTree = NULL;
1876 CommentNode* n = NULL;
1877
1878 assert(parent == NULL ||
1879 parent->getNodeKind() == store::StoreConsts::elementNode ||
1880 parent->getNodeKind() == store::StoreConsts::documentNode);
1881
1882 InternalNode* pnode = reinterpret_cast<InternalNode*>(parent);
1883
1884 try
1885 {
1886 if (parent == NULL)
1887 xmlTree = GET_NODE_FACTORY().createXmlTree();
1888
1889 n = GET_NODE_FACTORY().createCommentNode(xmlTree, pnode, false, pos, content);
1890 }
1891 catch (...)
1892 {
1893 delete xmlTree;
1894 throw;
1895 }
1896
1897 result = n;
1898 return n != NULL;
1899 }
1900
1901
1902 /*******************************************************************************
1903 Create a new comment node N and place it as the last child of a given parent
1904 node. If no parent is given, N becomes the root (and single node) of a
1905 new XML tree.
1906
1907 Note: This method should be used only while constructing a new xml tree. More
1908 specifically, it should not be used if the parent node had a child/attribute
1909 that was deleted some time before the invcation of this method (see comment
1910 in method XmlNode::XmlNode).
1911
1912 parent : The parent P of the new comment node; may be NULL.
1913 pos : The position, among the children of P, that N will occupy.
1914 If pos == current number of P's children, then N is appended
1915 to the list of children.
1916 content : The content property of N.
1917 ********************************************************************************/
createCommentNode(store::Item_t & result,store::Item * parent,zstring & content)1918 bool BasicItemFactory::createCommentNode(
1919 store::Item_t& result,
1920 store::Item* parent,
1921 zstring& content)
1922 {
1923 XmlTree* xmlTree = NULL;
1924 CommentNode* n = NULL;
1925
1926 assert(parent == NULL ||
1927 parent->getNodeKind() == store::StoreConsts::elementNode ||
1928 parent->getNodeKind() == store::StoreConsts::documentNode);
1929
1930 InternalNode* pnode = reinterpret_cast<InternalNode*>(parent);
1931
1932 try
1933 {
1934 if (parent == NULL)
1935 xmlTree = GET_NODE_FACTORY().createXmlTree();
1936
1937 n = GET_NODE_FACTORY().createCommentNode(xmlTree, pnode, true, 0, content);
1938 }
1939 catch (...)
1940 {
1941 delete xmlTree;
1942 throw;
1943 }
1944
1945 result = n;
1946 return n != NULL;
1947 }
1948
1949
1950 /*******************************************************************************
1951
1952 ********************************************************************************/
createPendingUpdateList()1953 store::PUL* BasicItemFactory::createPendingUpdateList()
1954 {
1955 return new PULImpl();
1956 }
1957
1958 #if 0
1959 /*******************************************************************************
1960
1961 ********************************************************************************/
1962 bool BasicItemFactory::createTuple(
1963 store::Item_t& result,
1964 std::vector<store::TupleField>& fields)
1965 {
1966 result = new TupleItem(fields);
1967 return true;
1968 }
1969
1970
1971 /*******************************************************************************
1972
1973 ********************************************************************************/
1974 bool BasicItemFactory::createTuple(
1975 store::Item_t& result,
1976 store::Item *inTuple,
1977 std::vector<int>& permutation)
1978 {
1979 ZORBA_ASSERT(inTuple->isTuple());
1980 std::vector<zorba::store::TupleField> newFields;
1981 int n = permutation.size();
1982 for(int i = 0; i <= n; ++i) {
1983 newFields.push_back(inTuple->getTupleField(permutation[i]));
1984 }
1985 result = new TupleItem(newFields);
1986 return true;
1987 }
1988 #endif
1989
1990 /*******************************************************************************
1991
1992 ********************************************************************************/
createError(store::Item_t & result,ZorbaException * inError)1993 bool BasicItemFactory::createError(
1994 store::Item_t& result,
1995 ZorbaException* inError)
1996 {
1997 result = new ErrorItem(inError);
1998 return true;
1999 }
2000
2001
splitToAtomicTextValues(zstring & textValue,std::vector<zstring> & atomicTextValues)2002 void BasicItemFactory::splitToAtomicTextValues(
2003 zstring& textValue,
2004 std::vector<zstring>& atomicTextValues)
2005 {
2006 ascii::normalize_whitespace(textValue);
2007
2008 zstring::size_type start = 0;
2009 zstring::size_type i = 0;
2010
2011 while (i < textValue.size())
2012 {
2013 if (isspace(textValue[i]))
2014 {
2015 atomicTextValues.push_back(textValue.substr(start, i - start));
2016 start = i+1;
2017 }
2018 i++;
2019 }
2020
2021 if ( start < (i-1) )
2022 atomicTextValues.push_back(textValue.substr(start, i-start));
2023 }
2024
2025
2026 #ifdef ZORBA_WITH_JSON
2027 /*******************************************************************************
2028
2029 ********************************************************************************/
createJSONNull(store::Item_t & result)2030 bool BasicItemFactory::createJSONNull(store::Item_t& result)
2031 {
2032 result = theNullItem;
2033 return true;
2034 }
2035
2036
2037 /*******************************************************************************
2038
2039 ********************************************************************************/
createJSONNumber(store::Item_t & result,store::Item_t & string)2040 bool BasicItemFactory::createJSONNumber(
2041 store::Item_t& result,
2042 store::Item_t& string)
2043 {
2044 zstring s = string->getStringValue();
2045 return createJSONNumber(result, s);
2046 }
2047
2048
2049 /*******************************************************************************
2050
2051 ********************************************************************************/
createJSONNumber(store::Item_t & result,zstring & string)2052 bool BasicItemFactory::createJSONNumber(
2053 store::Item_t& result,
2054 zstring& string)
2055 {
2056 try
2057 {
2058 bool dot = (strchr(string.c_str(), 46) != NULL);
2059 bool e = (strpbrk(string.c_str(), "eE") != NULL);
2060 if (!e)
2061 {
2062 if (!dot)
2063 {
2064 // xs:integer
2065 xs_integer i = Integer(string.c_str());
2066 return createInteger(result, i);
2067 }
2068 else
2069 {
2070 // xs:decimal
2071 xs_decimal d = Decimal(string.c_str());
2072 return createDecimal(result, d);
2073 }
2074 }
2075 else
2076 {
2077 // xs:double
2078 xs_double d = FloatImpl<double>(string.c_str());
2079 return createDouble(result, d);
2080 }
2081 }
2082 catch (std::exception& e)
2083 {
2084 return false;
2085 }
2086 }
2087
2088
2089 /*******************************************************************************
2090
2091 ********************************************************************************/
createJSONArray(store::Item_t & result,const std::vector<store::Iterator_t> & sources,const std::vector<store::CopyMode> & copyModes)2092 bool BasicItemFactory::createJSONArray(
2093 store::Item_t& result,
2094 const std::vector<store::Iterator_t>& sources,
2095 const std::vector<store::CopyMode>& copyModes)
2096 {
2097 result = new json::SimpleJSONArray();
2098
2099 json::JSONArray* array = static_cast<json::JSONArray*>(result.getp());
2100
2101 store::Item_t item;
2102
2103 csize numSources = sources.size();
2104 for (csize i = 0; i < numSources; ++i)
2105 {
2106 store::Iterator* source = sources[i].getp();
2107 const store::CopyMode& copymode = copyModes[i];
2108
2109 while (source->next(item))
2110 {
2111 if (copymode.theDoCopy && (item->isNode() || item->isJSONItem()))
2112 item = item->copy(NULL, copymode);
2113
2114 array->push_back(item);
2115 }
2116 }
2117
2118 return true;
2119 }
2120
2121
createJSONArray(store::Item_t & result,store::Item_t & item1,store::Item_t & item2,const store::Iterator_t & source,const store::CopyMode & copymode)2122 bool BasicItemFactory::createJSONArray(
2123 store::Item_t& result,
2124 store::Item_t& item1,
2125 store::Item_t& item2,
2126 const store::Iterator_t& source,
2127 const store::CopyMode& copymode)
2128 {
2129 result = new json::SimpleJSONArray();
2130
2131 json::SimpleJSONArray* array = static_cast<json::SimpleJSONArray*>(result.getp());
2132
2133 array->push_back(item1);
2134 array->push_back(item2);
2135
2136 store::Item_t item;
2137
2138 while (source->next(item))
2139 {
2140 if (copymode.theDoCopy && (item->isNode() || item->isJSONItem()))
2141 item = item->copy(NULL, copymode);
2142
2143 array->push_back(item);
2144 }
2145
2146 return true;
2147 }
2148
2149
createJSONArray(store::Item_t & result,const std::vector<store::Item_t> & items)2150 bool BasicItemFactory::createJSONArray(
2151 store::Item_t& result,
2152 const std::vector<store::Item_t>& items)
2153 {
2154 result = new json::SimpleJSONArray();
2155
2156 json::JSONArray* array = static_cast<json::JSONArray*>(result.getp());
2157
2158 std::vector<store::Item_t>::const_iterator ite = items.begin();
2159 std::vector<store::Item_t>::const_iterator end = items.end();
2160 for (; ite != end; ++ite)
2161 {
2162 array->push_back(*ite);
2163 }
2164 return true;
2165 }
2166
2167
2168 /*******************************************************************************
2169
2170 ********************************************************************************/
createJSONObject(store::Item_t & result,const std::vector<store::Iterator_t> & sources,const std::vector<store::CopyMode> & copyModes,bool accumulate)2171 bool BasicItemFactory::createJSONObject(
2172 store::Item_t& result,
2173 const std::vector<store::Iterator_t>& sources,
2174 const std::vector<store::CopyMode>& copyModes,
2175 bool accumulate)
2176 {
2177 result = new json::SimpleJSONObject();
2178
2179 json::JSONObject* obj = static_cast<json::JSONObject*>(result.getp());
2180
2181 store::Item_t objItem;
2182 store::Item_t keyItem;
2183 store::Item_t valueItem;
2184
2185 csize numSources = sources.size();
2186 for (csize i = 0; i < numSources; ++i)
2187 {
2188 store::Iterator* source = sources[i].getp();
2189 const store::CopyMode& copymode = copyModes[i];
2190
2191 while (source->next(objItem))
2192 {
2193 assert(objItem->isJSONObject());
2194
2195 json::SimpleJSONObject* sourceObj =
2196 static_cast<json::SimpleJSONObject*>(objItem.getp());
2197
2198 store::Iterator_t sourceKeys = sourceObj->getObjectKeys();
2199
2200 sourceKeys->open();
2201
2202 while (sourceKeys->next(keyItem))
2203 {
2204 valueItem = objItem->getObjectValue(keyItem);
2205 if (copymode.theDoCopy &&
2206 (valueItem->isJSONArray() ||
2207 valueItem->isJSONObject() ||
2208 valueItem->isNode()))
2209 {
2210 valueItem = valueItem->copy(NULL, copymode);
2211 }
2212
2213 if (!obj->add(keyItem, valueItem, accumulate))
2214 {
2215 RAISE_ERROR_NO_LOC(jerr::JNDY0003,
2216 ERROR_PARAMS(keyItem->getStringValue()));
2217 }
2218 }
2219
2220 sourceKeys->close();
2221 }
2222 }
2223
2224 return true;
2225 }
2226
2227
createJSONObject(store::Item_t & result,const std::vector<store::Item_t> & names,const std::vector<store::Item_t> & values)2228 bool BasicItemFactory::createJSONObject(
2229 store::Item_t& result,
2230 const std::vector<store::Item_t>& names,
2231 const std::vector<store::Item_t>& values)
2232 {
2233 result = new json::SimpleJSONObject();
2234
2235 json::JSONObject* obj = static_cast<json::JSONObject*>(result.getp());
2236
2237 assert(names.size() == values.size());
2238
2239 csize numPairs = names.size();
2240 for (csize i = 0; i < numPairs; ++i)
2241 {
2242 if (!obj->add(names[i], values[i], false))
2243 {
2244 RAISE_ERROR_NO_LOC(jerr::JNDY0003, ERROR_PARAMS(names[i]->getStringValue()));
2245 }
2246 }
2247
2248 return true;
2249 }
2250
2251
2252 #endif
2253
2254 } // namespace simplestore
2255 } // namespace zorba
2256 /* vim:set et sw=2 ts=2: */
2257