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