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 <zorba/error.h>
19 #include <zorba/diagnostic_list.h>
20 
21 #include "store/api/item.h"
22 
23 #include "diagnostics/xquery_diagnostics.h"
24 #include "diagnostics/assert.h"
25 
26 #include "zorbautils/hashmap.h"
27 
28 #include "zorbatypes/collation_manager.h"
29 
30 #include "zorbaserialization/archiver.h"
31 #include "zorbaserialization/archiver_field.h"
32 #include "zorbaserialization/class_serializer.h"
33 #include "zorbaserialization/mem_archiver.h"
34 
35 
36 namespace zorba
37 {
38 
39 namespace serialization
40 {
41 
42 
43 /*******************************************************************************
44   Constructor for simple non-pointer fields
45 ********************************************************************************/
archive_field(TypeCode type,const void * ptr,ArchiveFieldKind kind,int only_for_eval,ENUM_ALLOW_DELAY allow_delay,unsigned int level)46 archive_field::archive_field(
47     TypeCode type,
48     const void* ptr,
49     ArchiveFieldKind kind,
50     int only_for_eval,
51     ENUM_ALLOW_DELAY allow_delay,
52     unsigned int level)
53   :
54   theId(0),
55   theIsSimple(true),
56   theIsClass(false),
57   theKind(kind),
58   theType(type),
59   theValuePosInPool(0),
60   theObjPtr(ptr),
61   theReferredField(NULL),
62   theLevel(level),
63   theNextSibling(NULL),
64   theFirstChild(NULL),
65   theLastChild(NULL),
66   theParent(NULL),
67   theOnlyForEval(only_for_eval),
68   theAllowDelay2(allow_delay)
69 {
70   assert(theKind == ARCHIVE_FIELD_NORMAL);
71 
72   theValue.uint64v = 0;
73 
74   switch (type)
75   {
76   case TYPE_INT64:
77   {
78     theValue.int64v = *static_cast<const int64_t*>(ptr);
79     break;
80   }
81   case TYPE_UINT64:
82   {
83     theValue.uint64v = *static_cast<const uint64_t*>(ptr);
84     break;
85   }
86   case TYPE_INT32:
87   {
88     theValue.int32v = *static_cast<const int32_t*>(ptr);
89     break;
90   }
91   case TYPE_UINT32:
92   {
93     theValue.uint32v = *static_cast<const uint32_t*>(ptr);
94     break;
95   }
96   case TYPE_ENUM:
97   {
98     theValue.uint32v = *static_cast<const uint32_t*>(ptr);
99     break;
100   }
101   case TYPE_INT16:
102   {
103     theValue.int16v = *static_cast<const int16_t*>(ptr);
104     break;
105   }
106   case TYPE_UINT16:
107   {
108     theValue.uint16v = *static_cast<const uint16_t*>(ptr);
109     break;
110   }
111   case TYPE_CHAR:
112   {
113     theValue.charv = *static_cast<const char*>(ptr);
114     break;
115   }
116   case TYPE_UCHAR:
117   {
118     theValue.ucharv = *static_cast<const unsigned char*>(ptr);
119     break;
120   }
121   case TYPE_BOOL:
122   {
123     theValue.boolv = *static_cast<const bool*>(ptr);
124     break;
125   }
126   case TYPE_ZSTRING:
127   {
128     theStringValue = *static_cast<const zstring*>(ptr);
129     break;
130   }
131   case TYPE_STD_STRING:
132   {
133     theStringValue = *static_cast<const std::string*>(ptr);
134     break;
135   }
136   case TYPE_COLLATOR:
137   {
138     theStringValue = (static_cast<const XQPCollator*>(ptr))->getURI();
139     break;
140   }
141   default:
142   {
143     ZORBA_ASSERT(false);
144   }
145   }
146 
147 #ifdef ZORBA_PLAN_SERIALIZER_STATISTICS
148   theBytesSaved = 0;
149   theObjectsSaved = 0;
150 #endif
151 }
152 
153 
154 /*******************************************************************************
155   Constructor for simple or compound fields
156 ********************************************************************************/
archive_field(TypeCode type,bool is_simple,bool is_class,const void * ptr,ArchiveFieldKind kind,archive_field * refered,int only_for_eval,ENUM_ALLOW_DELAY allow_delay,unsigned int level)157 archive_field::archive_field(
158     TypeCode type,
159     bool is_simple,
160     bool is_class,
161     const void* ptr,
162     ArchiveFieldKind kind,
163     archive_field* refered,
164     int only_for_eval,
165     ENUM_ALLOW_DELAY allow_delay,
166     unsigned int level)
167   :
168   theId(0),
169   theIsSimple(is_simple),
170   theIsClass(is_class),
171   theKind(kind),
172   theType(type),
173   theValuePosInPool(0),
174   theObjPtr(ptr),
175   theReferredField(refered),
176   theLevel(level),
177   theNextSibling(NULL),
178   theFirstChild(NULL),
179   theLastChild(NULL),
180   theParent(NULL),
181   theOnlyForEval(only_for_eval),
182   theAllowDelay2(allow_delay)
183 {
184   assert(type != TYPE_ENUM);
185   assert(type != TYPE_UNKNOWN);
186 
187   theValue.uint64v = 0;
188 
189 #ifdef ZORBA_PLAN_SERIALIZER_STATISTICS
190   theBytesSaved = 0;
191   theObjectsSaved = 0;
192 #endif
193 }
194 
195 
196 /*******************************************************************************
197 
198 ********************************************************************************/
~archive_field()199 archive_field::~archive_field()
200 {
201   archive_field* temp1 = theFirstChild;
202   archive_field* temp2;
203 
204   while(temp1)
205   {
206     temp2 = temp1->theNextSibling;
207     delete temp1;
208     temp1 = temp2;
209   }
210 }
211 
212 
213 /*******************************************************************************
214 
215 ********************************************************************************/
Archiver(bool is_serializing_out,bool internal_archive)216 Archiver::Archiver(bool is_serializing_out, bool internal_archive)
217   :
218   theArchiveVersion(ClassSerializer::g_zorba_classes_version),
219   theSerializingOut(is_serializing_out),
220   theSerializeBaseClass(false),
221   theIsTempField(0),
222   theCompilerCB(NULL),
223   theFieldCounter(0),
224   theRootField(0),
225   theCurrentCompoundField(0),
226   theCurrentLevel(0),
227   theNonClassFieldsMap(0),
228   theClassFieldsMap(0),
229   theOnlyForEval(0),
230   all_reference_list(0),
231   internal_archive(internal_archive),
232   theSerializeEverything(false),
233   loading_hardcoded_objects(false),
234   theAllowDelay2(ALLOW_DELAY),
235   theUserCallback(0),
236   dont_allow_delay_for_plan_sctx(false)
237 {
238   if (theSerializingOut)
239   {
240     //create the top most field
241     theRootField = new archive_field(TYPE_LAST,
242                                      false, // is_simple
243                                      false, // is_class
244                                      NULL,  // ptr
245                                      ARCHIVE_FIELD_NORMAL,
246                                      NULL,  // referred
247                                      false, // only for eval
248                                      ALLOW_DELAY,
249                                      0);    // level
250 
251     theCurrentCompoundField = theRootField;
252 
253     theNonClassFieldsMap =
254     new HashMap<const void*, archive_field*, FieldCompare>(1000, false);
255 
256     theClassFieldsMap =
257     new HashMap<const void*, archive_field*, FieldCompare>(1000, false);
258   }
259 
260   if (!internal_archive)
261   {
262     Archiver* har = ClassSerializer::getInstance()->harcoded_objects_archive;
263     theFieldCounter = har->theFieldCounter;
264   }
265 }
266 
267 
268 /*******************************************************************************
269 
270 ********************************************************************************/
~Archiver()271 Archiver::~Archiver()
272 {
273   delete theRootField;
274   delete [] all_reference_list;
275   delete theNonClassFieldsMap;
276   delete theClassFieldsMap;
277 
278   std::vector<archive_field*>::const_iterator orphan_it;
279   for (orphan_it = orphan_fields.begin(); orphan_it != orphan_fields.end(); ++orphan_it)
280   {
281     delete (*orphan_it);
282   }
283 }
284 
285 
286 /*******************************************************************************
287 
288 ********************************************************************************/
get_is_temp_field_one_level()289 bool Archiver::get_is_temp_field_one_level()
290 {
291   if (limit_temp_level_stack.empty())
292   {
293     return false;
294   }
295   else if (limit_temp_level_stack.top() == theCurrentLevel)
296   {
297     return true;
298   }
299   else
300   {
301     unsigned int lastlevel = limit_temp_level_stack.top();
302     archive_field* temp_field = theCurrentCompoundField;
303 
304     assert(!temp_field || temp_field->theLevel <= theCurrentLevel);
305     assert(!temp_field || temp_field->theLevel >= lastlevel);
306 
307     while (temp_field && (temp_field->theLevel >= lastlevel))
308     {
309       if (temp_field->theKind == ARCHIVE_FIELD_PTR ||
310           temp_field->theKind == ARCHIVE_FIELD_REFERENCING)
311         return false;
312 
313       temp_field = temp_field->theParent;
314     }
315 
316     if (temp_field)
317       return true;
318     else
319       return false;
320   }
321 }
322 
323 
324 ////////////////////////////////////////////////////////////////////////////////
325 //                                                                            //
326 //  Serialization only                                                        //
327 //                                                                            //
328 ////////////////////////////////////////////////////////////////////////////////
329 
330 
331 /*******************************************************************************
332 
333 ********************************************************************************/
add_simple_temp_field(TypeCode type,const void * ptr)334 void Archiver::add_simple_temp_field(TypeCode type, const void* ptr)
335 {
336   archive_field* new_field;
337 
338   ++theCurrentLevel;
339 
340   assert(ptr);
341 
342   new_field = new archive_field(type,
343                                 ptr,
344                                 ARCHIVE_FIELD_NORMAL,
345                                 get_serialize_only_for_eval(),
346                                 theAllowDelay2,
347                                 theCurrentLevel);
348 
349   theAllowDelay2 = ALLOW_DELAY;
350 
351   new_field->theOrder = theFieldCounter + 1;
352 
353   new_field->theParent = theCurrentCompoundField;
354 
355   if (theCurrentCompoundField->theLastChild)
356     theCurrentCompoundField->theLastChild->theNextSibling = new_field;
357   else
358     theCurrentCompoundField->theFirstChild = new_field;
359 
360   theCurrentCompoundField->theLastChild = new_field;
361 
362   --theCurrentLevel;
363 }
364 
365 
366 
367 /*******************************************************************************
368   Create a "simple" field (ARCHIVE_FIELD_PTR, or ARCHIVE_FIELD_NUL, or
369   ARCHIVE_FIELD_NORMAL).
370 
371   Return true if field is not referencing
372 ********************************************************************************/
add_simple_ptr_field(TypeCode type,const void * ptr)373 bool Archiver::add_simple_ptr_field(TypeCode type, const void* ptr)
374 {
375   archive_field* new_field;
376   archive_field* ref_field = NULL;
377 
378   ++theCurrentLevel;
379 
380   if (ptr && !get_is_temp_field())
381   {
382     ref_field = lookup_non_class_field(ptr);
383   }
384 
385   if (ref_field)
386   {
387     ZORBA_ASSERT(ref_field->theKind == ARCHIVE_FIELD_PTR ||
388                  ref_field->theKind == ARCHIVE_FIELD_NORMAL);
389 
390     if (get_is_temp_field_one_level() && theAllowDelay2 == ALLOW_DELAY)
391     {
392       theAllowDelay2 = DONT_ALLOW_DELAY;
393     }
394 
395     new_field = new archive_field(type,
396                                   true,       // is_simple
397                                   false,      // is_class
398                                   NULL,       // ptr
399                                   ARCHIVE_FIELD_REFERENCING,
400                                   ref_field,
401                                   get_serialize_only_for_eval(),
402                                   theAllowDelay2,
403                                   theCurrentLevel);
404   }
405   else if (ptr)
406   {
407     new_field = new archive_field(type,
408                                   ptr,
409                                   ARCHIVE_FIELD_PTR,
410                                   get_serialize_only_for_eval(),
411                                   theAllowDelay2,
412                                   theCurrentLevel);
413   }
414   else
415   {
416     new_field = new archive_field(type,
417                                   true,       // is_simple
418                                   false,      // is_class
419                                   NULL,       // ptr
420                                   ARCHIVE_FIELD_NULL,
421                                   NULL,
422                                   get_serialize_only_for_eval(),
423                                   theAllowDelay2,
424                                   theCurrentLevel);
425   }
426 
427   theAllowDelay2 = ALLOW_DELAY;
428 
429   if (!ref_field && ptr && !get_is_temp_field())
430   {
431     theNonClassFieldsMap->insert(ptr, new_field);
432   }
433 
434   if (ptr == NULL || ref_field != NULL)
435   {
436     new_field->theId = 0;
437     new_field->theOrder = theFieldCounter + 1;
438   }
439   else
440   {
441     new_field->theId = ++theFieldCounter;
442     new_field->theOrder = new_field->theId;
443   }
444 
445   new_field->theParent = theCurrentCompoundField;
446 
447   if (theCurrentCompoundField->theLastChild)
448     theCurrentCompoundField->theLastChild->theNextSibling = new_field;
449   else
450     theCurrentCompoundField->theFirstChild = new_field;
451 
452   theCurrentCompoundField->theLastChild = new_field;
453 
454   --theCurrentLevel;
455 
456   return ref_field != NULL;
457 }
458 
459 
460 /*******************************************************************************
461 
462 ********************************************************************************/
add_compound_field(TypeCode type,bool is_class,const void * ptr,ArchiveFieldKind field_kind)463 bool Archiver::add_compound_field(
464     TypeCode type,
465     bool is_class,
466     const void* ptr,
467     ArchiveFieldKind field_kind)
468 {
469   archive_field* new_field;
470   archive_field* ref_field = NULL;
471 
472   ++theCurrentLevel;
473 
474   if (!ptr)
475   {
476     field_kind = ARCHIVE_FIELD_NULL;
477     --theCurrentLevel;
478   }
479   else if (field_kind != ARCHIVE_FIELD_BASECLASS &&
480            !get_is_temp_field() &&
481            (!get_is_temp_field_one_level() || field_kind == ARCHIVE_FIELD_PTR))
482   {
483     if (is_class)
484       ref_field = lookup_class_field(ptr);
485     else
486       ref_field = lookup_non_class_field(ptr);
487   }
488 
489   if (ref_field)
490   {
491     ZORBA_ASSERT(field_kind != ARCHIVE_FIELD_NORMAL);
492     ZORBA_ASSERT(ref_field->theKind == ARCHIVE_FIELD_PTR ||
493                  ref_field->theKind == ARCHIVE_FIELD_NORMAL);
494 
495     if (get_is_temp_field_one_level() &&
496         field_kind == ARCHIVE_FIELD_PTR &&
497         theAllowDelay2 == ALLOW_DELAY)
498     {
499       theAllowDelay2 = DONT_ALLOW_DELAY;
500     }
501 
502     field_kind = ARCHIVE_FIELD_REFERENCING;
503     ptr = NULL;
504   }
505 
506   new_field = new archive_field(type,
507                                 false,     // is_simple
508                                 is_class,
509                                 ptr,
510                                 field_kind,
511                                 ref_field,
512                                 get_serialize_only_for_eval(),
513                                 theAllowDelay2,
514                                 theCurrentLevel);
515 
516   theAllowDelay2 = ALLOW_DELAY;
517 
518   if (!ref_field &&
519       field_kind != ARCHIVE_FIELD_BASECLASS &&
520       ptr &&
521       !get_is_temp_field() &&
522       (!get_is_temp_field_one_level() || field_kind == ARCHIVE_FIELD_PTR))
523   {
524     if (is_class)
525       theClassFieldsMap->insert(ptr, new_field);
526     else
527       theNonClassFieldsMap->insert(ptr, new_field);
528   }
529 
530   new_field->theParent = theCurrentCompoundField;
531 
532   if (field_kind == ARCHIVE_FIELD_REFERENCING ||
533       field_kind == ARCHIVE_FIELD_NULL ||
534       field_kind == ARCHIVE_FIELD_BASECLASS)
535   {
536     new_field->theId = 0;
537     new_field->theOrder = theFieldCounter + 1;
538   }
539   else
540   {
541     new_field->theId = ++theFieldCounter;
542     new_field->theOrder = new_field->theId;
543   }
544 
545   if (theCurrentCompoundField->theLastChild)
546     theCurrentCompoundField->theLastChild->theNextSibling = new_field;
547   else
548     theCurrentCompoundField->theFirstChild = new_field;
549 
550   theCurrentCompoundField->theLastChild = new_field;
551 
552   if (!ref_field && ptr)
553     theCurrentCompoundField = new_field;
554 
555   if (ref_field)
556     --theCurrentLevel;
557 
558   return ref_field != NULL;
559 }
560 
561 
562 /*******************************************************************************
563 
564 ********************************************************************************/
add_end_compound_field()565 void Archiver::add_end_compound_field()
566 {
567   theCurrentCompoundField = theCurrentCompoundField->theParent;
568   --theCurrentLevel;
569 }
570 
571 
572 /*******************************************************************************
573   Check whether there exists already a field for the nonclass object at the given
574   memory address.
575 ********************************************************************************/
lookup_non_class_field(const void * ptr)576 archive_field* Archiver::lookup_non_class_field(const void* ptr)
577 {
578   if (!ptr)
579     return NULL;
580 
581   archive_field* duplicate_field = NULL;
582 
583   theNonClassFieldsMap->get(ptr, duplicate_field);
584 
585   if (!duplicate_field)
586   {
587     Archiver* har = ::zorba::serialization::ClassSerializer::getInstance()->
588     getArchiverForHardcodedObjects();
589 
590     if (har != this)
591       duplicate_field = har->lookup_non_class_field(ptr);
592   }
593 
594   return duplicate_field;
595 }
596 
597 
598 /*******************************************************************************
599   Check whether there exists already a field for the non-simple object at the
600   given memory address.
601 ********************************************************************************/
lookup_class_field(const void * ptr)602 archive_field* Archiver::lookup_class_field(const void* ptr)
603 {
604   if (!ptr)
605     return NULL;
606 
607   archive_field* duplicate_field = NULL;
608 
609   theClassFieldsMap->get(ptr, duplicate_field);
610 
611   if (!duplicate_field)
612   {
613     Archiver* har = ::zorba::serialization::ClassSerializer::getInstance()->
614     getArchiverForHardcodedObjects();
615 
616     if (har != this)
617       duplicate_field = har->lookup_class_field(ptr);
618   }
619 
620   return duplicate_field;
621 }
622 
623 
624 /*******************************************************************************
625   Place new_field in the position occupied by ref_field, and disconnect
626   ref_field from the tree.
627 ********************************************************************************/
replace_field(archive_field * new_field,archive_field * ref_field)628 void Archiver::replace_field(archive_field* new_field, archive_field* ref_field)
629 {
630   archive_field* ref_field_parent = ref_field->theParent;
631   archive_field* ref_field_prev = ref_field_parent->theFirstChild;
632 
633   if (ref_field_prev == ref_field)//is first child
634   {
635     ref_field_parent->theFirstChild = new_field;
636     new_field->theNextSibling = ref_field->theNextSibling;
637   }
638   else
639   {
640     while (ref_field_prev->theNextSibling != ref_field)
641       ref_field_prev = ref_field_prev->theNextSibling;
642 
643     ref_field_prev->theNextSibling = new_field;
644     new_field->theNextSibling = ref_field->theNextSibling;
645   }
646 
647   new_field->theParent = ref_field_parent;
648 
649   if (ref_field_parent->theLastChild == ref_field)
650     ref_field_parent->theLastChild = new_field;
651 
652   new_field->theOrder = ref_field->theOrder;
653 }
654 
655 
656 /*******************************************************************************
657   Return the left sibling of a given field (NULL if there is no left sibling).
658 ********************************************************************************/
get_prev(archive_field * field)659 archive_field* Archiver::get_prev(archive_field* field)
660 {
661   archive_field* temp;
662   temp = field->theParent->theFirstChild;
663 
664   if (temp == field)
665     return NULL;
666 
667   while (temp)
668   {
669     if (temp->theNextSibling == field)
670       return temp;
671 
672     temp = temp->theNextSibling;
673   }
674 
675   assert(false);
676   return NULL;
677 }
678 
679 
680 /*******************************************************************************
681 
682 ********************************************************************************/
prepare_serialize_out()683 void Archiver::prepare_serialize_out()
684 {
685   if (!is_serialize_everything())
686   {
687     check_compound_fields(theRootField);
688   }
689 
690   while(check_allowed_delays(theRootField))
691   {
692   }
693 }
694 
695 
696 /*******************************************************************************
697 
698 ********************************************************************************/
check_compound_fields(archive_field * parent_field)699 void Archiver::check_compound_fields(archive_field* parent_field)
700 {
701   //resolve all references first
702   //iterate: find the reference to the top most eval_only field and resolve it
703   archive_field* refering_field;
704 
705   while (1)
706   {
707     refering_field = find_top_most_eval_only_field(parent_field);
708 
709     if(!refering_field)
710       break;
711 
712     if((refering_field->theReferredField->theAllowDelay2 != ALLOW_DELAY) ||
713       (refering_field->theReferredField->theKind == ARCHIVE_FIELD_NORMAL) ||
714       !refering_field->theReferredField->theOnlyForEval)
715     {
716       //must preserve this serialization
717       archive_field* temp_field = refering_field->theReferredField->theParent;
718       while(temp_field)
719       {
720         temp_field->theOnlyForEval = 0;
721         temp_field = temp_field->theParent;
722       }
723     }
724     else
725     {
726       exchange_mature_fields(refering_field, refering_field->theReferredField);
727       refering_field->theOnlyForEval = refering_field->theReferredField->theOnlyForEval;
728     }
729 
730     clean_only_for_eval(refering_field->theReferredField,
731                         get_only_for_eval(refering_field->theReferredField));
732   }
733 
734   while (check_only_for_eval_nondelay_referencing(parent_field))
735   {
736   }
737 
738   replace_only_for_eval_with_null(parent_field);
739 }
740 
741 
742 /*******************************************************************************
743 
744 ********************************************************************************/
find_top_most_eval_only_field(archive_field * parent_field)745 archive_field* Archiver::find_top_most_eval_only_field(archive_field* parent_field)
746 {
747   int ref_depth = -1;
748   archive_field* refering_field = NULL;
749 
750   archive_field* child = parent_field->theFirstChild;
751 
752   while (child)
753   {
754     if (child->theOnlyForEval)
755     {
756     }
757     else if (child->theKind == ARCHIVE_FIELD_REFERENCING &&
758              get_only_for_eval(child->theReferredField))
759     {
760       int new_depth = compute_field_depth(child->theReferredField);
761       if(!refering_field || (ref_depth > new_depth))
762       {
763         ref_depth = new_depth;
764         refering_field = child;
765       }
766     }
767     else if (!child->theIsSimple && !child->theReferredField)
768     {
769       archive_field* new_refering = find_top_most_eval_only_field(child);
770 
771       if (new_refering)
772       {
773         int new_depth = compute_field_depth(new_refering->theReferredField);
774         if (!refering_field || (ref_depth > new_depth))
775         {
776           ref_depth = new_depth;
777           refering_field = new_refering;
778         }
779       }
780     }
781 
782     child = child->theNextSibling;
783   }
784 
785   return refering_field;
786 }
787 
788 
789 /*******************************************************************************
790 
791 ********************************************************************************/
compute_field_depth(archive_field * field)792 int Archiver::compute_field_depth(archive_field* field)
793 {
794   archive_field* temp;
795   int i = 0;
796   temp = field->theParent;
797   while(temp)
798   {
799     temp = temp->theParent;
800     i++;
801   }
802   return i;
803 }
804 
805 
806 /*******************************************************************************
807 
808 ********************************************************************************/
get_only_for_eval(archive_field * field)809 int Archiver::get_only_for_eval(archive_field* field)
810 {
811   if (field->theOnlyForEval)
812     return field->theOnlyForEval;
813 
814   archive_field* child;
815   for (child = field->theFirstChild; child; child = child->theNextSibling)
816   {
817     if (child->theOnlyForEval)
818       return child->theOnlyForEval;
819   }
820 
821   return 0;
822 }
823 
824 
825 /*******************************************************************************
826 
827 ********************************************************************************/
clean_only_for_eval(archive_field * field,int substract_value)828 void Archiver::clean_only_for_eval(archive_field* field, int substract_value)
829 {
830   if (field->theOnlyForEval >= substract_value)
831     field->theOnlyForEval -= substract_value;
832   else
833     field->theOnlyForEval = 0;
834 
835   if (!field->theIsSimple)
836   {
837     archive_field* child = field->theFirstChild;
838     while (child)
839     {
840       clean_only_for_eval(child, substract_value);
841       child = child->theNextSibling;
842     }
843   }
844 }
845 
846 
847 /*******************************************************************************
848 
849 ********************************************************************************/
check_only_for_eval_nondelay_referencing(archive_field * parent_field)850 bool Archiver::check_only_for_eval_nondelay_referencing(archive_field* parent_field)
851 {
852   archive_field* current_field = parent_field->theFirstChild;
853 
854   while (current_field)
855   {
856     if (current_field->theOnlyForEval && current_field->theKind != ARCHIVE_FIELD_NORMAL)
857     {
858       if (current_field->theKind == ARCHIVE_FIELD_REFERENCING &&
859           current_field->theAllowDelay2 != ALLOW_DELAY &&
860           !current_field->theReferredField->theOnlyForEval)
861       {
862         //must preserve this serialization
863         archive_field* temp_field = current_field->theParent;
864         while (temp_field)
865         {
866           temp_field->theOnlyForEval = 0;
867           temp_field = temp_field->theParent;
868         }
869         clean_only_for_eval(current_field, current_field->theOnlyForEval);
870         return true;
871       }
872     }
873 
874     if (!current_field->theIsSimple)
875     {
876       if (check_only_for_eval_nondelay_referencing(current_field))
877         return true;
878     }
879 
880     current_field = current_field->theNextSibling;
881   }
882   return false;
883 }
884 
885 
886 /*******************************************************************************
887 
888 ********************************************************************************/
replace_only_for_eval_with_null(archive_field * parent_field)889 void Archiver::replace_only_for_eval_with_null(archive_field* parent_field)
890 {
891   archive_field* current_field = parent_field->theFirstChild;
892 
893   while (current_field)
894   {
895     if (current_field->theOnlyForEval &&
896         (current_field->theKind != ARCHIVE_FIELD_NORMAL) &&
897         (current_field->theKind != ARCHIVE_FIELD_BASECLASS))
898     {
899       //don't save it, replace it with NULL if possible
900       archive_field* null_field = replace_with_null(current_field);
901 
902       orphan_fields.push_back(current_field);
903       current_field = null_field;
904     }
905 
906     if (!current_field->theIsSimple)
907     {
908       replace_only_for_eval_with_null(current_field);
909     }
910 
911     current_field = current_field->theNextSibling;
912   }
913 }
914 
915 
916 /*******************************************************************************
917 
918 ********************************************************************************/
replace_with_null(archive_field * current_field)919 archive_field* Archiver::replace_with_null(archive_field* current_field)
920 {
921   if (current_field->theParent)
922   {
923     archive_field* null_field = new archive_field(TYPE_NULL,
924                                                   current_field->theIsSimple,
925                                                   current_field->theIsClass,
926                                                   NULL,
927                                                   ARCHIVE_FIELD_NULL,
928                                                   NULL,
929                                                   false,
930                                                   ALLOW_DELAY,
931                                                   current_field->theLevel);
932     null_field->theId = 0;
933     replace_field(null_field, current_field);
934     current_field->theParent = NULL;
935     current_field->theNextSibling = NULL;
936 
937     return null_field;
938   }
939 
940   //otherwise it is orphan
941   return NULL;
942 }
943 
944 
945 /*******************************************************************************
946 
947 ********************************************************************************/
check_allowed_delays(archive_field * parent_field)948 bool Archiver::check_allowed_delays(archive_field* parent_field)
949 {
950   //check all fields with dont_allow_delay and see if they are delayed
951   //exchange field with the reference then
952   archive_field* child = parent_field->theFirstChild;
953 
954   while (child)
955   {
956     if (child->theKind == ARCHIVE_FIELD_REFERENCING &&
957         check_order(child, child->theReferredField) < 1)
958     {
959       ZORBA_ASSERT(false);
960     }
961 
962     if (child->theKind == ARCHIVE_FIELD_REFERENCING &&
963        ((child->theAllowDelay2 == DONT_ALLOW_DELAY &&
964          check_order(child, child->theReferredField) < 1) ||
965         child->theAllowDelay2 == SERIALIZE_NOW))
966     {
967       if (child->theReferredField->theKind == ARCHIVE_FIELD_NORMAL ||
968           child->theReferredField->theAllowDelay2 == SERIALIZE_NOW)
969       {
970         //impossible to solve situation
971         //need to change the serialization order somewhere
972         throw ZORBA_EXCEPTION(zerr::ZCSE0014_INFINITE_CIRCULAR_DEPENDENCIES);
973       }
974 
975       //exchange fields
976       exchange_mature_fields(child, child->theReferredField);
977 
978       child = child->theReferredField;
979 
980       return true;
981     }
982 
983     if (check_allowed_delays(child))
984       return true;
985 
986     child = child->theNextSibling;
987   }
988 
989   return false;
990 }
991 
992 
993 /*******************************************************************************
994   return 0 if not found
995   return -1 if field1 is before field2
996   return 1  if field1 is after field2
997 ********************************************************************************/
check_order(archive_field * field1,archive_field * field2)998 int Archiver::check_order(archive_field* field1, archive_field* field2)
999 {
1000 
1001   if (field1->theOrder < field2->theOrder)
1002     return -1;
1003   else if (field1->theOrder == field2->theOrder)
1004     return 0;
1005   else
1006     return 1;
1007 }
1008 
1009 
1010 /*******************************************************************************
1011 
1012 ********************************************************************************/
exchange_mature_fields(archive_field * field1,archive_field * field2)1013 void Archiver::exchange_mature_fields(archive_field* field1, archive_field* field2)
1014 {
1015   archive_field* field1_prev = get_prev(field1);
1016   archive_field* field1_next = field1->theNextSibling;
1017   archive_field* field1_parent = field1->theParent;
1018   archive_field* field2_prev = get_prev(field2);
1019   archive_field* field2_parent = field2->theParent;
1020   archive_field* field2_next = field2->theNextSibling;
1021 
1022   //move field2
1023   if (field1_prev)
1024     field1_prev->theNextSibling = field2;
1025   else
1026     field1_parent->theFirstChild = field2;
1027 
1028   field2->theNextSibling = field1_next;
1029 
1030   if (!field1_next)
1031     field1_parent->theLastChild = field2;
1032 
1033   field2->theParent = field1_parent;
1034 
1035   //move field1
1036   if (field2_prev)
1037     field2_prev->theNextSibling = field1;
1038   else
1039     field2_parent->theFirstChild = field1;
1040 
1041   field1->theNextSibling = field2_next;
1042 
1043   if (!field2_next)
1044     field2_parent->theLastChild = field1;
1045 
1046   field1->theParent = field2_parent;
1047 
1048   ENUM_ALLOW_DELAY temp_delay = field1->theAllowDelay2;
1049   field1->theAllowDelay2 = field2->theAllowDelay2;
1050   field2->theAllowDelay2 = temp_delay;
1051 
1052   unsigned int  temp_order;
1053   temp_order = field1->theOrder;
1054   field1->theOrder = field2->theOrder;
1055   field2->theOrder = temp_order;
1056 }
1057 
1058 
1059 ////////////////////////////////////////////////////////////////////////////////
1060 //                                                                            //
1061 //  De-Serialization only                                                     //
1062 //                                                                            //
1063 ////////////////////////////////////////////////////////////////////////////////
1064 
1065 
1066 /*******************************************************************************
1067 
1068 ********************************************************************************/
root_tag_is_read()1069 void Archiver::root_tag_is_read()
1070 {
1071   if (theArchiveVersion != ClassSerializer::g_zorba_classes_version)
1072   {
1073     throw ZORBA_EXCEPTION(zerr::ZCSE0012_INCOMPATIBLE_ARCHIVE_VERSION,
1074     ERROR_PARAMS(theArchiveVersion, ClassSerializer::g_zorba_classes_version));
1075   }
1076 
1077   all_reference_list = new void*[theFieldCounter+1];
1078 
1079   memset(all_reference_list, 0, sizeof(void*)*(theFieldCounter+1));
1080 }
1081 
1082 
1083 /*******************************************************************************
1084 
1085 ********************************************************************************/
read_next_compound_field(bool is_class,ArchiveFieldKind & field_kind,TypeCode & type,int & id,int & referencing)1086 void Archiver::read_next_compound_field(
1087     bool is_class,
1088     ArchiveFieldKind& field_kind,
1089     TypeCode& type,
1090     int& id,
1091     int& referencing)
1092 {
1093   read_next_compound_field_impl(is_class, field_kind, type, id, referencing);
1094 
1095   if (field_kind != ARCHIVE_FIELD_REFERENCING)
1096     ++theCurrentLevel;
1097 }
1098 
1099 
1100 /*******************************************************************************
1101 
1102 ********************************************************************************/
read_next_simple_ptr_field(TypeCode type,void ** obj)1103 void Archiver::read_next_simple_ptr_field(TypeCode type, void** obj)
1104 {
1105   read_next_simple_ptr_field_impl(type, obj);
1106 }
1107 
1108 
1109 /*******************************************************************************
1110 
1111 ********************************************************************************/
read_next_simple_temp_field(TypeCode type,void * obj)1112 void Archiver::read_next_simple_temp_field(TypeCode type, void* obj)
1113 {
1114   read_next_simple_temp_field_impl(type, obj);
1115 }
1116 
1117 
1118 /*******************************************************************************
1119 
1120 ********************************************************************************/
read_end_current_level()1121 void Archiver::read_end_current_level()
1122 {
1123   --theCurrentLevel;
1124   read_end_current_level_impl();
1125 }
1126 
1127 
1128 /*******************************************************************************
1129 
1130 ********************************************************************************/
check_nonclass_field(ArchiveFieldKind field_treat,ArchiveFieldKind required_field_treat,int id)1131 void Archiver::check_nonclass_field(
1132     ArchiveFieldKind field_treat,
1133     ArchiveFieldKind required_field_treat,
1134     int id)
1135 {
1136   if (field_treat == ARCHIVE_FIELD_NULL)
1137     return;
1138 
1139   if ((required_field_treat != (enum ArchiveFieldKind)-1) &&
1140       field_treat != required_field_treat)
1141   {
1142     throw ZORBA_EXCEPTION(zerr::ZCSE0002_INCOMPATIBLE_INPUT_FIELD, ERROR_PARAMS(id));
1143   }
1144 }
1145 
1146 
1147 /*******************************************************************************
1148 
1149 ********************************************************************************/
check_class_field(TypeCode type,TypeCode required_type,ArchiveFieldKind field_treat,ArchiveFieldKind required_field_treat,int id)1150 void Archiver::check_class_field(
1151     TypeCode type,
1152     TypeCode required_type,
1153     ArchiveFieldKind field_treat,
1154     ArchiveFieldKind required_field_treat,
1155     int id)
1156 {
1157   if (field_treat == ARCHIVE_FIELD_NULL)
1158     return;
1159 
1160   if ((required_field_treat != (ArchiveFieldKind)-1) &&
1161      field_treat != required_field_treat)
1162   {
1163     throw ZORBA_EXCEPTION(zerr::ZCSE0002_INCOMPATIBLE_INPUT_FIELD, ERROR_PARAMS(id));
1164   }
1165 
1166 #ifndef NDEBUG
1167   if (field_treat == ARCHIVE_FIELD_PTR && type != required_type)
1168   {
1169     throw ZORBA_EXCEPTION(zerr::ZCSE0002_INCOMPATIBLE_INPUT_FIELD, ERROR_PARAMS(id));
1170   }
1171 #endif
1172 }
1173 
1174 
1175 /*******************************************************************************
1176 
1177 ********************************************************************************/
register_reference(int id,ArchiveFieldKind field_kind,const void * ptr)1178 void Archiver::register_reference(int id, ArchiveFieldKind field_kind, const void* ptr)
1179 {
1180   if (get_is_temp_field())
1181     return;
1182 
1183   if (get_is_temp_field_one_level() && field_kind != ARCHIVE_FIELD_PTR)
1184     return;
1185 
1186   all_reference_list[id] = (void*)ptr;
1187 }
1188 
1189 
1190 /*******************************************************************************
1191 
1192 ********************************************************************************/
register_item(store::Item * i)1193 void Archiver::register_item(store::Item* i)
1194 {
1195   if (i)
1196     registered_items.push_back(i);
1197 }
1198 
1199 
1200 /*******************************************************************************
1201 
1202 ********************************************************************************/
get_reference_value(int refid)1203 void* Archiver::get_reference_value(int refid)
1204 {
1205   if (internal_archive && !all_reference_list)
1206   {
1207     //construct all_reference_list
1208     root_tag_is_read();
1209     register_pointers_internal(theRootField);
1210   }
1211 
1212   void* assoc_ptr = NULL;
1213 
1214   if (!(assoc_ptr = all_reference_list[refid]))
1215   {
1216     Archiver* har = ::zorba::serialization::ClassSerializer::getInstance()->
1217                     getArchiverForHardcodedObjects();
1218 
1219     if (har != this)
1220       assoc_ptr = har->get_reference_value(refid);
1221   }
1222 
1223   return assoc_ptr;
1224 }
1225 
1226 
1227 /*******************************************************************************
1228 
1229 ********************************************************************************/
register_pointers_internal(archive_field * fields)1230 void Archiver::register_pointers_internal(archive_field* fields)
1231 {
1232   archive_field* child;
1233   child = fields->theFirstChild;
1234 
1235   while (child)
1236   {
1237     register_reference(child->theId, child->theKind, child->theObjPtr);
1238     if (!child->theIsSimple)
1239     {
1240       register_pointers_internal(child);
1241     }
1242     child = child->theNextSibling;
1243   }
1244 }
1245 
1246 
1247 /*******************************************************************************
1248   Decrement RC on Items
1249 ********************************************************************************/
finalize_input_serialization()1250 void Archiver::finalize_input_serialization()
1251 {
1252   std::vector<store::Item*>::iterator item_it;
1253 
1254   for (item_it = registered_items.begin();
1255        item_it != registered_items.end();
1256        ++item_it)
1257   {
1258     if ((*item_it)->isNode())
1259     {
1260       assert(*(*item_it)->getSharedRefCounter() > 1);
1261     }
1262     else
1263     {
1264       assert((*item_it)->getRefCount() > 1);
1265     }
1266 
1267     (*item_it)->removeReference();
1268   }
1269 }
1270 
1271 
1272 } // namsspace serialization
1273 } // namespace zorba
1274 /* vim:set et sw=2 ts=2: */
1275