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 #ifndef __ANNOTATABLE_H__
00032 #define __ANNOTATABLE_H__
00033
00034 #if defined (MSC_VER)
00035 #define DYN_DETAIL_BOOST_NO_INTRINSIC_WCHAR_T 1
00036 #endif
00037 #include "dyntypes.h"
00038 #include <vector>
00039 #include <map>
00040 #include <typeinfo>
00041 #include <string>
00042 #include <string.h>
00043 #include <assert.h>
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 #include "Serialization.h"
00047 #include "util.h"
00048
00049 namespace Dyninst
00050 {
00051
00052
00053 class SerializerBase;
00054 class Serializable;
00055 typedef Serializable * (*ser_func_t) (void *, SerializerBase *, const char *);
00056
00057 #if !defined(SERIALIZATION_DISABLED)
00058 #define serialize_printf serializer_printf
00059 COMMON_EXPORT int serializer_printf(const char *format, ...);
00060 COMMON_EXPORT Serializable * ser_func_wrapper(void *it, SerializerBase *sb, const char *tag);
00061 #endif
00062 COMMON_EXPORT bool annotation_debug_flag();
00063 COMMON_EXPORT int annotatable_printf(const char *format, ...);
00064
00065 typedef unsigned short AnnotationClassID;
00066 typedef bool (*anno_cmp_func_t)(void *, void*);
00067
00068 extern int newAnnotationClass();
00069 extern bool void_ptr_cmp_func(void *, void *);
00070
00071 class AnnotationClassBase
00072 {
00073 friend class Serializable;
00074 private:
00075 static std::vector<AnnotationClassBase *> *annotation_types;
00076 static dyn_hash_map<std::string, AnnotationClassID> *annotation_ids_by_name;
00077 #if 0
00078 COMMON_EXPORT static void clearAnnotationIDMap();
00079 #endif
00080 anno_cmp_func_t cmp_func;
00081 AnnotationClassID id;
00082 std::string name;
00083
00084 protected:
00085
00086 ser_func_t serialize_func;
00087
00088 COMMON_EXPORT AnnotationClassBase(std::string n,
00089 anno_cmp_func_t cmp_func_ = NULL,
00090 ser_func_t sf_ = NULL);
00091
00092 COMMON_EXPORT virtual ~AnnotationClassBase();
00093
00094 public:
00095
00096 COMMON_EXPORT static AnnotationClassBase *findAnnotationClass(unsigned int id);
00097 COMMON_EXPORT static void dumpAnnotationClasses();
00098
00099 COMMON_EXPORT AnnotationClassID getID() { return id; }
00100 COMMON_EXPORT std::string &getName() {return name;}
00101 COMMON_EXPORT anno_cmp_func_t getCmpFunc() {return cmp_func;}
00102 COMMON_EXPORT ser_func_t getSerializeFunc() {return serialize_func;}
00103 COMMON_EXPORT virtual const char *getTypeName() = 0;
00104 COMMON_EXPORT virtual void *allocate() = 0;
00105 };
00106
00107 template <class T>
00108 class AnnotationClass : public AnnotationClassBase {
00109 public:
00110
00111 AnnotationClass(std::string n,
00112 anno_cmp_func_t cmp_func_ = NULL,
00113 ser_func_t s = NULL) :
00114 AnnotationClassBase(n, cmp_func_, s)
00115 {
00116 #if !defined(SERIALIZATION_DISABLED)
00117 if (NULL == s)
00118 {
00119
00120
00121
00122
00123 if (boost::is_base_of<Serializable, T>::value)
00124 {
00125 serialize_func = ser_func_wrapper;
00126 } else
00127 if (boost::is_pointer<T>::value)
00128 {
00129 if (boost::is_base_of<Serializable,
00130 typename boost::remove_pointer<T>::type>::value)
00131 {
00132 serialize_func = ser_func_wrapper;
00133 }
00134 }
00135 }
00136 #endif
00137 }
00138
00139 const char *getTypeName() { return typeid(T).name();}
00140 void *allocate()
00141 {
00142 return (void *) new T();
00143 }
00144
00145 size_t size() {return sizeof(T);}
00146 #if 0
00147 bool isSparselyAnnotatable();
00148 bool isDenselyAnnotatable();
00149 #endif
00150 };
00151
00152
00153 typedef enum {
00154 sparse,
00155 dense
00156 } sparse_or_dense_anno_t;
00157
00158 typedef struct {
00159 AnnotationClassBase *acb;
00160 void *data;
00161 void *parent_id;
00162 sparse_or_dense_anno_t sod;
00163 } ser_rec_t;
00164
00165 typedef enum {
00166 sp_add_anno = 2,
00167 sp_rem_anno = 3,
00168 sp_add_cont_item = 4,
00169 sp_rem_cont_item = 5
00170 } ser_post_op_t;
00171
00172 COMMON_EXPORT const char *serPostOp2Str(ser_post_op_t);
00173
00174
00175 class AnnotatableDense;
00176 class AnnotatableSparse;
00177 COMMON_EXPORT bool is_input(SerializerBase *sb);
00178 COMMON_EXPORT bool is_output(SerializerBase *sb);
00179 COMMON_EXPORT unsigned short get_serializer_index(SerializerBase *sb);
00180 COMMON_EXPORT bool ser_operation(SerializerBase *, ser_post_op_t &, const char *);
00181 COMMON_EXPORT bool add_annotations(SerializerBase *, AnnotatableDense *, std::vector<ser_rec_t> &);
00182 COMMON_EXPORT bool add_annotations(SerializerBase *, AnnotatableSparse *, std::vector<ser_rec_t> &);
00183 #if !defined(SERIALIZATION_DISABLED)
00184 COMMON_EXPORT bool serialize_annotation_list(void *, std::vector<ser_rec_t> &, SerializerBase *sb, const char *);
00185 COMMON_EXPORT SerializerBase *getExistingOutputSB(unsigned short);
00186 COMMON_EXPORT bool serialize_post_annotation(void *, void *, SerializerBase *, AnnotationClassBase *acb, sparse_or_dense_anno_t, const char *);
00187 #endif
00188
00189 class COMMON_EXPORT AnnotatableDense
00190 {
00191 friend COMMON_EXPORT bool add_annotations(SerializerBase *, AnnotatableDense *, std::vector<ser_rec_t> &);
00192 friend class SerializerBase;
00193 friend class Serializable;
00194 typedef void *anno_list_t;
00195
00196
00197
00198
00199
00200
00201
00202 private:
00203
00204 typedef anno_list_t anno_map_t;
00205
00206 struct aInfo {
00207 anno_map_t *data;
00208 AnnotationClassID max;
00209 unsigned short serializer_index;
00210 };
00211
00212 aInfo *annotations;
00213
00214
00215
00216
00217
00218 bool addAnnotation(const void *a, AnnotationClassID id)
00219 {
00220 if (annotation_debug_flag())
00221 {
00222 fprintf(stderr, "%s[%d]: Dense(%p) add %s-%d\n", FILE__, __LINE__, this,
00223 AnnotationClassBase::findAnnotationClass(id)
00224 ? AnnotationClassBase::findAnnotationClass(id)->getName().c_str()
00225 : "bad_anno_id", id);
00226 }
00227
00228 unsigned size = id + 1;
00229 if (!annotations)
00230 {
00231 annotations = (aInfo *) malloc(sizeof(aInfo));
00232 annotations->data = NULL;
00233 annotations->serializer_index = (unsigned short) -1;
00234 }
00235
00236
00237
00238
00239 if (annotations->data == NULL)
00240 {
00241 annotations->data = (anno_list_t *) calloc(sizeof(anno_list_t *), (size));
00242 annotations->max = size;
00243 for (unsigned i=0; i<size; i++)
00244 annotations->data[i] = NULL;
00245 }
00246 else if (id >= annotations->max)
00247 {
00248 int old_max = annotations->max;
00249 size = annotations->max * 2;
00250 annotations->max = size;
00251 annotations->data = (anno_list_t *) realloc(annotations->data, sizeof(anno_list_t *) * size);
00252 for (unsigned i=old_max; i<size; i++)
00253 annotations->data[i] = NULL;
00254 }
00255
00256 annotations->data[id] = const_cast<void *>(a);
00257
00258 return true;
00259 }
00260 public:
00261 AnnotatableDense() : annotations(NULL)
00262 {
00263 }
00264
00265 ~AnnotatableDense()
00266 {
00267 if (annotations)
00268 {
00269 if (annotations->data)
00270 free(annotations->data);
00271 free(annotations);
00272 }
00273 }
00274
00275 template<class T>
00276 bool addAnnotation(const T *a, AnnotationClass<T> &a_id)
00277 {
00278 if (annotation_debug_flag())
00279 {
00280 fprintf(stderr, "%s[%d]: Dense(%p): Add %s-%d, %s\n", FILE__, __LINE__,
00281 this, a_id.getName().c_str(), a_id.getID(), typeid(T).name());
00282 }
00283
00284 int id = a_id.getID();
00285 T *a_noconst = const_cast<T *>(a);
00286 bool ret = addAnnotation((void *)a_noconst, id);
00287 if (!ret)
00288 {
00289 fprintf(stderr, "%s[%d]: failed to add annotation\n", FILE__, __LINE__);
00290 return ret;
00291 }
00292
00293
00294 #if !defined(SERIALIZATION_DISABLED)
00295
00296
00297
00298 serialize_printf("%s[%d]: %p addAnnotation: serializer_index = %d\n",
00299 FILE__, __LINE__, this, annotations->serializer_index);
00300
00301 if (annotations && ( (unsigned short) -1 != annotations->serializer_index))
00302 {
00303 SerializerBase *sb = getExistingOutputSB(annotations->serializer_index);
00304 if (!sb)
00305 {
00306
00307 fprintf(stderr, "%s[%d]: FIXME: no existing serializer!\n", FILE__, __LINE__);
00308 return false;
00309 }
00310 ser_func_t sf = a_id.getSerializeFunc();
00311 if (sf)
00312 {
00313
00314
00315 ser_post_op_t op = sp_add_anno;
00316 ser_operation(sb, op, "AnnotationAdd");
00317 void * aa = (void *) const_cast<T *>(a);
00318 serialize_post_annotation(this, aa, sb, &a_id, dense, "PostAnnotation");
00319 }
00320 }
00321 #endif
00322
00323 return true;
00324 }
00325
00326
00327 template<class T>
00328 inline bool getAnnotation(T *&a, AnnotationClass<T> &a_id) const
00329 {
00330 if (!annotations)
00331 return false;
00332
00333 int id = a_id.getID();
00334
00335 if (id > annotations->max)
00336 {
00337 return false;
00338 }
00339
00340 a = (T *) annotations->data[id];
00341 if (!a) return false;
00342
00343 return true;
00344 }
00345
00346 template<class T>
00347 inline bool removeAnnotation(AnnotationClass<T> &a_id)
00348 {
00349 if (annotation_debug_flag())
00350 {
00351 fprintf(stderr, "%s[%d]: Dense(%p) remove %s-%d, %s\n", FILE__, __LINE__,
00352 this, a_id.getName().c_str(), a_id.getID(), a_id.getTypeName());
00353 }
00354
00355 if (!annotations) return false;
00356
00357 int id = a_id.getID();
00358 if (id > annotations->max)
00359 {
00360 return false;
00361 }
00362
00363 if (!annotations->data[id])
00364 return false;
00365
00366 annotations->data[id] = NULL;
00367
00368 return true;
00369 }
00370
00371 #if !defined(SERIALIZATION_DISABLED)
00372 void serializeAnnotations(SerializerBase *sb, const char *tag)
00373 {
00374 serialize_printf("%s[%d]: welcome to serializeAnotations:\n", FILE__, __LINE__);
00375
00376
00377
00378 std::vector<ser_rec_t> my_sers;
00379 if (is_output(sb))
00380 {
00381
00382
00383
00384
00385
00386
00387 if (annotations)
00388 {
00389 for (AnnotationClassID id = 0; id < annotations->max; ++id)
00390 {
00391 void *anno = annotations->data[id];
00392 if (anno)
00393 {
00394 AnnotationClassBase *acb = AnnotationClassBase::findAnnotationClass(id);
00395
00396 if (!acb)
00397 {
00398 fprintf(stderr, "%s[%d]: FIXME: no annotation class for id %d\n",
00399 FILE__, __LINE__, id);
00400 continue;
00401 }
00402
00403 ser_func_t sf = acb->getSerializeFunc();
00404
00405 if (NULL != sf)
00406 {
00407 ser_rec_t sr;
00408 sr.data = anno;
00409 sr.acb = acb;
00410 sr.parent_id = (void *) this;
00411 sr.sod = dense;
00412 my_sers.push_back(sr);
00413 }
00414 }
00415 }
00416
00417 annotations->serializer_index = get_serializer_index(sb);
00418 serialize_printf("%s[%d]: %p set serializer index to %d\n",
00419 FILE__, __LINE__, this, annotations->serializer_index);
00420 }
00421 else
00422 {
00423
00424 annotations = (aInfo *) malloc(sizeof(aInfo));
00425 annotations->data = NULL;
00426 annotations->max = 0;
00427 annotations->serializer_index = get_serializer_index(sb);
00428 serialize_printf("%s[%d]: %p set serializer index to %d\n",
00429 FILE__, __LINE__, this, annotations->serializer_index);
00430 }
00431 }
00432
00433 if (!serialize_annotation_list(this, my_sers, sb, tag))
00434 {
00435 fprintf(stderr, "%s[%d]: FIXME: failed to serialize annotation list\n",
00436 FILE__, __LINE__);
00437 }
00438 if (!add_annotations(sb, this, my_sers))
00439 {
00440 fprintf(stderr, "%s[%d]: failed to update annotation list after deserialize\n",
00441 FILE__, __LINE__);
00442 }
00443 }
00444 #else
00445 void serializeAnnotations(SerializerBase *, const char *) {
00446 }
00447 #endif
00448 void annotationsReport()
00449 {
00450 std::vector<AnnotationClassBase *> atypes;
00451 if (annotations && annotations->data)
00452 {
00453 for (unsigned int i = 0; i < annotations->max; ++i)
00454 {
00455 if (NULL != annotations->data[i])
00456 {
00457 AnnotationClassBase *acb = AnnotationClassBase::findAnnotationClass(i);
00458 if (!acb)
00459 {
00460 fprintf(stderr, "%s[%d]: ERROR: failed to find acb for %d\n",
00461 FILE__, __LINE__, i);
00462 continue;
00463 }
00464 else
00465 atypes.push_back(acb);
00466 }
00467 }
00468
00469 fprintf(stderr, "%s[%d]: Dense(%p): have %lu annotations\n",
00470 FILE__, __LINE__, this, (unsigned long) atypes.size());
00471
00472 for (unsigned int i = 0; i < atypes.size(); ++i)
00473 {
00474 fprintf(stderr, "\t%s-%d, %s\n", atypes[i]->getName().c_str(),
00475 atypes[i]->getID(), atypes[i]->getTypeName());
00476 }
00477 }
00478 }
00479 };
00480
00481 #define NON_STATIC_SPARSE_MAP 1
00482 #define AN_INLINE inline
00483
00484 class COMMON_EXPORT AnnotatableSparse
00485 {
00486 friend class SerializerBase;
00487 friend class Serializable;
00488 friend COMMON_EXPORT bool add_annotations(SerializerBase *,
00489 AnnotatableSparse *, std::vector<ser_rec_t> &);
00490
00491 public:
00492 struct void_ptr_hasher
00493 {
00494 size_t operator()(const void* a) const
00495 {
00496 return (size_t) a;
00497 }
00498 };
00499
00500 #if defined (_MSC_VER)
00501 typedef dyn_hash_map<void *, void *> annos_by_type_t;
00502 #pragma warning (push)
00503 #pragma warning (disable:4251)
00504 #else
00505 typedef dyn_hash_map<void *, void *, void_ptr_hasher> annos_by_type_t;
00506 #endif
00507
00508 typedef std::vector<annos_by_type_t *> annos_t;
00509
00510 ~AnnotatableSparse()
00511 {
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 unsigned int n = 0;
00523 for (unsigned int i = 0; i < getAnnos()->size(); ++i)
00524 {
00525 annos_by_type_t *abt = (*getAnnos())[i];
00526 if (!abt) continue;
00527
00528 annos_by_type_t::iterator iter = abt->find(this);
00529 if (iter != abt->end())
00530 {
00531 if (annotation_debug_flag())
00532 {
00533 fprintf(stderr, "%s[%d]: Sparse(%p) dtor remove %s-%d\n", FILE__, __LINE__,
00534 this, AnnotationClassBase::findAnnotationClass(i)
00535 ? AnnotationClassBase::findAnnotationClass(i)->getName().c_str()
00536 : "bad_anno_id", i);
00537 }
00538
00539 abt->erase(iter);
00540 n++;
00541
00542
00543
00544 annos_by_type_t::iterator iter2 = abt->find(this);
00545 if (iter2 != abt->end())
00546 fprintf(stderr, "%s[%d]: FIXME: REMOVE FAILED\n", FILE__, __LINE__);
00547 }
00548 }
00549 }
00550
00551 private:
00552
00553 #if defined (NON_STATIC_SPARSE_MAP)
00554
00555 #else
00556 static annos_t annos;
00557 #endif
00558 annos_t *getAnnos() const;
00559 static dyn_hash_map<void *, unsigned short> ser_ndx_map;
00560
00561 annos_by_type_t *getAnnosOfType(AnnotationClassID aid, bool do_create =false) const
00562 {
00563 annos_t &l_annos = *getAnnos();
00564 long nelems_to_create = aid - l_annos.size() + 1;
00565
00566 if (nelems_to_create > 0)
00567 {
00568 if (!do_create)
00569 {
00570 return NULL;
00571 }
00572
00573 while (nelems_to_create)
00574 {
00575 annos_by_type_t *newl = new annos_by_type_t();
00576 l_annos.push_back(newl);
00577 nelems_to_create--;
00578 }
00579 }
00580
00581 annos_by_type_t *abt = l_annos[aid];
00582
00583 return abt;
00584 }
00585
00586 template <class T>
00587 AN_INLINE annos_by_type_t *getAnnosOfType(AnnotationClass<T> &a_id, bool do_create =false) const
00588 {
00589 AnnotationClassID aid = a_id.getID();
00590
00591 return getAnnosOfType(aid, do_create);
00592 }
00593
00594
00595 void *getAnnosForObject(annos_by_type_t *abt,
00596 void *obj, bool do_create = false) const
00597 {
00598 assert(abt);
00599 assert(obj);
00600
00601 void *target = NULL;
00602
00603 annos_by_type_t::iterator iter = abt->find(obj);
00604
00605 if (iter == abt->end())
00606 {
00607 if (!do_create)
00608 {
00609 return NULL;
00610 }
00611
00612 (*abt)[obj] = target;
00613 }
00614 else
00615 {
00616 target = iter->second;
00617 }
00618
00619 return target;
00620 }
00621
00622
00623
00624 AN_INLINE bool addAnnotation(const void *a, AnnotationClassID aid)
00625 {
00626 if (annotation_debug_flag())
00627 {
00628 fprintf(stderr, "%s[%d]: Sparse(%p) add %s-%d void\n", FILE__, __LINE__, this,
00629 AnnotationClassBase::findAnnotationClass(aid)
00630 ? AnnotationClassBase::findAnnotationClass(aid)->getName().c_str()
00631 : "bad_anno_id", aid);
00632 }
00633
00634 void *obj = this;
00635 annos_by_type_t *abt = getAnnosOfType(aid, true );
00636 assert(abt);
00637
00638 annos_by_type_t::iterator iter = abt->find(obj);
00639 if (iter == abt->end())
00640 {
00641 (*abt)[obj] = const_cast<void *>(a);
00642 }
00643 else
00644 {
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654 if (a != iter->second)
00655 {
00656 annotatable_printf("%s[%d]: WEIRD: already have annotation of this type: %p, replacing with %p\n", FILE__, __LINE__, iter->second, a);
00657 iter->second = const_cast<void *>(a);
00658 }
00659
00660 return true;
00661 }
00662
00663 return true;
00664 }
00665
00666 public:
00667
00668 bool operator==(AnnotatableSparse &cmp)
00669 {
00670 annos_t &l_annos = *getAnnos();
00671 unsigned this_ntypes = l_annos.size();
00672 unsigned cmp_ntypes = cmp.getAnnos()->size();
00673 unsigned ntypes = (cmp_ntypes > this_ntypes) ? cmp_ntypes : this_ntypes;
00674
00675 for (unsigned int i = 0; i < ntypes; ++i)
00676 {
00677 if ((i >= cmp_ntypes) || (i >= this_ntypes))
00678 {
00679
00680
00681 break;
00682 }
00683
00684 annos_by_type_t *this_abt = l_annos[i];
00685 annos_by_type_t *cmp_abt = (*cmp.getAnnos())[i];
00686
00687 if (!this_abt)
00688 {
00689 fprintf(stderr, "%s[%d]: WEIRD: FIXME\n", FILE__, __LINE__);
00690 continue;
00691 }
00692
00693 if (!cmp_abt)
00694 {
00695 fprintf(stderr, "%s[%d]: WEIRD: FIXME\n", FILE__, __LINE__);
00696 continue;
00697 }
00698
00699 annos_by_type_t::iterator this_abt_iter = this_abt->find(this);
00700 annos_by_type_t::iterator cmp_abt_iter = cmp_abt->find(&cmp);
00701
00702
00703
00704
00705 if (this_abt_iter == this_abt->end())
00706 {
00707 if (cmp_abt_iter != cmp_abt->end())
00708 {
00709 return false;
00710 }
00711
00712
00713 continue;
00714 }
00715
00716 if ( (cmp_abt_iter == cmp_abt->end())
00717 && (this_abt_iter != this_abt->end()))
00718 {
00719 return false;
00720 }
00721
00722 AnnotationClassBase *acb = AnnotationClassBase::findAnnotationClass(i);
00723
00724 if (!acb)
00725 {
00726 return false;
00727 }
00728
00729
00730 anno_cmp_func_t cmpfunc = acb->getCmpFunc();
00731
00732 if (!cmpfunc)
00733 {
00734
00735
00736
00737 fprintf(stderr, "%s[%d]: no cmp func for anno id %d\n",
00738 FILE__, __LINE__, i);
00739 return false;
00740 }
00741
00742 void *arg1 = cmp_abt_iter->second;
00743 void *arg2 = this_abt_iter->second;
00744
00745 bool ret = (*cmpfunc)(arg1, arg2);
00746
00747 return ret;
00748 }
00749
00750 return true;
00751 }
00752
00753 template<class T>
00754 AN_INLINE bool addAnnotation(const T *a, AnnotationClass<T> &a_id)
00755 {
00756 annotatable_printf("%s[%d]: Sparse(%p): Add %s-%d, %s\n", FILE__, __LINE__,
00757 this, a_id.getName().c_str(), a_id.getID(), typeid(T).name());
00758 void *obj = this;
00759 annos_by_type_t *abt = getAnnosOfType(a_id, true );
00760 assert(abt);
00761
00762 annos_by_type_t::iterator iter = abt->find(obj);
00763 if (iter == abt->end())
00764 {
00765 (*abt)[obj] = (void *) const_cast<T *>(a);
00766 }
00767 else
00768 {
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778 if (iter->second != a)
00779 {
00780
00781 iter->second = (void *)const_cast<T *>(a);
00782 }
00783
00784 return true;
00785 }
00786
00787 #if !defined(SERIALIZATION_DISABLED)
00788 dyn_hash_map<void *, unsigned short>::iterator seriter;
00789 seriter = ser_ndx_map.find(this);
00790 if (seriter != ser_ndx_map.end())
00791 {
00792 if (seriter->second != (unsigned short) -1)
00793 {
00794 SerializerBase *sb = getExistingOutputSB(seriter->second);
00795 if (!sb)
00796 {
00797 fprintf(stderr, "%s[%d]: FIXME: no existing output SB\n",
00798 FILE__, __LINE__);
00799 return false;
00800 }
00801
00802 ser_func_t sf = a_id.getSerializeFunc();
00803 if (sf)
00804 {
00805 ser_post_op_t op = sp_add_anno;
00806 ser_operation(sb, op, "AnnotationAdd");
00807 void *aa = (void *) const_cast<T *>(a);
00808 serialize_post_annotation(this, aa, sb, &a_id, sparse, "PostAnnotation");
00809 }
00810 }
00811 }
00812 #endif
00813
00814 return true;
00815 }
00816
00817 template<class T>
00818 AN_INLINE bool getAnnotation(T *&a, AnnotationClass<T> &a_id) const
00819 {
00820 a = NULL;
00821
00822 annos_by_type_t *abt = getAnnosOfType(a_id, false );
00823
00824 if (!abt)
00825 {
00826 return false;
00827 }
00828
00829 AnnotatableSparse * this_noconst = const_cast<AnnotatableSparse *>(this);
00830 void *annos_for_object = getAnnosForObject(abt, (void *)this_noconst,
00831 false );
00832
00833 if (!annos_for_object)
00834 {
00835 return false;
00836 }
00837
00838 a = (T *)annos_for_object;
00839 return true;
00840 }
00841
00842 template<class T>
00843 inline bool removeAnnotation(AnnotationClass<T> &a_id)
00844 {
00845 if (annotation_debug_flag())
00846 {
00847 fprintf(stderr, "%s[%d]: Sparse(%p) remove %s-%d, %s\n", FILE__, __LINE__,
00848 this, a_id.getName().c_str(), a_id.getID(), typeid(T).name());
00849 }
00850
00851 void *obj = this;
00852 annos_by_type_t *abt = getAnnosOfType(a_id, false );
00853 assert(abt);
00854
00855 annos_by_type_t::iterator iter = abt->find(obj);
00856 if (iter == abt->end())
00857 {
00858
00859 return false;
00860 }
00861 else
00862 {
00863 abt->erase(iter);
00864 return true;
00865 }
00866 return false;
00867 }
00868
00869 void serializeAnnotations(SerializerBase *sb, const char *)
00870 {
00871 annos_t &l_annos = *getAnnos();
00872 std::vector<ser_rec_t> my_sers;
00873 void *obj = this;
00874 if (is_output(sb))
00875 {
00876 for (AnnotationClassID id = 0; id < l_annos.size(); ++id)
00877 {
00878 annos_by_type_t *abt = getAnnosOfType(id, false );
00879 if (NULL == abt) continue;
00880
00881 annos_by_type_t::iterator iter = abt->find(obj);
00882
00883 if (iter == abt->end())
00884 {
00885
00886 continue;
00887 }
00888
00889
00890
00891
00892 AnnotationClassBase *acb = AnnotationClassBase::findAnnotationClass(id);
00893 if (!acb)
00894 {
00895 fprintf(stderr, "%s[%d]: FIXME, cannot find annotation class base for id %d, mode = %s\n", FILE__, __LINE__, id, is_input(sb) ? "deserialize" : "serialize");
00896 continue;
00897 }
00898
00899 ser_func_t sf = acb->getSerializeFunc();
00900
00901 if (NULL == sf)
00902 {
00903 continue;
00904 }
00905
00906 ser_rec_t sr;
00907 sr.acb = acb;
00908 sr.data = iter->second;
00909 sr.parent_id = (void *) this;
00910 sr.sod = sparse;
00911 my_sers.push_back(sr);
00912 }
00913
00914 ser_ndx_map[this] = get_serializer_index(sb);
00915 }
00916
00917 #if !defined(SERIALIZATION_DISABLED)
00918 if (!serialize_annotation_list(this, my_sers, sb, tag))
00919 {
00920 fprintf(stderr, "%s[%d]: FIXME: failed to serialize annotation list\n",
00921 FILE__, __LINE__);
00922 }
00923 #endif
00924
00925 if (!add_annotations(sb, this, my_sers))
00926 {
00927 fprintf(stderr, "%s[%d]: failed to update annotation list after deserialize\n",
00928 FILE__, __LINE__);
00929 }
00930 }
00931
00932 void annotationsReport()
00933 {
00934 std::vector<AnnotationClassBase *> atypes;
00935 annos_t &l_annos = *getAnnos();
00936
00937 for (AnnotationClassID id = 0; id < l_annos.size(); ++id)
00938 {
00939 annos_by_type_t *abt = getAnnosOfType(id, false );
00940 if (NULL == abt) continue;
00941
00942 annos_by_type_t::iterator iter = abt->find(this);
00943
00944 if (iter == abt->end())
00945 {
00946
00947 continue;
00948 }
00949
00950 AnnotationClassBase *acb = AnnotationClassBase::findAnnotationClass(id);
00951 if (!acb)
00952 {
00953 fprintf(stderr, "%s[%d]: FIXME, cant find anno class base for id %d\n",
00954 FILE__, __LINE__, id);
00955 continue;
00956 }
00957 atypes.push_back(acb);
00958 }
00959
00960 fprintf(stderr, "%s[%d]: Sparse(%p): have %lu annos:\n", FILE__, __LINE__,
00961 this, (unsigned long) atypes.size());
00962 for (unsigned int i = 0; i < atypes.size(); ++i)
00963 {
00964 fprintf(stderr, "\t%s-%d, %s\n", atypes[i]->getName().c_str(),
00965 atypes[i]->getID(), atypes[i]->getTypeName());
00966 }
00967 }
00968
00969 };
00970
00971 }
00972
00973 #ifdef _MSC_VER
00974 #pragma warning(pop)
00975 #endif
00976
00977 #endif