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