00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #if !defined (SERIALIZATION_PUBLIC_H)
00032 #define SERIALIZATION_PUBLIC_H
00033
00034
00035
00036
00037 #define SERIALIZATION_DISABLED
00038 #if defined(SERIALIZATION_DISABLED)
00039
00040 #if defined(THROW_SPEC)
00041 #undef THROW_SPEC
00042 #endif
00043 #define THROW_SPEC(X)
00044
00045 #include <stdlib.h>
00046
00047 namespace Dyninst {
00048 class Serializable {
00049 public:
00050 virtual ~Serializable() {}
00051 };
00052 class SerializerBase {
00053 public:
00054 virtual ~SerializerBase() {}
00055 };
00056
00057 template <class T>
00058 class AnnotationContainer
00059 {
00060 virtual bool deserialize_item(SerializerBase *) { return true; }
00061 public:
00062 AnnotationContainer() { }
00063 virtual ~AnnotationContainer() { }
00064 virtual bool addItem_impl(T t) = 0;
00065 bool addItem(T t) { return addItem_impl(t); }
00066 virtual const char *getElementTypename() {return NULL;}
00067 virtual Serializable *ac_serialize_impl(SerializerBase *, const char *) THROW_SPEC(SerializerError) { return NULL; };
00068 };
00069 }
00070
00071 #else
00072
00073 #include <stdio.h>
00074 #include <assert.h>
00075 #include <string.h>
00076 #include <stdexcept>
00077 #include <typeinfo>
00078 #include <vector>
00079 #include <map>
00080 #include <assert.h>
00081 #include "dyntypes.h"
00082 #include "util.h"
00083 #include "Annotatable.h"
00084 #include "boost/type_traits/is_fundamental.hpp"
00085 #include "boost/type_traits/is_const.hpp"
00086 #include "boost/type_traits/remove_cv.hpp"
00087 #include "boost/type_traits/is_pointer.hpp"
00088 #include "boost/type_traits/is_enum.hpp"
00089 #include "boost/type_traits/alignment_of.hpp"
00090 #include "boost/type_traits/type_with_alignment.hpp"
00091 #include "boost/type_traits/remove_pointer.hpp"
00092
00093 #define SERIALIZE_CONTROL_ENV_VAR "DYNINST_SERIALIZE_ENABLE"
00094 #define SERIALIZE_DISABLE "disable"
00095 #define SERIALIZE_ONLY "serialize_but_dont_deserialize"
00096 #define SERIALIZE_DESERIALIZE "deserialize"
00097 #define SERIALIZE_DESERIALIZE_OR_DIE "deser_or_die"
00098 #define DESERIALIZE_FORCE_ENV_VAR "DYNINST_DESERIALIZE_FORCE"
00099
00100 namespace Dyninst
00101 {
00102 #if 0
00103
00104
00105
00106
00107
00108
00109
00110
00111 #define throw_ser_err(FILE__, __LINE__,cmsg) \
00112 do { \
00113 if (serializer_debug_flag()) { \
00114 serialize_printf("SER_ERR: %s", cmsg); \
00115 throw SerializerError(__FILE__, __LINE__, std::string(cmsg)); \
00116 } else { \
00117 throw SerializerError(__FILE__, __LINE__, std::string(cmsg)); \
00118 } \
00119 } while (0)
00120 #endif
00121
00122 COMMON_EXPORT bool &serializer_debug_flag();
00123
00124 class SerializerBase;
00125
00126 typedef enum {sd_serialize, sd_deserialize} iomode_t;
00127
00128 class SerializerError {
00129
00130
00131
00132
00133
00134
00135
00136 public:
00137
00138 typedef enum {
00139 ser_err_unspecified,
00140 ser_err_no_err,
00141 ser_err_disabled
00142 } SerializerErrorType;
00143
00144 private:
00145
00146 std::string msg__;
00147 std::string file__;
00148 int line__;
00149 SerializerErrorType err__;
00150
00151 public:
00152
00153 COMMON_EXPORT SerializerError(const std::string &__file__,
00154 const int &__line__,
00155 const std::string &msg,
00156 SerializerErrorType __err__ = ser_err_unspecified) :
00157 msg__(msg),
00158 file__(__file__),
00159 line__(__line__),
00160 err__(__err__)
00161 {}
00162
00163 COMMON_EXPORT virtual ~SerializerError() THROW {}
00164
00165 COMMON_EXPORT std::string file() const {return file__;}
00166 COMMON_EXPORT std::string msg() const {return msg__;}
00167 COMMON_EXPORT const char* what() const {return msg__.c_str();}
00168 COMMON_EXPORT int line() const {return line__;}
00169 COMMON_EXPORT SerializerErrorType code() const {return err__;}
00170 };
00171
00172 COMMON_EXPORT void printSerErr(const SerializerError &err);
00173
00174 typedef enum {
00175 ser_bin,
00176 ser_xml
00177 } ser_type_t;
00178
00179 class SerContextBase
00180 {
00181 friend class Serializable;
00182 friend class SerializerBase;
00183 COMMON_EXPORT static std::vector<std::pair<std::string, dyn_hash_map<std::string, short>*> > ser_control_map;
00184 std::string fname;
00185 std::string serfilename;
00186 static dyn_hash_map<std::string, short> *getMapForType(std::string);
00187 public:
00188
00189 COMMON_EXPORT SerContextBase(std::string, std::string);
00190 COMMON_EXPORT virtual ~SerContextBase() {}
00191 COMMON_EXPORT virtual void *getVoidContext() = 0;
00192 COMMON_EXPORT virtual const char *getRootTypename() = 0;
00193 COMMON_EXPORT static void enableSerialize(std::string, std::string, bool);
00194 COMMON_EXPORT static void enableDeserialize(std::string, std::string, bool);
00195 COMMON_EXPORT static void enforceDeserialize(std::string, std::string, bool);
00196 COMMON_EXPORT static void enableSerDes(std::string, std::string, bool);
00197 COMMON_EXPORT void enableSerialize(bool);
00198 COMMON_EXPORT void enableDeserialize(bool);
00199 COMMON_EXPORT void enforceDeserialize(bool);
00200 COMMON_EXPORT void enableSerDes(bool);
00201
00202 COMMON_EXPORT bool serializeEnabled();
00203 COMMON_EXPORT bool deserializeEnabled();
00204 COMMON_EXPORT static bool deserializeEnforced(std::string, std::string);
00205 COMMON_EXPORT bool deserializeEnforced();
00206
00207 COMMON_EXPORT std::string getSerFileName();
00208 COMMON_EXPORT virtual bool isContextType(Serializable *) = 0;
00209 };
00210
00211 template <class T>
00212 class SerContext : public SerContextBase
00213 {
00214 T *scope;
00215
00216 public:
00217
00218 SerContext(T *scope_, std::string fname) : SerContextBase(std::string(typeid(T).name()), fname), scope(scope_) {}
00219 ~SerContext() {}
00220 void *getVoidContext() {return (void *) scope;}
00221 const char *getRootTypename() {return typeid(T).name();}
00222 T *getScope() {return scope;}
00223 bool isContextType(Serializable *s) { return (NULL != dynamic_cast<T *>(s));}
00224 };
00225
00226 class SerFile;
00227 class SerDes;
00228
00229 class SerializerBase {
00230 friend class Serializable;
00231
00232 public:
00233 COMMON_EXPORT static std::vector<SerializerBase *> active_serializers;
00234
00235 static bool global_disable;
00236 private:
00237
00238 SerFile *sf;
00239 SerDes *sd;
00240 SerContextBase *scon;
00241 unsigned short ser_index;
00242
00243 std::string serializer_name;
00244
00245 typedef dyn_hash_map<std::string, SerializerBase *> subsystem_serializers_t;
00246 COMMON_EXPORT static dyn_hash_map<std::string, subsystem_serializers_t> all_serializers;
00247
00248 dyn_hash_map<void *, AnnotatableSparse *> *sparse_annotatable_map;
00249 dyn_hash_map<void *, AnnotatableDense *> *dense_annotatable_map;
00250 void clearAnnotationMaps();
00251 public:
00252 COMMON_EXPORT void set_annotatable_sparse_map(AnnotatableSparse *, void *);
00253 COMMON_EXPORT void set_annotatable_dense_map(AnnotatableDense *, void *);
00254 COMMON_EXPORT unsigned short getIndex();
00255 COMMON_EXPORT static void globalDisable();
00256 COMMON_EXPORT static bool serializationDisabled();
00257 COMMON_EXPORT static void globalEnable();
00258
00259 COMMON_EXPORT virtual bool isXML() = 0;
00260 COMMON_EXPORT virtual bool isBin ()= 0;
00261 COMMON_EXPORT bool isEOF();
00262
00263 COMMON_EXPORT SerContextBase *getContext();
00264 COMMON_EXPORT bool isInput ();
00265 COMMON_EXPORT bool isOutput ();
00266 COMMON_EXPORT AnnotatableSparse *findSparseAnnotatable(void *id);
00267 COMMON_EXPORT AnnotatableDense *findDenseAnnotatable(void *id);
00268
00269 COMMON_EXPORT static void dumpActiveBinSerializers();
00270
00271 COMMON_EXPORT SerializerBase(SerContextBase *scb, std::string name_, std::string filename, iomode_t dir, bool verbose);
00272 COMMON_EXPORT SerializerBase();
00273
00274 COMMON_EXPORT virtual ~SerializerBase();
00275
00276 COMMON_EXPORT virtual SerDes &getSD();
00277 COMMON_EXPORT SerFile &getSF();
00278 COMMON_EXPORT std::string &name() {return serializer_name;}
00279 COMMON_EXPORT static SerializerBase *getSerializer(std::string subsystem, std::string fname);
00280 COMMON_EXPORT static bool addSerializer(std::string subsystem, std::string fname, SerializerBase *sb);
00281 COMMON_EXPORT static bool removeSerializer(unsigned short);
00282 COMMON_EXPORT virtual void vector_start(unsigned long &, const char * = NULL);
00283 COMMON_EXPORT virtual void vector_end();
00284 COMMON_EXPORT virtual void hash_map_start(unsigned long &size, const char *tag = NULL);
00285 COMMON_EXPORT virtual void hash_map_end();
00286 COMMON_EXPORT virtual void multimap_start(unsigned long &size, const char *tag = NULL);
00287 COMMON_EXPORT virtual void multimap_end();
00288 COMMON_EXPORT virtual void pair_start(const char *tag = NULL);
00289 COMMON_EXPORT virtual void pair_end();
00290 COMMON_EXPORT virtual void annotation_start(AnnotationClassID &a_id, void *&lparent_id, sparse_or_dense_anno_t &lsod, const char *);
00291 COMMON_EXPORT virtual void annotation_end();
00292 COMMON_EXPORT virtual void annotation_container_start(void *&id);
00293 COMMON_EXPORT virtual void annotation_container_end();
00294 COMMON_EXPORT virtual void annotation_container_item_start(void *&id);
00295 COMMON_EXPORT virtual void annotation_container_item_end();
00296 COMMON_EXPORT void translate_base(bool &v, const char *&t);
00297 COMMON_EXPORT void translate_base(short &v, const char *&t);
00298 COMMON_EXPORT void translate_base(unsigned short &v, const char *&t);
00299 COMMON_EXPORT void translate_base(char &v, const char *&t);
00300 COMMON_EXPORT void translate_base(int &v, const char *&t);
00301 COMMON_EXPORT void translate_base(unsigned int &v, const char *&t);
00302 COMMON_EXPORT void translate_base(unsigned long &v, const char *&t);
00303 COMMON_EXPORT void translate_base(long &v, const char *&t);
00304 COMMON_EXPORT void translate_base(float &v, const char *&t);
00305 COMMON_EXPORT void translate_base(double &v, const char *&t);
00306 COMMON_EXPORT void translate_base(const char * &v, int bufsize, const char *&t);
00307 COMMON_EXPORT void translate_base(char * &v, int bufsize, const char *&t);
00308 COMMON_EXPORT void translate_base(void * &v, const char *&t);
00309 COMMON_EXPORT void translate_base(std::string &v, const char *t);
00310 COMMON_EXPORT virtual void magic_check(const char *file__, unsigned int line__);
00311
00312 COMMON_EXPORT virtual iomode_t iomode();
00313
00314 COMMON_EXPORT void serialize_annotations(void *, std::vector<ser_rec_t> &sers, const char * = NULL);
00315 COMMON_EXPORT bool serialize_post_annotation(void *parent_id, void *anno, AnnotationClassBase *acb, sparse_or_dense_anno_t , const char * = NULL);
00316 };
00317
00318 SerializerBase *createSerializer(SerContextBase *, std::string, std::string, ser_type_t, iomode_t, bool = false);
00319
00320 class AnnotatableSparse;
00321 class AnnotatableDense;
00322 class AnnotationContainerBase;
00323
00324 COMMON_EXPORT void serialize_annotatable_id(SerializerBase *sb, void *&id, const char *tag);
00325 COMMON_EXPORT bool set_sb_annotatable_sparse_map(SerializerBase *, AnnotatableSparse *, void *);
00326 COMMON_EXPORT bool set_sb_annotatable_dense_map(SerializerBase *, AnnotatableDense *, void *);
00327 COMMON_EXPORT unsigned short get_serializer_index(SerializerBase *sb);
00328 COMMON_EXPORT void annotation_start(SerializerBase *, AnnotationClassID &, void *&, sparse_or_dense_anno_t &, const char *);
00329 COMMON_EXPORT void annotation_end(SerializerBase *);
00330 COMMON_EXPORT AnnotatableSparse *find_sparse_annotatable(SerializerBase *, void *);
00331 COMMON_EXPORT AnnotatableDense *find_dense_annotatable(SerializerBase *, void *);
00332 COMMON_EXPORT bool isEOF(SerializerBase *);
00333 COMMON_EXPORT void throw_ser_err(const char *file__, unsigned int line, const char *msg);
00334
00335
00336 COMMON_EXPORT void annotation_container_start(SerializerBase *sb, void *&id);
00337 COMMON_EXPORT void annotation_container_end(SerializerBase *sb);
00338 COMMON_EXPORT void annotation_container_item_start(SerializerBase *, void *&);
00339 COMMON_EXPORT void annotation_container_item_end(SerializerBase *);
00340 COMMON_EXPORT bool deserialize_container_item(SerializerBase *, void *);
00341 COMMON_EXPORT AnnotationContainerBase *get_container(void *);
00342 COMMON_EXPORT bool deserialize_container_item(AnnotationContainerBase *acb, SerializerBase *sb);
00343
00344 template <class T>
00345 void enableSerialize(std::string fname, bool val)
00346 {
00347 serialize_printf("%s[%d]: %s serialize for type %s\n",
00348 FILE__, __LINE__, val ? "enabling" : "disabling", typeid(T).name());
00349 SerContextBase::enableSerialize(std::string(typeid(T).name()), fname, val);
00350 }
00351
00352 template <class T>
00353 void enableDeserialize(std::string fname, bool val)
00354 {
00355 serialize_printf("%s[%d]: %s deserialize for type %s\n",
00356 FILE__, __LINE__, val ? "enabling" : "disabling", typeid(T).name());
00357 SerContextBase::enableDeserialize(std::string(typeid(T).name()), fname, val);
00358 }
00359
00360 template <class T>
00361 void enforceDeserialize(std::string fname, bool val)
00362 {
00363 serialize_printf("%s[%d]: %s enforced deserialize for type %s\n",
00364 FILE__, __LINE__, val ? "enabling" : "disabling", typeid(T).name());
00365 SerContextBase::enforceDeserialize(std::string(typeid(T).name()), fname, val);
00366 }
00367
00368 template <class T>
00369 bool deserializeEnforced(std::string fname)
00370 {
00371 return SerContextBase::deserializeEnforced(std::string(typeid(T).name()), fname);
00372 }
00373
00374 template <class T>
00375 void enableSerDes(std::string fname, bool val)
00376 {
00377 serialize_printf("%s[%d]: %s serialize/deserialize for type %s\n",
00378 FILE__, __LINE__, val ? "enabling" : "disabling", typeid(T).name());
00379 SerContextBase::enableSerDes(std::string(typeid(T).name()), fname, val);
00380 }
00381
00382 class Serializable {
00383 bool was_deserialized;
00384 static void clearContainersByID();
00385
00386 protected:
00387 unsigned short active_serializer_index;
00388
00389 COMMON_EXPORT Serializable() :
00390 was_deserialized(false),
00391 active_serializer_index((unsigned short) (-1)) {}
00392
00393 COMMON_EXPORT virtual ~Serializable()
00394 {
00395 if (active_serializer_index != (unsigned short) -1)
00396 {
00397 SerializerBase *sb = getExistingOutputSB(active_serializer_index);
00398 if (sb)
00399 {
00400 SerContextBase *scb = sb->getContext();
00401 if (scb->isContextType(this))
00402 {
00403
00404 fprintf(stderr, "%s[%d]: TOP LEVEL SERIALIZE DONE: removing serializer\n", FILE__, __LINE__);
00405 sb->removeSerializer(active_serializer_index);
00406 }
00407 }
00408 }
00409 }
00410
00411 COMMON_EXPORT virtual Serializable *serialize_impl(SerializerBase *, const char * = NULL) THROW_SPEC(SerializerError) = 0;
00412
00413 public:
00414
00415 COMMON_EXPORT unsigned short getID() {return active_serializer_index;}
00416
00417 COMMON_EXPORT bool serialize(std::string filename, SerContextBase *scb, ser_type_t);
00418
00419 COMMON_EXPORT bool deserialize(std::string filename, SerContextBase *scb)
00420 {
00421 std::string sername = std::string("Deserializer");
00422
00423 SerializerBase *serializer = createSerializer(scb, sername, filename,
00424 ser_bin, sd_deserialize, false);
00425
00426 if (!serializer)
00427 {
00428 serialize_printf("%s[%d]: ERROR: failed to create deserializer for %s\n",
00429 FILE__, __LINE__, filename.c_str());
00430 clearContainersByID();
00431 return false;
00432 }
00433
00434 try
00435 {
00436
00437 serialize(serializer, NULL);
00438 }
00439 catch (const SerializerError &err_)
00440 {
00441 serialize_printf("%s[%d]: deserialize failed\n", FILE__, __LINE__);
00442 printSerErr(err_);
00443 serializer->clearAnnotationMaps();
00444 clearContainersByID();
00445 return false;
00446 }
00447 catch (...)
00448 {
00449 serialize_printf("%s[%d]: caught unexpected exception\n", FILE__, __LINE__);
00450 serializer->clearAnnotationMaps();
00451 clearContainersByID();
00452 return false;
00453 }
00454
00455 void *barrier_magic = (void *) 0xdeadbeef;
00456 serialize_annotatable_id(serializer, barrier_magic, NULL);
00457
00458 if (barrier_magic != (void *)0xdeadbeef)
00459 {
00460 fprintf(stderr, "%s[%d]: FIXME: failed to read magic barrier\n", FILE__, __LINE__);
00461 }
00462
00463 unsigned op_count = 0;
00464 while (1)
00465 {
00466 try
00467 {
00468 void *my_anno = NULL;
00469 void *parent_id = NULL;
00470 ser_post_op_t op = sp_add_anno;
00471 AnnotationClassBase *acb = NULL;
00472 sparse_or_dense_anno_t sod = sparse;
00473 AnnotationClassID a_id = 0;
00474
00475 serializer_printf("%s[%d]: reading post-serialize item %d\n",
00476 FILE__, __LINE__, op_count);
00477
00478 if (!ser_operation(serializer, op, NULL))
00479 {
00480 if (isEOF(serializer))
00481 {
00482 serialize_printf("%s[%d]: got EOF\n", FILE__, __LINE__);
00483 serializer->clearAnnotationMaps();
00484 clearContainersByID();
00485 return true;
00486 }
00487 }
00488 switch (op) {
00489 case sp_add_anno:
00490 {
00491 annotation_start(serializer, a_id, parent_id, sod, NULL);
00492 acb = AnnotationClassBase::findAnnotationClass(a_id);
00493 if (!acb)
00494 {
00495 fprintf(stderr, "%s[%d]: failed to find annotation type %d\n",
00496 FILE__, __LINE__, a_id);
00497 serializer->clearAnnotationMaps();
00498 clearContainersByID();
00499 return false;
00500 }
00501 else
00502 {
00503 serializer_printf("%s[%d]: found annotation id %d/%d\n",
00504 FILE__, __LINE__, acb->getID(), a_id);
00505 }
00506
00507 my_anno = acb->allocate();
00508 assert(my_anno);
00509
00510 ser_func_t sf = acb->getSerializeFunc();
00511 if (!sf)
00512 {
00513 fprintf(stderr, "%s[%d]: failed to find serialization function\n",
00514 FILE__, __LINE__);
00515 serializer->clearAnnotationMaps();
00516 clearContainersByID();
00517 return false;
00518 }
00519
00520
00521 serializer_printf("%s[%d]: calling serialize func for type %s\n",
00522 FILE__, __LINE__, acb->getTypeName());
00523
00524 (*sf)(my_anno, serializer, NULL);
00525
00526 serializer_printf("%s[%d]: called serialize func for type %s\n",
00527 FILE__, __LINE__, acb->getTypeName());
00528
00529 annotation_end(serializer);
00530
00531
00532
00533
00534
00535
00536 if (sparse == sod)
00537 {
00538 AnnotatableSparse *as = find_sparse_annotatable(serializer, parent_id);
00539 if (NULL == as)
00540 {
00541 fprintf(stderr, "%s[%d]: ERROR: cannot find anno parent id %p for anno of type %s\n",
00542 FILE__, __LINE__, parent_id, acb->getTypeName());
00543 }
00544 else
00545 {
00546 assert(acb);
00547
00548 if (!as->addAnnotation(my_anno, acb->getID()))
00549 {
00550 fprintf(stderr, "%s[%d]: ERROR: failed to add annotation here\n",
00551 FILE__, __LINE__);
00552 }
00553
00554
00555
00556
00557
00558 }
00559 }
00560 else if (dense == sod)
00561 {
00562 AnnotatableDense *ad = find_dense_annotatable(serializer, parent_id);
00563 if (NULL == ad)
00564 {
00565 fprintf(stderr, "%s[%d]: ERROR: cannot find anno parent id = %p\n",
00566 FILE__, __LINE__, (void *) parent_id);
00567 }
00568 else
00569 {
00570 assert(acb);
00571 serializer_printf("%s[%d]: reading post annotation\n",
00572 FILE__, __LINE__);
00573 if (!ad->addAnnotation(my_anno, acb->getID()))
00574 {
00575 fprintf(stderr, "%s[%d]: ERROR: failed to add annotation here\n",
00576 FILE__, __LINE__);
00577 }
00578 }
00579 }
00580 else
00581 {
00582 fprintf(stderr, "%s[%d]: ERROR: sparse/dense not set properly\n",
00583 FILE__, __LINE__);
00584 serializer->clearAnnotationMaps();
00585 clearContainersByID();
00586 return false;
00587 }
00588 break;
00589 }
00590 case sp_rem_anno:
00591 {
00592 fprintf(stderr, "%s[%d]: FIXME: not implemented\n", FILE__, __LINE__);
00593 break;
00594 }
00595 case sp_add_cont_item:
00596 {
00597 void *parent_id = NULL;
00598 annotation_container_item_start(serializer, parent_id);
00599 if (!parent_id)
00600 {
00601 fprintf(stderr, "%s[%d]: NULL container with id\n",
00602 FILE__, __LINE__);
00603 serializer->clearAnnotationMaps();
00604 clearContainersByID();
00605 return false;
00606 }
00607
00608 if (!deserialize_container_item(serializer, parent_id))
00609 {
00610 fprintf(stderr, "%s[%d]: failed deser contitem w/parent %p\n",
00611 FILE__, __LINE__, parent_id);
00612 serializer->clearAnnotationMaps();
00613 clearContainersByID();
00614 return false;
00615 }
00616
00617 annotation_container_item_end(serializer);
00618 break;
00619 }
00620 case sp_rem_cont_item:
00621 {
00622 fprintf(stderr, "%s[%d]: FIXME: not implemented\n",
00623 FILE__, __LINE__);
00624 break;
00625 }
00626 default:
00627 fprintf(stderr, "%s[%d]: ERROR: bad ser operation %d\n",
00628 FILE__, __LINE__, op);
00629 serializer->clearAnnotationMaps();
00630 clearContainersByID();
00631 return false;
00632 };
00633
00634 if (isEOF(serializer))
00635 {
00636 fprintf(stderr, "%s[%d]: got EOF\n", FILE__, __LINE__);
00637 serializer->clearAnnotationMaps();
00638 clearContainersByID();
00639 return true;
00640 }
00641
00642 }
00643 catch (const Dyninst::SerializerError &err_)
00644 {
00645 if (isEOF(serializer))
00646 {
00647 serialize_printf("%s[%d]: got EOF\n", FILE__, __LINE__);
00648 serializer->clearAnnotationMaps();
00649 clearContainersByID();
00650 return true;
00651 }
00652 if (serializer_debug_flag())
00653 {
00654 fprintf(stderr, "%s[%d]: deserialize caught exception\n", FILE__, __LINE__);
00655 printSerErr(err_);
00656 }
00657 serializer->clearAnnotationMaps();
00658 clearContainersByID();
00659 return false;
00660 }
00661 catch (...)
00662 {
00663 serialize_printf("%s[%d]: caught unknown exception\n", FILE__, __LINE__);
00664 if (isEOF(serializer))
00665 {
00666 serialize_printf("%s[%d]: got EOF\n", FILE__, __LINE__);
00667 serializer->clearAnnotationMaps();
00668 clearContainersByID();
00669 return true;
00670 }
00671 serializer->clearAnnotationMaps();
00672 clearContainersByID();
00673 return false;
00674 }
00675 op_count++;
00676 }
00677
00678 serializer->clearAnnotationMaps();
00679 clearContainersByID();
00680 return true;
00681 }
00682
00683 COMMON_EXPORT SerializerBase *lookupExistingSerializer();
00684 COMMON_EXPORT bool from_cache() {return was_deserialized;}
00685
00686 COMMON_EXPORT virtual Serializable *serialize(SerializerBase *sb,
00687 const char *tag = NULL) THROW_SPEC(SerializerError)
00688 {
00689
00690
00691
00692
00693
00694
00695
00696 sb->magic_check(FILE__, __LINE__);
00697 Serializable *res = serialize_impl(sb, tag);
00698 sb->magic_check(FILE__, __LINE__);
00699
00700
00701 void *id = this;
00702
00703 AnnotatableSparse *as = dynamic_cast<AnnotatableSparse *> (this);
00704 if (as)
00705 {
00706 id = as;
00707
00708
00709
00710
00711 sb->magic_check(FILE__, __LINE__);
00712 serialize_annotatable_id(sb, id, "SparseAnnotatableObjectID");
00713 sb->magic_check(FILE__, __LINE__);
00714
00715 if (is_input(sb))
00716 {
00717 if (NULL != id)
00718 {
00719 if (!set_sb_annotatable_sparse_map(sb, as, id))
00720 {
00721 fprintf(stderr, "%s[%d]: failed to set annotatable-anno mapping here\n",
00722 FILE__, __LINE__);
00723 }
00724 }
00725 else
00726 fprintf(stderr, "%s[%d]: ERROR: id is NULL\n", FILE__, __LINE__);
00727 }
00728
00729 if (is_output(sb))
00730 serialize_printf("%s[%d]: set anno mapping for %p\n", FILE__, __LINE__, id);
00731
00732 sb->magic_check(FILE__, __LINE__);
00733 as->serializeAnnotations(sb, tag);
00734 sb->magic_check(FILE__, __LINE__);
00735 }
00736 else
00737 {
00738 AnnotatableDense *ad = dynamic_cast<AnnotatableDense *> (this);
00739 if (ad)
00740 {
00741
00742
00743
00744 id = ad;
00745 sb->magic_check(FILE__, __LINE__);
00746 serialize_annotatable_id(sb, id, "DenseAnnotatableObjectID");
00747 sb->magic_check(FILE__, __LINE__);
00748
00749 serialize_printf("%s[%d]: %sserializing annotatable id %p, this = %p\n",
00750 FILE__, __LINE__, is_output(sb) ? "": "de", id, this);
00751
00752 if (is_input(sb))
00753 {
00754 if (NULL != id)
00755 {
00756
00757
00758 if (!set_sb_annotatable_dense_map(sb, ad, id))
00759 {
00760 fprintf(stderr, "%s[%d]: failed to set annotatable-annotation map\n",
00761 FILE__, __LINE__);
00762 }
00763
00764 serialize_printf("%s[%d]: set dense annotatable mapping for id %p\n",
00765 FILE__, __LINE__, (void *)id);
00766 }
00767 else
00768 fprintf(stderr, "%s[%d]: got NULL id in deserialize\n", FILE__, __LINE__);
00769 }
00770
00771 sb->magic_check(FILE__, __LINE__);
00772 ad->serializeAnnotations(sb, tag);
00773 sb->magic_check(FILE__, __LINE__);
00774 }
00775 else
00776 {
00777 serialize_printf("%s[%d]: class %s is not annotatable\n",
00778 FILE__, __LINE__, typeid(this).name());
00779 }
00780 }
00781
00782 if (is_input(sb))
00783 was_deserialized = true;
00784
00785 active_serializer_index = get_serializer_index(sb);
00786
00787 return res;
00788 }
00789 };
00790
00791
00792 class AnnotationContainerBase : public Serializable
00793 {
00794 friend class Serializable;
00795 friend COMMON_EXPORT bool deserialize_container_item(SerializerBase *, void *);
00796 friend COMMON_EXPORT bool deserialize_container_item(AnnotationContainerBase *, SerializerBase *);
00797
00798 protected:
00799 static dyn_hash_map<void *, AnnotationContainerBase *> containers_by_id;
00800 COMMON_EXPORT static void clearContainersByID();
00801
00802 COMMON_EXPORT AnnotationContainerBase() {}
00803 COMMON_EXPORT virtual ~AnnotationContainerBase() {}
00804 COMMON_EXPORT virtual bool deserialize_item(SerializerBase *) = 0;
00805
00806 public:
00807
00808 COMMON_EXPORT virtual Serializable *ac_serialize_impl(SerializerBase *,
00809 const char * = NULL) THROW_SPEC(SerializerError) = 0;
00810
00811 COMMON_EXPORT virtual Serializable *serialize_impl(SerializerBase *sb,
00812 const char *tag = NULL) THROW_SPEC(SerializerError)
00813 {
00814 void *id = this;
00815 annotation_container_start(sb, id);
00816
00817
00818 Serializable *res = ac_serialize_impl(sb, tag);
00819 annotation_container_end(sb);
00820
00821 if (is_input(sb))
00822 {
00823
00824 containers_by_id[id] = this;
00825 }
00826 annotatable_printf("%s[%d]: %s AnnotationContainer(%p) of type %s, id = %p\n",
00827 FILE__, __LINE__, is_input(sb) ? "deserialized" : "serialized", this,
00828 getElementTypename(), id);
00829 return res;
00830 }
00831
00832 COMMON_EXPORT virtual const char *getElementTypename() = 0;
00833 COMMON_EXPORT static AnnotationContainerBase *getContainer(void *id)
00834 {
00835 dyn_hash_map<void *, AnnotationContainerBase *>::iterator iter;
00836
00837 iter = containers_by_id.find(id);
00838 if (iter == containers_by_id.end())
00839 {
00840 fprintf(stderr, "%s[%d]: ERROR: cannot find id %p in container-id map\n",
00841 FILE__, __LINE__, id);
00842 return NULL;
00843 }
00844
00845 return iter->second;
00846 }
00847
00848 COMMON_EXPORT static void setContainerID(AnnotationContainerBase *acb, void *id)
00849 {
00850
00851 containers_by_id[id] = acb;
00852 }
00853 };
00854
00855
00856 template <class T>
00857 Serializable *cont_ser_func_wrapper(void *it, SerializerBase *sb, const char *)
00858 {
00859 T *itt = (T*) it;
00860 gtranslate(sb, *itt);
00861 return NULL;
00862 }
00863
00864 #if 0
00865 template <class T, typename IS_POINTER, typename IS_SERIALIZABLE>
00866 class SerFuncExecutor
00867 {
00868 AnnotationClass<T> *ac;
00869
00870 public:
00871
00872 SerFuncExecutor(AnnotationClass<T> *ac_) : ac(ac_) {}
00873
00874 Serializable *operator()(T &my_item, SerializerBase *sb, const char *tag = NULL)
00875 {
00876 ser_func_t sf = ac->getSerializeFunc();
00877 assert(sf);
00878
00879 serialize_printf("%s[%d]: calling serialize func for type %s\n",
00880 FILE__, __LINE__, ac->getTypeName());
00881
00882 Serializable *res = (*sf)(&my_item, sb, tag);
00883 return res;
00884 }
00885 };
00886
00887 template <class T>
00888 class SerFuncExecutor<T, dyn_detail::boost::true_type, dyn_detail::boost::true_type>
00889 {
00890 AnnotationClass<T> *ac;
00891
00892 public:
00893
00894 SerFuncExecutor(AnnotationClass<T> *ac_) : ac(ac_) {}
00895
00896 void operator()(T &my_item, SerializerBase *sb, const char *tag = NULL)
00897 {
00898 ser_func_t sf = ac->getSerializeFunc();
00899 assert(sf);
00900
00901
00902 my_item = (T) ac->allocate();
00903 serialize_printf("%s[%d]: calling serialize func for type %s\n",
00904 FILE__, __LINE__, ac->getTypeName());
00905
00906 Serializable *sable = (*sf)(my_item, sb, tag);
00907
00908 T res = dynamic_cast<T>(sable);
00909
00910 if (sable && !res)
00911 {
00912 fprintf(stderr, "%s[%d]: ERROR: %s not Serializable ??\n",
00913 FILE__, __LINE__, typeid(T).name());
00914 }
00915
00916 if (res && (res != my_item))
00917 {
00918 fprintf(stderr, "%s[%d]: serialize func for %s did a realloc\n",
00919 FILE__, __LINE__, typeid(T).name());
00920 fprintf(stderr, "%s[%d]: REMOVED DELETE\n", FILE__, __LINE__);
00921 delete my_item;
00922 my_item = res;
00923 }
00924 serialize_printf("%s[%d]: called serialize func for type %s\n",
00925 FILE__, __LINE__, ac->getTypeName());
00926 }
00927 };
00928 #endif
00929
00930 template <class T>
00931 class AnnotationContainer : public AnnotationContainerBase
00932 {
00933 #if 0
00934
00935
00936
00937
00938
00939 AnnotationClass<T> *ac;
00940 #endif
00941
00942 virtual bool deserialize_item(SerializerBase *sb)
00943 {
00944 T my_item;
00945 if (dyn_detail::boost::is_pointer<T>::value)
00946 {
00947
00948 memset( &my_item, 0, sizeof(T));
00949 }
00950
00951 if (!sb)
00952 {
00953 fprintf(stderr, "%s[%d]: FIXME: bad param\n", FILE__, __LINE__);
00954 return false;
00955 }
00956 #if 0
00957 ser_func_t sf = ac->getSerializeFunc();
00958
00959 if (!sf)
00960 {
00961 fprintf(stderr, "%s[%d]: failed to find serialization function\n",
00962 FILE__, __LINE__);
00963 return false;
00964 }
00965
00966 SerFuncExecutor<T, typename dyn_detail::boost::is_pointer<T>::type,
00967 typename dyn_detail::boost::is_base_of<Serializable,
00968 typename dyn_detail::boost::remove_pointer<T>::type>::type>
00969 sfe(ac);
00970
00971 sfe(my_item, sb);
00972 #else
00973 gtranslate(sb, my_item);
00974 #endif
00975
00976 if (!addItem_impl(my_item))
00977 {
00978 fprintf(stderr, "%s[%d]: failed to addItem after deserialize\n", FILE__, __LINE__);
00979 return false;
00980 }
00981
00982 return true;
00983 }
00984
00985 public:
00986
00987
00988 AnnotationContainer()
00989 #if 0
00990 : ac(NULL)
00991 #endif
00992 {
00993 #if 0
00994 ser_func_t sf = NULL;
00995
00996 if (dyn_detail::boost::is_fundamental<T>::value)
00997 {
00998 sf = (ser_func_t) cont_ser_func_wrapper<T>;
00999 }
01000
01001 std::string aname = std::string(typeid(*this).name()) + std::string("_elem");
01002 ac = new AnnotationClass<T>(aname, NULL, sf);
01003 #endif
01004 }
01005
01006 ~AnnotationContainer()
01007 {}
01008
01009
01010
01011
01012 virtual bool addItem_impl(T t) = 0;
01013
01014 bool addItem(T t)
01015 {
01016 if (!addItem_impl(t))
01017 {
01018 fprintf(stderr, "%s[%d]: failed to add item of type %s to container\n",
01019 FILE__, __LINE__, typeid(T).name());
01020 return false;
01021 }
01022
01023
01024
01025 SerializerBase *sb = lookupExistingSerializer();
01026 if (sb)
01027 {
01028
01029 ser_post_op_t op = sp_add_cont_item;
01030 void *id = this;
01031 ser_operation(sb, op, NULL);
01032 annotation_container_item_start(sb, id);
01033 gtranslate(sb, t, NULL);
01034 annotation_container_item_end(sb);
01035 }
01036 return true;
01037 }
01038
01039 virtual const char *getElementTypename() {return typeid(T).name();}
01040
01041 virtual Serializable *ac_serialize_impl(SerializerBase *,
01042 const char *tag) THROW_SPEC(SerializerError) = 0;
01043 };
01044
01045 template <typename T>
01046 void translate_vector(SerializerBase *ser, std::vector<T> &vec,
01047 const char *tag = NULL, const char *elem_tag = NULL)
01048 {
01049 unsigned long nelem = 0UL;
01050
01051 if (ser->iomode() == sd_serialize)
01052 nelem = (unsigned long) vec.size();
01053
01054 ser->vector_start(nelem, tag);
01055
01056 if (ser->iomode() == sd_deserialize)
01057 {
01058 if (vec.size())
01059 throw_ser_err(FILE__, __LINE__,"nonempty vector used to create");
01060
01061
01062 serialize_printf("%s[%d]: about to resize vector to %lu\n",
01063 FILE__, __LINE__, nelem);
01064
01065 if (nelem)
01066 vec.resize(nelem);
01067 }
01068
01069 for (unsigned long i = 0; i < nelem; ++i)
01070 {
01071 gtranslate(ser, vec[i], elem_tag);
01072 #if 0
01073 if (ser->isOutput())
01074 gtranslate(ser, vec[i], elem_tag);
01075 else
01076 {
01077 T t;
01078 gtranslate(ser, t, elem_tag);
01079 vec.push_back(t);
01080 }
01081 #endif
01082 #if 0
01083 T t;
01084 if (ser->isOutput())
01085 t = vec[i];
01086
01087
01088 gtranslate(ser, t, elem_tag);
01089 if (ser->isInput())
01090 vec[i] = t;
01091 #endif
01092 }
01093
01094 ser->vector_end();
01095 }
01096
01097 template <typename K, typename V>
01098 void translate_pair(SerializerBase *ser, std::pair<K, V> &p,
01099 const char *tag = NULL, const char *tag2 = NULL)
01100 {
01101 ser->pair_start();
01102
01103 gtranslate(ser, p.first, tag);
01104 gtranslate(ser, p.second, tag2);
01105
01106 ser->pair_end();
01107 }
01108
01109 template <typename T, typename T2>
01110 struct pair_translator {
01111 void operator()(SerializerBase *ser, std::pair<T, T2> &p,
01112 const char *tag = NULL, const char *tag2 = NULL)
01113 {
01114 ser->pair_start();
01115
01116 gtranslate(ser, p.first, tag);
01117 gtranslate(ser, p.second, tag2);
01118
01119 ser->pair_end();
01120 }
01121 };
01122
01123 template <class S, class K, class V>
01124 void translate_dyn_hash_map(S *ser, dyn_hash_map<K, V> &map,
01125 const char *tag = NULL, const char *elem_tag = NULL)
01126 {
01127 serialize_printf("%s[%d]: welcome to translate_dyn_hash_map<%s, %s>, size = %ld\n",
01128 FILE__, __LINE__, typeid(K).name(), typeid(V).name(), map.size());
01129
01130 unsigned long nelem = 0UL;
01131 nelem = map.size();
01132 ser->hash_map_start(nelem, tag);
01133
01134 if (ser->iomode() == sd_deserialize)
01135 {
01136 if (map.size())
01137 throw_ser_err(FILE__, __LINE__,"nonempty vector used to create");
01138
01139 for (unsigned long i = 0UL; i < nelem; ++i)
01140 {
01141 typename dyn_hash_map<K, V>::value_type mapentry;
01142 gtranslate(ser, mapentry, elem_tag);
01143 map.insert(mapentry);
01144 }
01145 }
01146 else
01147 {
01148 assert (ser->iomode() == sd_serialize);
01149 typename dyn_hash_map<K, V>::iterator iter = map.begin();
01150 while (iter != map.end())
01151 {
01152 gtranslate(ser, *iter, elem_tag);
01153 iter++;
01154 }
01155 }
01156
01157 ser->hash_map_end();
01158
01159 serialize_printf("%s[%d]: leaving translate_dyn_hash_map<%s, %s>\n",
01160 FILE__, __LINE__, typeid(K).name(), typeid(V).name());
01161 }
01162
01163 template <class S, class K, class V>
01164 void translate_map(S *ser, std::map<K, V> &map,
01165 const char *tag = NULL, const char *elem_tag = NULL)
01166 {
01167 unsigned long nelem = 0UL;
01168 nelem = map.size();
01169 ser->map_start(nelem, tag);
01170
01171 if (ser->iomode() == sd_deserialize)
01172 {
01173 if (map.size())
01174 throw_ser_err(FILE__, __LINE__,"nonempty vector used to create");
01175
01176 typename std::map<K, V>::iterator lastentry = map.begin();
01177
01178 for (unsigned int i = 0; i < nelem; ++i)
01179 {
01180 K a_k;
01181 V a_v;
01182 gtranslate(ser, a_k, elem_tag);
01183 gtranslate(ser, a_v, elem_tag);
01184 map[a_k] = a_v;
01185 }
01186
01187 }
01188 else
01189 {
01190 assert (ser->iomode() == sd_serialize);
01191 typename std::map<K, V>::iterator iter = map.begin();
01192 while (iter != map.end())
01193 {
01194 K &a_k = const_cast<K &>(iter->first);
01195 V &a_v = const_cast<V &>(iter->second);
01196 gtranslate(ser, a_k, elem_tag);
01197 gtranslate(ser, a_v, elem_tag);
01198 iter++;
01199 }
01200 }
01201 ser->map_end();
01202 }
01203
01204 template <class K, class V, class L>
01205 struct multimap_translator
01206 {
01207 void operator()(SerializerBase *ser, std::multimap<K, V, L> &map,
01208 const char *tag = NULL, const char *elem_tag = NULL)
01209 {
01210 unsigned long nelem = 0UL;
01211 nelem = map.size();
01212 ser->multimap_start(nelem, tag);
01213
01214 if (ser->iomode() == sd_deserialize)
01215 {
01216 if (map.size())
01217 throw_ser_err(FILE__, __LINE__,"nonempty vector used to create");
01218
01219 typename std::multimap<K, V, L>::iterator lastentry = map.begin();
01220
01221 for (unsigned int i = 0; i < nelem; ++i)
01222 {
01223 typename std::multimap<K, V, L>::value_type mapentry;
01224 gtranslate(ser, mapentry, elem_tag);
01225
01226
01227
01228 lastentry = map.insert(lastentry, mapentry);
01229 }
01230
01231 }
01232 else
01233 {
01234 assert (ser->iomode() == sd_serialize);
01235 typename std::multimap<K, V, L>::iterator iter = map.begin();
01236 while (iter != map.end())
01237 {
01238 gtranslate(ser, *iter, elem_tag);
01239 iter++;
01240 }
01241 }
01242
01243 ser->multimap_end();
01244 }
01245 };
01246
01247 template <class K, class V, class L>
01248 void translate_multimap(SerializerBase *ser, std::multimap<K, V, L> &map,
01249 const char *tag = NULL, const char *elem_tag = NULL)
01250 {
01251 unsigned long nelem = 0UL;
01252 nelem = map.size();
01253 ser->multimap_start(nelem, tag);
01254
01255 if (ser->iomode() == sd_deserialize)
01256 {
01257 if (map.size())
01258 throw_ser_err(FILE__, __LINE__,"nonempty vector used to create");
01259
01260 typename std::multimap<K, V, L>::iterator lastentry = map.begin();
01261
01262 for (unsigned int i = 0; i < nelem; ++i)
01263 {
01264 typename std::multimap<K, V, L>::value_type mapentry;
01265 gtranslate(ser, mapentry, elem_tag);
01266
01267
01268
01269 lastentry = map.insert(lastentry, mapentry);
01270 }
01271
01272 }
01273 else
01274 {
01275 assert (ser->iomode() == sd_serialize);
01276 typename std::multimap<K, V, L>::iterator iter = map.begin();
01277 while (iter != map.end())
01278 {
01279 gtranslate(ser, *iter, elem_tag);
01280 iter++;
01281 }
01282 }
01283
01284 ser->multimap_end();
01285 }
01286
01287 template <class S, class K, class V>
01288 void translate_hash_map(S *ser, dyn_hash_map<K, V> &hash,
01289 const char *tag = NULL, const char *key_tag = NULL, const char *value_tag = NULL)
01290 {
01291 fprintf(stderr, "%s[%d]: welcome to translate_hash_map<%s, %s>()\n",
01292 __FILE__, __LINE__,
01293 typeid(K).name(), typeid(V).name());
01294
01295 unsigned long nelem = 0UL;
01296 nelem = hash.size();
01297 ser->hash_map_start(nelem, tag);
01298
01299 if (ser->iomode() == sd_serialize)
01300 {
01301 typename dyn_hash_map<K,V>::iterator iter = hash.begin();
01302
01303 while (iter != hash.end())
01304 {
01305 K k = iter->first;
01306 V v = iter->second;
01307 ser->translate_base(k, key_tag);
01308 ser->translate_base(v, value_tag);
01309 iter++;
01310 }
01311 }
01312 else
01313 {
01314
01315 for (unsigned long i = 0; i < nelem; ++i)
01316 {
01317 K k;
01318 V v;
01319
01320
01321 if (dyn_detail::boost::is_pointer<K>::value)
01322 memset(&k, 0, sizeof(K));
01323 if (dyn_detail::boost::is_pointer<V>::value)
01324 memset(&v, 0, sizeof(V));
01325 ser->translate_base(k, key_tag);
01326 ser->translate_base(v, value_tag);
01327 hash[k] = v;
01328 }
01329 }
01330
01331 ser->hash_map_end();
01332 }
01333
01334 COMMON_EXPORT bool isBinary(Dyninst::SerializerBase *ser);
01335 COMMON_EXPORT bool isOutput(Dyninst::SerializerBase *ser);
01336
01337 typedef void NOTYPE_T;
01338
01339 template<typename T, typename T2 = typename dyn_detail::boost::is_enum<T>::type,
01340 typename T3 = typename dyn_detail::boost::is_base_of<Serializable, T>::type>
01341 class trans_adaptor {
01342 public:
01343 trans_adaptor() {}
01344
01345 T * operator()(SerializerBase *ser, T & it,
01346 const char *tag = NULL, const char * = NULL)
01347 {
01348 ser->translate_base(it, tag);
01349 return ⁢
01350 }
01351 };
01352
01353 template <>
01354 class trans_adaptor<char *, dyn_detail::boost::false_type,
01355 dyn_detail::boost::false_type>
01356 {
01357 public:
01358 trans_adaptor() {}
01359
01360 char * * operator()(SerializerBase *ser, char * & it,
01361 const char *tag = NULL, const char * = NULL)
01362 {
01363 int len = it ? strlen(it) : 0;
01364 ser->translate_base(it, len, tag);
01365 return ⁢
01366 }
01367 };
01368
01369 template<typename T>
01370 class trans_adaptor<T, dyn_detail::boost::false_type,
01371 dyn_detail::boost::true_type>
01372 {
01373 public:
01374 trans_adaptor() {}
01375
01376 Serializable * operator()(SerializerBase *ser, T & it, const char *tag = NULL,
01377 const char * = NULL)
01378 {
01379
01380
01381 serialize_printf("%s[%d]: translating serializable: %s\n",
01382 FILE__, __LINE__, typeid(T).name());
01383
01384 it.serialize(ser, tag);
01385
01386 serialize_printf("%s[%d]: translated serializable: %s\n",
01387 FILE__, __LINE__, typeid(T).name());
01388
01389 return ⁢
01390 }
01391 };
01392
01393 template<typename T>
01394 class trans_adaptor<T, dyn_detail::boost::true_type,
01395 dyn_detail::boost::false_type>
01396 {
01397 public:
01398 trans_adaptor() {}
01399
01400 Serializable * operator()(SerializerBase *ser, T & it, const char *tag = NULL,
01401 const char * = NULL)
01402 {
01403
01404 if (sizeof(T) != sizeof(int))
01405 fprintf(stderr, "%s[%d]: enum size is %lu, not %lu\n",
01406 FILE__, __LINE__, sizeof(T), sizeof(int));
01407 int e_int = (int) it;
01408 ser->translate_base(e_int, tag);
01409 if (ser->isInput())
01410 it = (T) e_int;
01411 #if 0
01412
01413
01414 serialize_printf("%s[%d]: translating serializable: %s\n",
01415 FILE__, __LINE__, typeid(T).name());
01416
01417 it.serialize(ser, tag);
01418
01419 serialize_printf("%s[%d]: translated serializable: %s\n",
01420 FILE__, __LINE__, typeid(T).name());
01421 #endif
01422
01423 return NULL;
01424
01425 }
01426 };
01427
01428 #if 0
01429 template<typename T>
01430 class trans_adaptor<std::vector<T>, dyn_detail::boost::false_type,
01431 dyn_detail::boost::false_type>
01432 {
01433 public:
01434 trans_adaptor() {}
01435
01436 std::vector<T> * operator()(SerializerBase *ser, std::vector<T> &v,
01437 const char *tag = NULL, const char *tag2 = NULL)
01438 {
01439 translate_vector(ser, v, tag, tag2);
01440 return &v;
01441 }
01442 };
01443 #endif
01444
01445 template <typename T, bool = dyn_detail::boost::is_base_of<Serializable, typename dyn_detail::boost::remove_pointer<T>::type>::value>
01446 class deref_adaptor
01447 {
01448 public:
01449 deref_adaptor() {}
01450
01451 T * operator()(SerializerBase *sb, T &it,
01452 const char *tag = NULL, const char *tag2 = NULL)
01453 {
01454 trans_adaptor<T> ta;
01455 ta(sb, it, tag, tag2);
01456 return ⁢
01457 }
01458 };
01459
01460 template <typename T>
01461 class deref_adaptor<T, true>
01462 {
01463 public:
01464 deref_adaptor() {}
01465
01466 T * operator()(SerializerBase *sb, T *&it,
01467 const char *tag = NULL, const char *tag2 = NULL)
01468 {
01469
01470 if (!isOutput(sb))
01471 {
01472 it = new T();
01473 }
01474 gtranslate(sb, *it, tag, tag2);
01475 return it;
01476 }
01477 };
01478
01479 template <typename T, typename T2 = typename dyn_detail::boost::is_pointer<T>::type,
01480 typename T3 = typename dyn_detail::boost::is_base_of<Serializable,
01481 typename dyn_detail::boost::remove_pointer<T>::type>::type>
01482 class ptr_adaptor
01483 {
01484 public:
01485 ptr_adaptor() {}
01486
01487 T * operator()(SerializerBase *sb, T &it,
01488 const char *tag = NULL, const char *tag2 = NULL)
01489 {
01490 trans_adaptor<T> ta;
01491 ta(sb, it, tag, tag2);
01492 return ⁢
01493 }
01494 };
01495
01496 template <typename T>
01497 class ptr_adaptor<T, dyn_detail::boost::true_type, dyn_detail::boost::false_type>
01498 {
01499 typedef typename dyn_detail::boost::remove_pointer<T>::type pointed_to_t;
01500
01501 public:
01502 ptr_adaptor() {}
01503 T * operator()(SerializerBase *sb, T &it,
01504 const char *tag = NULL, const char *tag2 = NULL)
01505 {
01506 deref_adaptor<pointed_to_t> da;
01507 da(sb, it, tag, tag2);
01508 return ⁢
01509 }
01510 };
01511
01512 template <typename T>
01513 class ptr_adaptor<T, dyn_detail::boost::true_type, dyn_detail::boost::true_type>
01514 {
01515 typedef typename dyn_detail::boost::remove_pointer<T>::type pointed_to_t;
01516 public:
01517 ptr_adaptor() {}
01518 T * operator()(SerializerBase *sb, T &it,
01519 const char *tag = NULL, const char * = NULL)
01520 {
01521 if (!isOutput(sb))
01522 {
01523 if (it)
01524 fprintf(stderr, "%s[%d]: WARNING: allocating to non-null pointer: %s\n",
01525 FILE__, __LINE__, typeid(T).name());
01526 serialize_printf("%s[%d]: allocating new %s\n",
01527 FILE__, __LINE__, typeid(T).name());
01528
01529 it = new pointed_to_t();
01530 }
01531
01532 Serializable *res = NULL;
01533 res = it->serialize(sb, tag);
01534
01535 if (!isOutput(sb))
01536 {
01537 T res_typed = dynamic_cast<T>(res);
01538
01539 if (res && !res_typed)
01540 {
01541 fprintf(stderr, "%s[%d]: ERROR: ser func allocated bad type object! not %s\n",
01542 FILE__, __LINE__, typeid(T).name());
01543 }
01544
01545 if (res_typed && (res_typed != it))
01546 {
01547 serialize_printf("%s[%d]: serialize fn for %s reallocated object\n",
01548 FILE__, __LINE__, typeid(T).name());
01549 delete it;
01550 it = res_typed;
01551 }
01552 }
01553
01554 return ⁢
01555 }
01556 };
01557
01558
01559
01560 template <>
01561 class ptr_adaptor<char *, dyn_detail::boost::true_type, dyn_detail::boost::false_type>
01562 {
01563 public:
01564 ptr_adaptor() {}
01565 char * * operator()(SerializerBase *sb, char * &it,
01566 const char *tag = NULL, const char *tag2 = NULL)
01567 {
01568 trans_adaptor<char *> ta;
01569 ta(sb, it, tag, tag2);
01570 return ⁢
01571 }
01572 };
01573
01574 template <typename T, bool = dyn_detail::boost::is_const<T>::value>
01575 class const_adaptor
01576 {
01577 public:
01578 const_adaptor() {}
01579
01580 T *operator()(SerializerBase *sb, T &it,
01581 const char *tag = 0, const char *tag2 = 0)
01582 {
01583 ptr_adaptor<T> ta;
01584 T *itp = ta(sb, it, tag, tag2);
01585 return itp;
01586 }
01587 };
01588
01589 template <typename T>
01590 class const_adaptor<T, true>
01591 {
01592 typedef typename dyn_detail::boost::remove_cv<T>::type non_const_type;
01593
01594 public:
01595 const_adaptor() {}
01596
01597 T *operator()(SerializerBase *sb, T &it,
01598 const char *tag = 0, const char *tag2 = 0)
01599 {
01600 gtranslate(sb, const_cast<non_const_type &>(it), tag, tag2);
01601 return ⁢
01602 }
01603 };
01604
01605 template <typename T>
01606 void gtranslate(SerializerBase *ser, T &it,
01607 const char *tag = NULL, const char *tag2 = NULL)
01608 {
01609
01610
01611
01612
01613
01614 const_adaptor<T> ta;
01615 T *itp = ta(ser, it, tag, tag2);
01616
01617 if (!itp)
01618 {
01619 fprintf(stderr, "%s[%d]: translate adaptor failed to de/serialize\n",
01620 __FILE__, __LINE__);
01621 }
01622 }
01623
01624 template <typename T>
01625 void gtranslate(SerializerBase *ser, std::vector<T> &it,
01626 const char *tag = NULL, const char *tag2 = NULL)
01627 {
01628 translate_vector(ser, it, tag, tag2);
01629 }
01630
01631 template <typename T, typename T2>
01632 void gtranslate(SerializerBase *ser, std::pair<T, T2> &it,
01633 const char *tag = NULL, const char *tag2 = NULL)
01634 {
01635
01636 pair_translator<T, T2> pt;
01637 pt(ser, it, tag, tag2);
01638 }
01639
01640 template <typename K, typename V, typename L>
01641 void gtranslate(SerializerBase *ser, std::multimap<K, V, L> &it,
01642 const char *tag = NULL, const char *tag2 = NULL)
01643 {
01644 translate_multimap(ser, it, tag, tag2);
01645 }
01646
01647 template <typename K, typename V>
01648 void gtranslate(SerializerBase *ser, dyn_hash_map<K, V> &it,
01649 const char *tag = NULL, const char *tag2 = NULL)
01650 {
01651 translate_dyn_hash_map(ser, it, tag, tag2);
01652 }
01653
01654 COMMON_EXPORT bool ifxml_start_element(SerializerBase *sb, const char *tag);
01655 COMMON_EXPORT bool ifxml_end_element(SerializerBase *sb, const char * );
01656 COMMON_EXPORT bool sb_is_input(SerializerBase *sb);
01657 COMMON_EXPORT bool sb_is_output(SerializerBase *sb);
01658
01659 template <typename T>
01660 void gtranslate(SerializerBase *ser,
01661 T &it,
01662 const char * (*to_str_func)(T),
01663 const char *tag = NULL,
01664 const char * = NULL)
01665 {
01666 assert(ser);
01667 int enum_int = 0;
01668 enum_int = (int) it;
01669
01670 if (!isBinary(ser))
01671 {
01672 assert(isOutput(ser));
01673
01674
01675 const char *enum_tag = (*to_str_func)(it);
01676 std::string enum_tag_str(enum_tag);
01677 assert(enum_tag);
01678
01679 gtranslate(ser, enum_tag_str, tag, NULL);
01680 }
01681 else
01682 {
01683
01684
01685 gtranslate(ser, enum_int, tag, NULL);
01686 it = (T) enum_int;
01687 }
01688 }
01689
01690 template <typename T>
01691 bool gtranslate_w_err(SerializerBase *ser, T &it,
01692 const char *tag = NULL, const char *tag2 = NULL)
01693 {
01694 try
01695 {
01696 gtranslate(ser, it, tag, tag2);
01697 }
01698
01699 catch (const SerializerError &err_)
01700 {
01701 fprintf(stderr, "%s[%d]: gtranslate failed\n", __FILE__, __LINE__);
01702 printSerErr(err_);
01703 return false;
01704 }
01705 return true;
01706 }
01707
01708 }
01709
01710 #endif
01711
01712 #endif
01713