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 #pragma once
17 #ifndef TEMPLATE_SERIALIZATION_OPERATORS
18 #define TEMPLATE_SERIALIZATION_OPERATORS
19
20 #include <list>
21 #include <vector>
22 #include <map>
23 #include <stdio.h>
24
25 #include <zorba/diagnostic_list.h>
26 #include <zorba/internal/unique_ptr.h>
27
28 #include "util/string_util.h"
29 #include "util/stl_util.h"
30
31 #include "diagnostics/xquery_diagnostics.h"
32 #include "diagnostics/assert.h"
33
34 #include "zorbatypes/zstring.h"
35
36 #include "zorbautils/checked_vector.h"
37
38 #include "zorbaserialization/archiver.h"
39 //#include "zorbaserialization/class_serializer.h"
40 #include "zorbaserialization/serialize_basic_types.h"
41
42 namespace zorba
43 {
44
45 namespace serialization
46 {
47
48 /*******************************************************************************
49
50 ********************************************************************************/
51 template<class T>
serialize_baseclass(Archiver & ar,T * obj)52 void serialize_baseclass(Archiver& ar, T* obj)
53 {
54 ar.set_serialize_base_class(true);
55
56 ar & obj;
57 }
58
59
60 /*******************************************************************************
61
62 ********************************************************************************/
63 template<class T>
64 void operator&(Archiver& ar, T& obj)
65 {
66 if (ar.is_serializing_out())
67 {
68 bool is_ref = ar.add_compound_field(obj.get_serializer_type_code(),
69 true,
70 (SerializeBaseClass*)&obj,
71 ARCHIVE_FIELD_NORMAL);
72 if (!is_ref)
73 {
74 obj.serialize_internal(ar);
75
76 ar.add_end_compound_field();
77 }
78 }
79 else
80 {
81 TypeCode type;
82 int id;
83 ArchiveFieldKind field_kind = ARCHIVE_FIELD_NORMAL;
84 int referencing;
85
86 ar.read_next_compound_field(true, field_kind, type, id, referencing);
87
88 ar.check_class_field(type, obj.get_serializer_type_code(),
89 field_kind, ARCHIVE_FIELD_NORMAL, id);
90
91 ar.register_reference(id, field_kind, (SerializeBaseClass*)&obj);
92
93 obj.serialize_internal(ar);
94
95 ar.read_end_current_level();
96 }
97 }
98
99
100 /*******************************************************************************
101
102 ********************************************************************************/
103 template<class T>
104 void operator&(Archiver& ar, T*& obj)
105 {
106 if (ar.is_serializing_out())
107 {
108 if (obj == NULL)
109 {
110 ar.add_compound_field(TYPE_NULL, true, NULL, ARCHIVE_FIELD_NULL);
111 return;
112 }
113
114 bool is_ref = ar.add_compound_field((ar.is_serialize_base_class() ?
115 TYPE_LAST :
116 obj->get_serializer_type_code()),
117 true,
118 (SerializeBaseClass*)obj,
119 (ar.is_serialize_base_class() ?
120 ARCHIVE_FIELD_BASECLASS :
121 ARCHIVE_FIELD_PTR));
122 if (!is_ref)
123 {
124 if (!ar.is_serialize_base_class())
125 {
126 obj->serialize_internal(ar);
127 }
128 else
129 {
130 obj->T::serialize_internal(ar);
131 }
132
133 ar.add_end_compound_field();
134 }
135 }
136 else
137 {
138 TypeCode type;
139 int id;
140 ArchiveFieldKind field_kind = ARCHIVE_FIELD_PTR;
141 int referencing;
142
143 ar.read_next_compound_field(true, field_kind, type, id, referencing);
144
145 ar.check_class_field(TYPE_NULL, TYPE_NULL,
146 field_kind, (ArchiveFieldKind)-1, id);
147
148 if (field_kind == ARCHIVE_FIELD_NULL)
149 {
150 assert(!ar.is_serialize_base_class());
151 obj = NULL;
152 ar.read_end_current_level();
153 return;
154 }
155
156 if (ar.is_serialize_base_class())
157 {
158 if (field_kind != ARCHIVE_FIELD_BASECLASS)
159 {
160 throw ZORBA_EXCEPTION(zerr::ZCSE0002_INCOMPATIBLE_INPUT_FIELD, ERROR_PARAMS(id));
161 }
162 }
163 else
164 {
165 if (field_kind != ARCHIVE_FIELD_PTR && field_kind != ARCHIVE_FIELD_REFERENCING)
166 {
167 throw ZORBA_EXCEPTION(zerr::ZCSE0002_INCOMPATIBLE_INPUT_FIELD, ERROR_PARAMS(id));
168 }
169 }
170
171 SerializeBaseClass* new_obj = NULL;
172
173 if (field_kind == ARCHIVE_FIELD_PTR)
174 {
175 assert(type > 0 && type < TYPE_LAST);
176
177 ClassDeserializer* cls_factory;
178 cls_factory = ClassSerializer::getInstance()->get_class_factory(type);
179
180 if (cls_factory == NULL)
181 {
182 throw ZORBA_EXCEPTION(zerr::ZCSE0003_UNRECOGNIZED_CLASS_FIELD,
183 ERROR_PARAMS(BUILD_STRING((ulong)type)));
184 }
185
186 new_obj = cls_factory->create_new(ar);
187
188 obj = dynamic_cast<T*>(new_obj);
189
190 if (!obj)
191 {
192 delete new_obj;
193 obj = NULL;
194
195 throw ZORBA_EXCEPTION(zerr::ZCSE0002_INCOMPATIBLE_INPUT_FIELD,
196 ERROR_PARAMS(id, BUILD_STRING((ulong)type), typeid(T).name()));
197 }
198
199 ar.register_reference(id, field_kind, new_obj);
200
201 try
202 {
203 obj->serialize_internal(ar);
204 }
catch(...)205 catch(...)
206 {
207 delete new_obj;
208 obj = NULL;
209 throw;
210 }
211
212 ar.read_end_current_level();
213 }
214 else if (field_kind == ARCHIVE_FIELD_BASECLASS)
215 {
216 obj->T::serialize_internal(ar);
217
218 ar.read_end_current_level();
219 }
220 // ARCHIVE_FIELD_REFERENCING
221 else if ((new_obj = (SerializeBaseClass*)ar.get_reference_value(referencing)))
222 {
223 try
224 {
225 obj = dynamic_cast<T*>(new_obj);
226 }
catch(...)227 catch(...)
228 {
229 throw ZORBA_EXCEPTION(zerr::ZCSE0004_UNRESOLVED_FIELD_REFERENCE,
230 ERROR_PARAMS(id));
231 }
232
233 if (!obj)
234 {
235 throw ZORBA_EXCEPTION(zerr::ZCSE0002_INCOMPATIBLE_INPUT_FIELD,
236 ERROR_PARAMS(id));
237 }
238 }
239 else
240 {
241 ZORBA_ASSERT(false);
242 }
243 }
244 }
245
246
247 template<class T>
248 void operator&(Archiver& ar, zorba::rchandle<T>& obj)
249 {
250 if (ar.is_serializing_out())
251 {
252 T* p = obj.getp();
253 ar & p;
254 }
255 else
256 {
257 T* p;
258 ar & p;
259 obj = p;
260 }
261 }
262
263
264 template<class T>
265 void operator&(Archiver& ar, zorba::const_rchandle<T>& obj)
266 {
267 if (ar.is_serializing_out())
268 {
269 T* p = (T*)obj.getp();
270 ar & p;
271 }
272 else
273 {
274 T* p;
275 ar & p;
276 obj = p;
277 }
278 }
279
280
281 template<class T>
282 void operator&(Archiver& ar, store::ItemHandle<T>& obj)
283 {
284 if (ar.is_serializing_out())
285 {
286 T* p = obj.getp();
287 ar & p;
288 }
289 else
290 {
291 T* p;
292 ar & p;
293 obj = p;
294 }
295 }
296
297
298 /*******************************************************************************
299
300 ********************************************************************************/
301 template<class T>
302 void operator&(Archiver& ar, checked_vector<T>& obj)
303 {
304 if (ar.is_serializing_out())
305 {
306 csize size = obj.size();
307 ar & size;
308
309 typename checked_vector<T>::iterator it = obj.begin();
310 typename checked_vector<T>::iterator end = obj.end();
311 for(; it != end; ++it)
312 {
313 ar & (*it);
314 }
315 }
316 else
317 {
318 csize size;
319 ar & size;
320
321 obj.resize(size);
322
323 typename checked_vector<T>::iterator it = obj.begin();
324 typename checked_vector<T>::iterator end = obj.end();
325
326 for(; it != end; ++it)
327 {
328 ar & (*it);
329 }
330 }
331 }
332
333
334 /*******************************************************************************
335
336 ********************************************************************************/
337 template<typename T>
338 void operator&(Archiver& ar, std::vector<T>& obj)
339 {
340 if (ar.is_serializing_out())
341 {
342 csize size = obj.size();
343 ar & size;
344
345 typename std::vector<T>::iterator it = obj.begin();
346 typename std::vector<T>::iterator end = obj.end();
347 for (; it != end; ++it)
348 {
349 ar & (*it);
350 }
351 }
352 else
353 {
354 csize size;
355 ar & size;
356
357 obj.resize(size);
358
359 typename std::vector<T>::iterator it = obj.begin();
360 typename std::vector<T>::iterator end = obj.end();
361 for (; it != end; ++it)
362 {
363 ar & (*it);
364 }
365 }
366 }
367
368
369 /*******************************************************************************
370
371 ********************************************************************************/
372 template<typename T>
373 void operator&(Archiver& ar, std::vector<T*>& obj)
374 {
375 if (ar.is_serializing_out())
376 {
377 csize size = obj.size();
378 ar & size;
379
380 typename std::vector<T*>::iterator it = obj.begin();
381 typename std::vector<T*>::iterator end = obj.end();
382 for (; it != end; ++it)
383 {
384 ar & (*it);
385 }
386 }
387 else
388 {
389 csize size;
390 ar & size;
391
392 obj.resize(size);
393
394 typename std::vector<T*>::iterator it = obj.begin();
395 typename std::vector<T*>::iterator end = obj.end();
396
397 for (; it != end; ++it)
398 {
399 ar & (*it);
400 }
401 }
402 }
403
404
405 /*******************************************************************************
406
407 ********************************************************************************/
408 template<typename T>
409 void operator&(Archiver& ar, std::vector<T>*& obj)
410 {
411 assert(!ar.is_serialize_base_class());
412
413 csize size = 0;
414
415 if (ar.is_serializing_out())
416 {
417 if (obj == NULL)
418 {
419 ar.add_compound_field(TYPE_NULL, false, NULL, ARCHIVE_FIELD_NULL);
420 return;
421 }
422
423 bool is_ref = ar.add_compound_field(TYPE_LAST, false, obj, ARCHIVE_FIELD_PTR);
424 assert(!is_ref);
425 (void)is_ref;
426
427 size = obj->size();
428 ar & size;
429
430 typename std::vector<T>::iterator it = obj->begin();
431 typename std::vector<T>::iterator end = obj->end();
432 for (; it != end; ++it)
433 {
434 ar & (*it);
435 }
436
437 ar.add_end_compound_field();
438 }
439 else
440 {
441 TypeCode type;
442 int id;
443 ArchiveFieldKind field_kind = ARCHIVE_FIELD_PTR;
444 int referencing;
445
446 ar.read_next_compound_field(false, field_kind, type, id, referencing);
447
448 ar.check_nonclass_field(field_kind, (ArchiveFieldKind)-1, id);
449
450 if (field_kind == ARCHIVE_FIELD_NULL)
451 {
452 obj = NULL;
453 ar.read_end_current_level();
454 return;
455 }
456
457 ZORBA_ASSERT(field_kind == ARCHIVE_FIELD_PTR);
458
459 obj = new std::vector<T>;
460
461 ar & size;
462
463 obj->resize(size);
464
465 typename std::vector<T>::iterator it = obj->begin();
466 typename std::vector<T>::iterator end = obj->end();
467 for (; it != end; ++it)
468 {
469 ar & (*it);
470 }
471
472 ar.read_end_current_level();
473 }
474 }
475
476
477 /*******************************************************************************
478
479 ********************************************************************************/
480 template<typename T>
481 void operator&(Archiver& ar, std::list<T>& obj)
482 {
483 if (ar.is_serializing_out())
484 {
485 csize size = obj.size();
486 ar & size;
487
488 typename std::list<T>::iterator it = obj.begin();
489 typename std::list<T>::iterator end = obj.end();
490 for (; it != end; ++it)
491 {
492 ar & (*it);
493 }
494 }
495 else
496 {
497 csize size;
498 ar & size;
499
500 obj.resize(size);
501
502 typename std::list<T>::iterator it = obj.begin();
503 typename std::list<T>::iterator end = obj.end();
504 for (; it != end; ++it)
505 {
506 ar & (*it);
507 }
508 }
509 }
510
511
512 /*******************************************************************************
513
514 ********************************************************************************/
515 template<typename T1, typename T2>
516 void operator&(Archiver& ar, std::pair<T1, T2>& obj)
517 {
518 ar & obj.first;
519 ar & obj.second;
520 }
521
522
523 /*******************************************************************************
524
525 ********************************************************************************/
526 template<typename T1, typename T2>
527 void operator&(Archiver& ar, std::map<T1, T2>*& obj)
528 {
529 assert(!ar.is_serialize_base_class());
530
531 csize size = 0;
532
533 if (ar.is_serializing_out())
534 {
535 if (obj == NULL)
536 {
537 ar.add_compound_field(TYPE_NULL, false, NULL, ARCHIVE_FIELD_NULL);
538 return;
539 }
540
541 bool is_ref = ar.add_compound_field(TYPE_LAST, false, obj, ARCHIVE_FIELD_PTR);
542
543 assert(!is_ref);
544 (void)is_ref;
545
546 size = obj->size();
547 ar & size;
548
549 typename std::map<T1, T2>::iterator it = obj->begin();
550 typename std::map<T1, T2>::iterator end = obj->end();
551
552 for (; it != end; ++it)
553 {
554 T1 key = (*it).first;
555 ar & key;
556 ar & (*it).second;
557 }
558
559 ar.add_end_compound_field();
560 }
561 else
562 {
563 TypeCode type;
564 int id;
565 ArchiveFieldKind field_kind = ARCHIVE_FIELD_PTR;
566 int referencing;
567
568 ar.read_next_compound_field(false, field_kind, type, id, referencing);
569
570 ar.check_nonclass_field(field_kind, (ArchiveFieldKind)-1, id);
571
572 if (field_kind == ARCHIVE_FIELD_NULL)
573 {
574 obj = NULL;
575 ar.read_end_current_level();
576 return;
577 }
578
579 ZORBA_ASSERT(field_kind == ARCHIVE_FIELD_PTR);
580
581 obj = new std::map<T1, T2>;
582
583 ar & size;
584
585 std::pair<T1, T2> p;
586
587 for (csize i = 0; i < size; ++i)
588 {
589 ar & p.first;
590 ar & p.second;
591
592 obj->insert(p);
593 }
594
595 ar.read_end_current_level();
596 }
597 }
598
599
600 /*******************************************************************************
601
602 ********************************************************************************/
603 template<typename T1, typename T2, class Tcomp>
604 void operator&(Archiver& ar, std::map<T1, T2, Tcomp>& obj)
605 {
606 if (ar.is_serializing_out())
607 {
608 csize s = obj.size();
609 ar & s;
610
611 typename std::map<T1, T2, Tcomp>::iterator it = obj.begin();
612 typename std::map<T1, T2, Tcomp>::iterator end = obj.end();
613
614 for (; it != end; ++it)
615 {
616 T1 key = (*it).first;
617 ar & key;
618 ar & (*it).second;
619 }
620 }
621 else
622 {
623 csize s;
624 ar & s;
625
626 std::pair<T1, T2> p;
627
628 for (csize i = 0; i < s; ++i)
629 {
630 ar & p.first;
631 ar & p.second;
632
633 obj.insert(p);
634 }
635 }
636 }
637
638
639 /*******************************************************************************
640
641 ********************************************************************************/
642 template<typename T, typename V, class Tcomp>
643 void operator&(Archiver& ar, HashMap<T, V, Tcomp>& obj)
644 {
645 ar & obj.theHashTabSize;
646 ar & obj.theCompareFunction;
647
648 bool sync = false;
649 csize size;
650
651 if (ar.is_serializing_out())
652 {
653 sync = obj.get_sync();
654 size = obj.size();
655
656 ar & sync;
657 ar & size;
658
659 typename HashMap<T, V, Tcomp>::iterator it = obj.begin();
660 typename HashMap<T, V, Tcomp>::iterator end = obj.end();
661
662 for (; it != end; ++it)
663 {
664 T key = it.getKey();
665 ar & key;
666 ar & it.getValue();
667 }
668 }
669 else
670 {
671 ar & sync;
672 ar & size;
673
674 obj.theNumEntries = 0;
675 obj.theInitialSize = obj.theHashTabSize;
676 obj.theHashTab = computeTabSize(obj.theHashTabSize);
677 obj.theLoadFactor = HashMap<T, V, Tcomp>::DEFAULT_LOAD_FACTOR;
678 obj.numCollisions = 0;
679
680 obj.formatCollisionArea();
681
682 SYNC_CODE(obj.theMutexp = (sync ? &obj.theMutex : NULL);)
683
684 for (csize i = 0; i < size; ++i)
685 {
686 T t;
687 V v;
688 ar & t;
689 ar & v;
690 bool insert_ret = obj.insert(t, v);
691 assert(insert_ret);
692 (void)insert_ret;
693 }
694 }
695 }
696
697
698 /*******************************************************************************
699
700 ********************************************************************************/
701 template<typename T, typename V, class Tcomp>
702 void operator&(Archiver& ar, HashMap<T, V, Tcomp>*& obj)
703 {
704 assert(!ar.is_serialize_base_class());
705
706 bool sync = false;
707 csize size;
708 csize capacity;
709 Tcomp comp;
710
711 if (ar.is_serializing_out())
712 {
713 if (obj == NULL)
714 {
715 ar.add_compound_field(TYPE_NULL, false, NULL, ARCHIVE_FIELD_NULL);
716 return;
717 }
718
719 bool is_ref = ar.add_compound_field(TYPE_LAST, false, obj, ARCHIVE_FIELD_PTR);
720
721 assert(!is_ref);
722 (void)is_ref;
723
724 sync = obj->get_sync();
725 capacity = obj->capacity();
726 comp = obj->get_compare_function();
727 size = obj->size();
728
729 ar.set_is_temp_field(true);
730
731 ar & capacity;
732 ar & sync;
733 ar & comp;
734 ar & size;
735
736 ar.set_is_temp_field(false);
737
738 typename HashMap<T, V, Tcomp>::iterator it = obj->begin();
739 typename HashMap<T, V, Tcomp>::iterator end = obj->end();
740
741 for (; it != end; ++it)
742 {
743 T key = it.getKey();
744 ar & key;
745 ar & it.getValue();
746 }
747
748 ar.add_end_compound_field();
749 }
750 else
751 {
752 TypeCode type;
753 int id;
754 ArchiveFieldKind field_kind = ARCHIVE_FIELD_PTR;
755 int referencing;
756
757 ar.read_next_compound_field(false, field_kind, type, id, referencing);
758
759 ar.check_nonclass_field(field_kind, (ArchiveFieldKind)-1, id);
760
761 if (field_kind == ARCHIVE_FIELD_NULL)
762 {
763 obj = NULL;
764 ar.read_end_current_level();
765 return;
766 }
767
768 assert(field_kind == ARCHIVE_FIELD_PTR);
769
770 ar.set_is_temp_field(true);
771
772 ar & capacity;
773 ar & sync;
774 ar & comp;
775 ar & size;
776
777 ar.set_is_temp_field(false);
778
779 obj = new HashMap<T, V, Tcomp>(comp, capacity, sync);
780
781 for (csize i = 0; i < size; ++i)
782 {
783 T key;
784 V value;
785 ar & key;
786 ar & value;
787 bool insert_ret = obj->insert(key, value);
788 assert(insert_ret);
789 (void)insert_ret;
790 }
791
792 ar.read_end_current_level();
793 }
794 }
795
796
797 template<typename FloatType>
798 void operator&(Archiver& ar, FloatImpl<FloatType>& obj)
799 {
800 ar & obj.value_;
801 ar & obj.precision_;
802 }
803
804
805 } // namespace serialization
806 } // namespace zorba
807
808 #endif /* TEMPLATE_SERIALIZATION_OPERATORS */
809 /* vim:set et sw=2 ts=2: */
810