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