serialize-bin.C

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 #include <stdio.h>
00032 #include <vector>
00033 
00034 #include "dynutil/h/dyntypes.h"
00035 #include "dynutil/h/Annotatable.h"
00036 #include "common/h/serialize.h"
00037 #include "common/h/Types.h"
00038 #include "common/h/headers.h"
00039 
00040 #if defined(SERIALIZATION_DISABLED)
00041 unsigned short Dyninst::get_serializer_index(Dyninst::SerializerBase *) {
00042   return 0;
00043 }
00044 
00045 
00046 #else
00047 
00048 using namespace Dyninst;
00049 
00050 //COMMON_EXPORT dyn_hash_map<Address, AnnotatableBase *> SerDesBin::annotatable_id_map;
00051 
00052 
00053 COMMON_EXPORT dyn_hash_map<std::string, SerializerBase::subsystem_serializers_t> SerializerBase::all_serializers;
00054 
00055 
00056 dyn_hash_map<void *, AnnotationContainerBase *> AnnotationContainerBase::containers_by_id;
00057 void AnnotationContainerBase::clearContainersByID()
00058 {
00059     containers_by_id.clear();
00060 }
00061 void Serializable::clearContainersByID()
00062 {
00063     AnnotationContainerBase::clearContainersByID();
00064 }
00065 
00066 namespace Dyninst 
00067 {
00068 bool dyn_debug_serializer = false;
00069 bool &serializer_debug_flag()
00070 {
00071    //  This function exists to get around problems with exporting the variable
00072    //  across library boundaries on windows...   there's probably a better way to do this...
00073    return dyn_debug_serializer;
00074 }
00075 
00076 Serializable * ser_func_wrapper(void *it, SerializerBase *sb, 
00077         const char *tag)
00078 {   
00079     assert(it);
00080     assert(sb);
00081     Serializable *s = (Serializable *) (it);
00082     return s->serialize(sb, tag);
00083 }   
00084 
00085 
00086 void serialize_debug_init()
00087 {
00088    char *p;
00089    if ( (p=getenv("DYNINST_DEBUG_SERIALIZER"))) {
00090       fprintf(stderr, "Enabling DyninstAPI serializer debug\n");
00091       dyn_debug_serializer = true;
00092    }
00093 }
00094 
00095 
00096 int serializer_printf(const char *format, ...) 
00097 {   
00098    if (!dyn_debug_serializer) return 0;
00099    if (NULL == format) return -1;
00100 
00101    //debugPrintLock->_Lock(FILE__, __LINE__);
00102 
00103    //  probably want to have basic thread-id routines in libcommon...
00104    //  uh...  later....
00105 
00106    //fprintf(stderr, "[%s]", getThreadStr(getExecThreadID()));
00107    va_list va;
00108    va_start(va, format);
00109    int ret = vfprintf(stderr, format, va);
00110    va_end(va);
00111 
00112    //debugPrintLock->_Unlock(FILE__, __LINE__);
00113 
00114    return ret;
00115 } 
00116 
00117 #ifndef CASE_RETURN_STR 
00118 #define CASE_RETURN_STR(x) case x: return #x;
00119 #endif
00120 const char *serPostOp2Str(ser_post_op_t s)
00121 {
00122     switch (s)
00123     {
00124         CASE_RETURN_STR(sp_add_anno);
00125         CASE_RETURN_STR(sp_rem_anno);
00126         CASE_RETURN_STR(sp_add_cont_item);
00127         CASE_RETURN_STR(sp_rem_cont_item);
00128     }
00129     return "bad_op";
00130 }
00131 
00132 std::vector<std::pair<std::string, dyn_hash_map<std::string, short>*> >  SerContextBase::ser_control_map;
00133 dyn_hash_map<std::string, short> *SerContextBase::getMapForType(std::string tname)
00134 {
00135     for (unsigned int i = 0; i < ser_control_map.size(); ++i)
00136     {
00137         if (std::string(tname) == ser_control_map[i].first)
00138             return ser_control_map[i].second;
00139     }
00140     return NULL;
00141 }
00142 
00143 SerContextBase::SerContextBase(std::string tname, std::string fname_) :
00144     fname(fname_)
00145 {
00146     dyn_hash_map<std::string, short> *map_p = getMapForType(tname);
00147     if (!map_p)
00148     {
00149         map_p = new dyn_hash_map<std::string, short>();
00150         ser_control_map.push_back(std::make_pair(std::string(tname), map_p));
00151         (*map_p)[fname] = 0;
00152     }
00153     //  If we already have a serialize control specification for this file
00154     //  do not reset it here.  This allows us to specify serializer behavior
00155     //  in the testsuite apriori.
00156 }
00157 
00158 void SerContextBase::enableSerialize(std::string tname, std::string filename, bool val)
00159 {
00160     dyn_hash_map<std::string, short> *map_p = getMapForType(tname);
00161     if (!map_p)
00162     {
00163         //  This case should not be able to happen, but, anyways....
00164         map_p = new dyn_hash_map<std::string, short>();
00165         ser_control_map.push_back(std::make_pair(tname, map_p));
00166     }
00167 
00168     dyn_hash_map<std::string, short>::iterator iter = map_p->find(filename);
00169     if (iter == map_p->end())
00170     {
00171         if (val)
00172             (*map_p)[filename] = SERIALIZE_ENABLE_FLAG;
00173         else
00174             (*map_p)[filename] = 0;
00175     }
00176     else
00177     {
00178         short &flags = iter->second;
00179         if (val)
00180             flags |= SERIALIZE_ENABLE_FLAG;
00181         else
00182             flags &= ~SERIALIZE_ENABLE_FLAG;
00183     }
00184 }
00185 
00186 void SerContextBase::enableSerialize(bool val)
00187 {
00188     SerContextBase::enableDeserialize(std::string(getRootTypename()), fname, val);
00189 }
00190 
00191 void SerContextBase::enableDeserialize(std::string tname, std::string filename, bool val)
00192 {
00193     dyn_hash_map<std::string, short> *map_p = getMapForType(tname);
00194     if (!map_p)
00195     {
00196         //  This case should not be able to happen, but, anyways....
00197         map_p = new dyn_hash_map<std::string, short>();
00198         ser_control_map.push_back(std::make_pair(tname, map_p));
00199     }
00200 
00201     dyn_hash_map<std::string, short>::iterator iter = map_p->find(filename);
00202     if (iter == map_p->end())
00203     {
00204         if (val)
00205             (*map_p)[filename] = DESERIALIZE_ENABLE_FLAG;
00206         else
00207             (*map_p)[filename] = 0;
00208     }
00209     else
00210     {
00211         short &flags = iter->second;
00212         if (val)
00213             flags |= DESERIALIZE_ENABLE_FLAG;
00214         else
00215             flags &= ~DESERIALIZE_ENABLE_FLAG;
00216     }
00217 }
00218 
00219 void SerContextBase::enableDeserialize(bool val)
00220 {
00221     SerContextBase::enableDeserialize(std::string(getRootTypename()), fname, val);
00222 }
00223 
00224 void SerContextBase::enforceDeserialize(std::string tname, std::string filename, bool val)
00225 {
00226     dyn_hash_map<std::string, short> *map_p = getMapForType(tname);
00227     if (!map_p)
00228     {
00229         //  This case should not be able to happen, but, anyways....
00230         map_p = new dyn_hash_map<std::string, short>();
00231         ser_control_map.push_back(std::make_pair(tname, map_p));
00232     }
00233 
00234     dyn_hash_map<std::string, short>::iterator iter = map_p->find(filename);
00235     if (iter == map_p->end())
00236     {
00237         if (val)
00238             (*map_p)[filename] = DESERIALIZE_ENFORCE_FLAG;
00239         else
00240             (*map_p)[filename] = 0;
00241     }
00242     else
00243     {
00244         short &flags = iter->second;
00245         if (val)
00246             flags |= DESERIALIZE_ENFORCE_FLAG;
00247         else
00248             flags &= ~DESERIALIZE_ENFORCE_FLAG;
00249     }
00250 }
00251 
00252 void SerContextBase::enforceDeserialize(bool val)
00253 {
00254     SerContextBase::enforceDeserialize(std::string(getRootTypename()), fname, val);
00255 }
00256 
00257 void SerContextBase::enableSerDes(std::string tname, std::string filename, bool val)
00258 {
00259     dyn_hash_map<std::string, short> *map_p = getMapForType(tname);
00260     if (!map_p)
00261     {
00262         //  This case should not be able to happen, but, anyways....
00263         map_p = new dyn_hash_map<std::string, short>();
00264         ser_control_map.push_back(std::make_pair(tname, map_p));
00265     }
00266 
00267     dyn_hash_map<std::string, short>::iterator iter = map_p->find(filename);
00268     if (iter == map_p->end())
00269     {
00270         if (val)
00271             (*map_p)[filename] = DESERIALIZE_ENABLE_FLAG | SERIALIZE_ENABLE_FLAG;
00272         else
00273             (*map_p)[filename] = 0;
00274     }
00275     else
00276     {
00277         short &flags = iter->second;
00278         if (val)
00279         {
00280             flags |= SERIALIZE_ENABLE_FLAG;
00281             flags |= DESERIALIZE_ENABLE_FLAG;
00282         }
00283         else
00284             flags = 0;
00285     }
00286 }
00287 
00288 void SerContextBase::enableSerDes(bool val)
00289 {
00290     SerContextBase::enableSerDes(std::string(getRootTypename()), fname, val);
00291 }
00292 
00293 bool SerContextBase::serializeEnabled()
00294 {
00295     dyn_hash_map<std::string, short> *map_p = getMapForType(std::string(getRootTypename()));
00296     if (!map_p)
00297     {
00298         //  This case should not be able to happen, but, anyways....
00299         return false;
00300     }
00301 
00302     dyn_hash_map<std::string, short>::iterator iter = map_p->find(fname);
00303     if (iter == map_p->end())
00304     {
00305         //  This case should not be able to happen, but, anyways....
00306         return false;
00307     }
00308 
00309     short &flags = iter->second;
00310     return (0 != (flags & SERIALIZE_ENABLE_FLAG));
00311 }
00312 
00313 bool SerContextBase::deserializeEnabled()
00314 {
00315     dyn_hash_map<std::string, short> *map_p = getMapForType(std::string(getRootTypename()));
00316     if (!map_p)
00317     {
00318         //  This case should not be able to happen, but, anyways....
00319         return false;
00320     }
00321 
00322     dyn_hash_map<std::string, short>::iterator iter = map_p->find(fname);
00323     if (iter == map_p->end())
00324     {
00325         //  This case should not be able to happen, but, anyways....
00326         return false;
00327     }
00328 
00329     short &flags = iter->second;
00330     return (0 != (flags & DESERIALIZE_ENABLE_FLAG));
00331 }
00332 
00333 bool SerContextBase::deserializeEnforced(std::string tname, std::string filename)
00334 {
00335     dyn_hash_map<std::string, short> *map_p = getMapForType(tname);
00336     if (!map_p)
00337     {
00338         //  This case should not be able to happen, but, anyways....
00339         return false;
00340     }
00341 
00342     dyn_hash_map<std::string, short>::iterator iter = map_p->find(filename);
00343     if (iter == map_p->end())
00344     {
00345         //  This case should not be able to happen, but, anyways....
00346         return false;
00347     }
00348 
00349     short &flags = iter->second;
00350     return (0 != (flags & DESERIALIZE_ENFORCE_FLAG));
00351 }
00352 
00353 bool SerContextBase::deserializeEnforced()
00354 {
00355     return SerContextBase::deserializeEnforced(std::string(getRootTypename()), fname);
00356 }
00357 
00358 std::string SerContextBase::getSerFileName()
00359 {
00360     return serfilename;
00361 }
00362 
00363 SerializerBase *createSerializer(SerContextBase *scs, 
00364         std::string ser_name, std::string file, ser_type_t ser_type, 
00365         iomode_t mode, bool verbose)
00366 
00367 {
00368     if (!scs->serializeEnabled() && (mode == sd_serialize))
00369     {
00370         serialize_printf("%s[%d]:  serialization not enabled\n", FILE__, __LINE__);
00371         return NULL;
00372     }
00373 
00374     if (!scs->deserializeEnabled() && (mode == sd_deserialize))
00375     {
00376         serialize_printf("%s[%d]:  deserialization not enabled\n", FILE__, __LINE__);
00377         return NULL;
00378     }
00379 
00380     SerializerBase *ret = NULL;
00381     try {
00382         if (!scs)
00383         {
00384             fprintf(stderr, "%s[%d]:  ERROR context object not given for serialiezr\n", 
00385                     FILE__, __LINE__);
00386             return NULL;
00387         }
00388 
00389         if (ser_type == ser_bin)
00390         {
00391             serialize_printf("%s[%d]:  creating bin serializer %s/%s, %p\n", 
00392                     FILE__, __LINE__, ser_name.c_str(), file.c_str(), scs);
00393             ret = new SerializerBin(scs, ser_name, file, mode, verbose);
00394         }
00395         else if (ser_type == ser_xml)
00396         {
00397             ret = new SerializerXML(scs, ser_name, file, mode, verbose);
00398         }
00399         else
00400         {
00401             serialize_printf("%s[%d]:  bad serializer type provided\n", 
00402                     FILE__, __LINE__);
00403             return NULL;
00404         }
00405     }
00406     catch(const SerializerError &err) 
00407     {
00408         fprintf(stderr, "%s[%d]:  %sserialize failed init...  \n\t%s[%d]: %s\n",
00409                 FILE__, __LINE__, mode == sd_serialize ? "" : "de", 
00410                 err.file().c_str(), err.line(), err.what());
00411         return NULL;
00412     }
00413     return ret;
00414 }
00415 
00416 SerDes *SerFile::getSD()
00417 {
00418     return sd;
00419 }
00420 
00421 SerFile::SerFile(std::string fname, iomode_t mode, bool verbose) :
00422     writer (NULL), 
00423     f(NULL), 
00424     iomode_(mode), 
00425     noisy(verbose) 
00426 {
00427         std::string file_path = resolve_file_path(fname.c_str());
00428         if( file_path.empty() )
00429     {
00430         char msg[1024];
00431         snprintf(msg, 1024, "failed to resolve path for '%s'\n", fname.c_str());
00432         SER_ERR(msg);
00433     }
00434 
00435     filename = std::string(file_path);
00436     serialize_debug_init();
00437 
00438     if (strstr(filename.c_str(), "xml")) 
00439     {
00440         fprintf(stderr, "%s[%d]:  opening xml file %s for %s\n", FILE__, __LINE__, 
00441                 filename.c_str(), mode == sd_serialize ? "output" : "input");
00442 
00443         if (mode == sd_deserialize) 
00444         {
00445             fprintf(stderr, "%s[%d]:  ERROR:  deserializing xml not supported\n", 
00446                     FILE__, __LINE__);
00447             assert(0);
00448         }
00449 
00450 #if defined (cap_have_libxml)
00451         writer = SerDesXML::init(fname, mode, verbose);
00452 
00453         if (!writer) 
00454         {
00455             fprintf(stderr, "%s[%d]:  ERROR:  failed to init xml writer\n", 
00456                     FILE__, __LINE__);
00457             assert(0);
00458         }
00459 #else
00460 
00461         writer = NULL;
00462 #endif
00463 
00464         sd = new SerDesXML(writer, mode);
00465 
00466     }
00467     else 
00468     {
00469         serialize_printf("%s[%d]:  opening %s file for %s\n", FILE__, __LINE__, 
00470                 filename.c_str(), mode == sd_serialize ? "output" : "input");
00471 
00472         f = SerDesBin::init(std::string(fname), mode, verbose);
00473 
00474         if (!f) 
00475         {
00476             fprintf(stderr, "%s[%d]:  failed to init file i/o\n", FILE__, __LINE__);
00477             assert(0);
00478         }
00479 
00480         sd = new SerDesBin(f,mode, verbose);
00481     }
00482 }
00483 
00484 iomode_t SerFile::iomode()
00485 {
00486     return iomode_;
00487 }
00488 
00489 std::string SerFile::getCacheFileName()
00490 {
00491     std::string cache_name;
00492     SerDes *sd = getSD();
00493     if (!sd) return std::string();
00494     SerDesBin *sdb = dynamic_cast<SerDesBin *>(sd);
00495     if (!sdb) return std::string();
00496     sdb->resolveCachePath(filename, cache_name); 
00497     return cache_name;
00498 }
00499 
00500 bool Serializable::serialize(std::string file, SerContextBase *scb, ser_type_t mode)
00501 {
00502     std::string sername = file;
00503     SerializerBase *serializer = createSerializer(scb, sername, file, mode, sd_serialize, false);
00504 
00505     if (!serializer)
00506     {
00507         serialize_printf("%s[%d]:  failed to create serializer\n", FILE__, __LINE__);
00508         return false;
00509     }
00510 
00511     try 
00512     {
00513         //  Do the serialization
00514         serialize(serializer, NULL);
00515         void *barrier_magic = (void *)0xdeadbeef;
00516         serialize_annotatable_id(serializer, barrier_magic, NULL);
00517         if (barrier_magic != (void *)0xdeadbeef)
00518         {
00519             fprintf(stderr, "%s[%d]:  FIXME:  failed to read magic barrier val\n", 
00520                     FILE__, __LINE__);
00521         }
00522 
00523     }
00524     catch (const SerializerError &err_)
00525     {
00526         fprintf(stderr, "%s[%d]:  serialize failed\n", FILE__, __LINE__);
00527         printSerErr(err_);
00528         return false;
00529     }
00530 
00531     return true;
00532 
00533 }
00534 
00535 AnnotatableSparse *find_sparse_annotatable(SerializerBase *serializer, void *id)
00536 {
00537     assert(serializer);
00538     return serializer->findSparseAnnotatable(id);
00539 }
00540 
00541 AnnotatableDense *find_dense_annotatable(SerializerBase *serializer,void *id)
00542 {
00543     assert(serializer);
00544     return serializer->findDenseAnnotatable(id);
00545 }
00546 
00547 bool isEOF(SerializerBase *sb)
00548 {
00549     if (!sb)
00550     {
00551         fprintf(stderr, "%s[%d]:  FIXME\n", FILE__, __LINE__);
00552         return false;
00553     }
00554     return sb->isEOF();
00555 }
00556 
00557 bool SerializerBase::isEOF()
00558 {
00559     return sd->isEOF();
00560 }
00561 
00562 void SerializerBase::clearAnnotationMaps()
00563 {
00564     if (sparse_annotatable_map) 
00565     {
00566         sparse_annotatable_map->clear();
00567         //delete sparse_annotatable_map;
00568         //sparse_annotatable_map = NULL;
00569     }
00570     if (dense_annotatable_map) 
00571     {
00572         dense_annotatable_map->clear();
00573         //delete dense_annotatable_map;
00574         //dense_annotatable_map = NULL;
00575     }
00576 }
00577 
00578 AnnotatableSparse *SerializerBase::findSparseAnnotatable(void *id)
00579 {
00580     dyn_hash_map<void *, AnnotatableSparse *>::iterator iter;
00581     iter = sparse_annotatable_map->find(id);
00582     if (iter == sparse_annotatable_map->end())
00583     {
00584         serialize_printf("%s[%d]:  ERROR:  cannot find parent to assign annotation to\n",
00585                 __FILE__, __LINE__);
00586         return NULL;
00587     }
00588     return iter->second;
00589 }
00590 
00591 AnnotatableDense *SerializerBase::findDenseAnnotatable(void *id)
00592 {
00593     dyn_hash_map<void *, AnnotatableDense *>::iterator iter;
00594     iter = dense_annotatable_map->find(id);
00595     if (iter == dense_annotatable_map->end())
00596     {
00597         serialize_printf("%s[%d]:  ERROR:  cannot find parent to assign annotation to\n",
00598                 __FILE__, __LINE__);
00599         return NULL;
00600     }
00601     return iter->second;
00602 }
00603 
00604 void printSerErr(const SerializerError &err) 
00605 {
00606     fprintf(stderr, "\tserializer exception %s from \n\t%s[%d]\n", 
00607             err.what(), err.file().c_str(), err.line());
00608 }
00609 
00610 
00611 bool isOutput(SerializerBase *ser)
00612 {
00613     return (ser->iomode() == sd_serialize);
00614 }
00615 
00616 bool isBinary(SerializerBase *ser)
00617 {
00618     return ser->isBin();
00619 }
00620 
00621 #if 0
00622 void trans_adapt(SerializerBase *ser, Serializable &it, const char *tag)
00623 {
00624     it.serialize(ser, tag);
00625 }
00626 
00627 void trans_adapt(SerializerBase *ser, Serializable  *itp, const char *tag)
00628 {
00629    assert(itp);
00630    trans_adapt(ser, *itp, tag);
00631 }
00632 
00633 void trans_adapt(SerializerBase *ser, bool &it, const char *tag)
00634 {
00635    assert(ser);
00636    ser->translate_base(it, tag);
00637 }
00638 
00639 void trans_adapt(SerializerBase *ser, int &it, const char *tag)
00640 {
00641    assert(ser);
00642    ser->translate_base(it, tag);
00643 }
00644 
00645 void trans_adapt(SerializerBase *ser, unsigned int &it, const char *tag)
00646 {
00647    assert(ser);
00648    ser->translate_base(it, tag);
00649 }
00650 
00651 void trans_adapt(SerializerBase *ser, long &it, const char *tag)
00652 {
00653    assert(ser);
00654    ser->translate_base(it, tag);
00655 }
00656 
00657 void trans_adapt(SerializerBase *ser, unsigned long &it, const char *tag)
00658 {
00659    assert(ser);
00660    ser->translate_base(it, tag);
00661 }
00662 
00663 void trans_adapt(SerializerBase *ser, char &it, const char *tag)
00664 {
00665    assert(ser);
00666    ser->translate_base(it, tag);
00667 }
00668 
00669 void trans_adapt(SerializerBase *ser, char *&it, const char *tag)
00670 {
00671    assert(ser);
00672    assert(it);
00673    int s_len = strlen(it);
00674    ser->translate_base(const_cast<const char *&>(it), s_len, tag);
00675 }
00676 
00677 void trans_adapt(SerializerBase *ser, std::string &it, const char *tag)
00678 {
00679    assert(ser);
00680    ser->translate_base(it, tag);
00681 }
00682 
00683 void trans_adapt(SerializerBase *ser, float &it, const char *tag)
00684 {
00685    assert(ser);
00686    ser->translate_base(it, tag);
00687 }
00688 
00689 void trans_adapt(SerializerBase *ser, double  &it, const char *tag)
00690 {
00691    assert(ser);
00692    ser->translate_base(it, tag);
00693 }
00694 #endif
00695 
00696 bool sb_is_input(SerializerBase *sb) 
00697 {
00698    return  (sb->iomode() == sd_deserialize);
00699 }
00700 
00701 bool sb_is_output(SerializerBase *sb) 
00702 {
00703    return  (sb->iomode() == sd_serialize);
00704 }
00705 
00706 
00707 SerializerBase *getExistingOutputSB(Serializable *s)
00708 {
00709     return s->lookupExistingSerializer();
00710 }
00711 
00712 SerializerBase *getExistingOutputSB(unsigned short ndx)
00713 {
00714     if (SerializerBase::active_serializers.size() <= ndx)
00715         return NULL;
00716     return SerializerBase::active_serializers[ndx];
00717 }
00718 
00719 } /* namespace Dyninst */
00720 
00721 bool SerializerBase::removeSerializer(unsigned short ndx)
00722 {
00723     if (SerializerBase::active_serializers.size() <= ndx)
00724         return false;
00725     SerializerBase::active_serializers[ndx] = NULL;
00726     if (ndx == (unsigned short) (active_serializers.size() - 1))
00727         active_serializers.pop_back();
00728     return true;
00729 }
00730 bool SerializerBase::global_disable = false;
00731 
00732 #if 0
00733 COMMON_EXPORT dyn_hash_map<std::string, SerializerBase *> SerializerBase::active_bin_serializers;
00734 #endif
00735 COMMON_EXPORT std::vector<SerializerBase *> SerializerBase::active_serializers;
00736 
00737 SerDesBin &SerializerBin::getSD_bin()
00738 {
00739     SerializerBase *sb = this;
00740    SerDes &sd = sb->getSD();
00741    SerDesBin *sdbin = dynamic_cast<SerDesBin *> (&sd);
00742    assert(sdbin);
00743    return *sdbin;
00744 }
00745 
00746 SerializerBin::SerializerBin(SerContextBase *s, std::string name_, std::string filename,
00747         iomode_t dir, bool verbose) :
00748     SerializerBase(s, std::string(name_), std::string(filename), dir, verbose)
00749 { 
00750     SerializerBase *sb = this;
00751     if (sb->serializationDisabled())
00752     {
00753         fprintf(stderr, "%s[%d]:  Failing to construct Bin Translator:  global disable set\n"
00754                 ,       
00755                 FILE__, __LINE__);
00756 
00757         throw SerializerError(FILE__, __LINE__,
00758                 std::string("serialization disabled"),
00759                 SerializerError::ser_err_disabled);
00760     }
00761 }
00762 
00763 SerializerBin::~SerializerBin()
00764 {
00765     serialize_printf("%s[%d]:  WELCOME TO SERIALIZER_BIN dtor\n", FILE__, __LINE__);
00766     //dyn_hash_map<std::string, SerializerBase *>::iterator iter;
00767 }
00768 
00769 void SerializerBase::dumpActiveBinSerializers()
00770 {
00771     fprintf(stderr, "%s[%d]:  have serializers: FIXME\n", FILE__, __LINE__);
00772 }
00773 
00774 FILE *SerDesBin::init(std::string filename, iomode_t mode, bool /*verbose*/) 
00775 {
00776    if (SerializerBase::serializationDisabled()) 
00777    {
00778       fprintf(stderr, "%s[%d]:  Failing BinTranslator:  global disable set\n", 
00779               FILE__, __LINE__);
00780       throw SerializerError(FILE__, __LINE__, 
00781             std::string("serialization disabled"), 
00782             SerializerError::ser_err_disabled);
00783    }
00784 
00785    //  NOTE:  fname is path-resolved and turned into "filename" by the SerDes ctor
00786    FILE *f = NULL;
00787    std::string cache_name;
00788 
00789    if (! SerDesBin::resolveCachePath(filename, cache_name)) 
00790    {
00791       serialize_printf("%s[%d]:  no cache file exists for %s\n", 
00792             FILE__, __LINE__, filename.c_str());
00793 
00794       if (mode == sd_deserialize) 
00795       {
00796          //  can't deserialize from a file that does not exist
00797          char msg[1024];
00798          snprintf(msg, 1024, "%s[%d]:  no cache file exists for %s/%s\n", 
00799                FILE__, __LINE__, filename.c_str(), cache_name.c_str());
00800          fprintf(stderr, "%s\n", msg);
00801          SER_ERR(msg);
00802       }
00803    }
00804 
00805    errno = 0;
00806    serialize_printf("%s[%d]:  opening cache file %s for %s\n", FILE__, __LINE__, cache_name.c_str(), (mode == sd_serialize) ? "serialize" : "deserialize");
00807 
00808    f = fopen(cache_name.c_str(), (mode == sd_serialize) ? "w+" : "r");
00809 
00810    if (!f) 
00811    {
00812       char msg[1024];
00813       serialize_printf("%s[%d]: fopen(%s, %s): %s\n", FILE__, __LINE__, 
00814             cache_name.c_str(), (mode == sd_serialize) ? "w+" : "r", strerror(errno));
00815       snprintf(msg, 1024, "fopen(%s, %s): %s", cache_name.c_str(), 
00816               (mode == sd_serialize) ? "w+" : "r", strerror(errno));
00817       fprintf(stderr, "%s\n", msg);
00818       SER_ERR(msg);
00819    }
00820 
00821    serialize_printf("%s[%d]:  opened cache file %s: %s\n", 
00822            FILE__, __LINE__, cache_name.c_str(), strerror(errno));
00823 
00824    try 
00825    {
00826       if (mode == sd_serialize)
00827       {
00828          writeHeaderPreamble(f, filename, cache_name);
00829       }
00830       else 
00831       {
00832          readHeaderAndVerify(filename, cache_name, f);
00833       }
00834    }
00835    catch(const SerializerError &err) 
00836    {
00837       fclose(f);
00838       serialize_printf("%s[%d]:  %sserialize failed init.\n\t%s[%d]: %s\n\trethrowing.\n",
00839             FILE__, __LINE__, mode == sd_serialize ? "" : "de", 
00840             err.file().c_str(), err.line(), err.what());
00841       throw(err);
00842    }
00843 
00844    return f;
00845 }
00846 
00847 SerDesBin::~SerDesBin()
00848 {
00849 }
00850 
00851 bool SerDesBin::isEOF()
00852 {
00853     return (0 != feof(f));
00854 }
00855 
00856 bool SerDesBin::getDefaultCacheDir(std::string &path)
00857 {
00858    char *home_dir = getenv("HOME");
00859 
00860    if (!home_dir) 
00861    {
00862       fprintf(stderr, "%s[%d]:  weird, no $HOME dir\n", FILE__, __LINE__);
00863       return false;
00864    }
00865 
00866    std::string dot_dyninst_dir = std::string(home_dir) + std::string("/")
00867       + std::string(DEFAULT_DYNINST_DIR);
00868 
00869    struct stat statbuf;
00870 
00871    if (0 != stat(dot_dyninst_dir.c_str(), &statbuf)) 
00872    {
00873       if (errno == ENOENT) 
00874       {
00875 #if defined (os_windows)
00876          if (0 != P_mkdir(dot_dyninst_dir.c_str(), 0)) 
00877          {
00878             fprintf(stderr, "%s[%d]:  failed to make %s\n", FILE__, __LINE__, 
00879                   dot_dyninst_dir.c_str(), strerror(errno));
00880             return false;
00881          } 
00882 #else
00883          if (0 != mkdir(dot_dyninst_dir.c_str(), S_IRWXU)) 
00884          {
00885             fprintf(stderr, "%s[%d]:  failed to make %s: %s\n", FILE__, __LINE__, 
00886                   dot_dyninst_dir.c_str(), strerror(errno));
00887             return false;
00888          } 
00889 #endif
00890       }
00891       else 
00892       {
00893          fprintf(stderr, "%s[%d]:  stat(%s) failed: %s\n", FILE__, __LINE__, 
00894                dot_dyninst_dir.c_str(), strerror(errno));
00895          return false;
00896       }
00897    }
00898    else 
00899    {
00900 #if !defined (os_windows)
00901       //  sanity check that its a dir
00902       if (!S_ISDIR(statbuf.st_mode)) 
00903       {
00904          fprintf(stderr, "%s[%d]:  ERROR:  %s is not a dir\n", FILE__, __LINE__, 
00905                dot_dyninst_dir.c_str());
00906          return false;
00907       }
00908 #else
00909       //  windows equiv to S_ISDIR??
00910 #endif
00911    }
00912 
00913    std::string cpath = dot_dyninst_dir + std::string("/") + std::string(DEFAULT_CACHE_DIR);
00914 
00915    if (0 != stat(cpath.c_str(), &statbuf)) 
00916    {
00917       if (errno == ENOENT) 
00918       {
00919 #if defined (os_windows)
00920          if (0 != P_mkdir(cpath.c_str(), 0)) 
00921          {
00922             fprintf(stderr, "%s[%d]:  failed to make %s\n", FILE__, __LINE__, 
00923                   cpath.c_str(), strerror(errno));
00924             return false;
00925          } 
00926 #else
00927          if (0 != mkdir(cpath.c_str(), S_IRWXU)) 
00928          {
00929             fprintf(stderr, "%s[%d]:  failed to make %s: %s\n", FILE__, __LINE__, 
00930                   cpath.c_str(), strerror(errno));
00931             return false;
00932          } 
00933 #endif
00934       }
00935       else 
00936       {
00937          fprintf(stderr, "%s[%d]:  stat(%s) failed: %s\n", FILE__, __LINE__, 
00938                cpath.c_str(), strerror(errno));
00939          return false;
00940       }
00941    }
00942    else 
00943    {
00944 #if !defined (os_windows)
00945       //  sanity check that its a dir
00946       if (!S_ISDIR(statbuf.st_mode)) 
00947       {
00948          fprintf(stderr, "%s[%d]:  ERROR:  %s is not a dir\n", FILE__, __LINE__, 
00949                cpath.c_str());
00950          return false;
00951       }
00952 #else
00953       //  windows equiv to S_ISDIR??
00954 #endif
00955    }
00956 
00957    //  Finally qualify path with platform to avoid collisions with cachenames
00958    //  when the home directory is shared across multiple machines.
00959 
00960    path = cpath + std::string("/") + std::string(platform_string()); 
00961 
00962    if (0 != stat(path.c_str(), &statbuf)) 
00963    {
00964       if (errno == ENOENT) 
00965       {
00966 #if defined (os_windows)
00967          if (0 != P_mkdir(path.c_str(), 0)) 
00968          {
00969             fprintf(stderr, "%s[%d]:  failed to make %s\n", FILE__, __LINE__, 
00970                   path.c_str(), strerror(errno));
00971             return false;
00972          } 
00973 #else
00974          if (0 != mkdir(path.c_str(), S_IRWXU)) 
00975          {
00976             fprintf(stderr, "%s[%d]:  failed to make %s: %s\n", FILE__, __LINE__, 
00977                   path.c_str(), strerror(errno));
00978             return false;
00979          } 
00980 #endif
00981       }
00982       else 
00983       {
00984          fprintf(stderr, "%s[%d]:  stat(%s) failed: %s\n", FILE__, __LINE__, 
00985                path.c_str(), strerror(errno));
00986          return false;
00987       }
00988    }
00989    else 
00990    {
00991 #if !defined (os_windows)
00992       //  sanity check that its a dir
00993       if (!S_ISDIR(statbuf.st_mode)) 
00994       {
00995          fprintf(stderr, "%s[%d]:  ERROR:  %s is not a dir\n", FILE__, __LINE__, 
00996                path.c_str());
00997          return false;
00998       }
00999 #else
01000       //  windows equiv to S_ISDIR??
01001 #endif
01002    }
01003 
01004    serialize_printf("%s[%d]:  using default cache dir: %s\n", 
01005            FILE__, __LINE__, path.c_str());
01006 
01007    return true;
01008 }
01009 
01010 bool SerDesBin::resolveCachePath(std::string full_file_path, std::string &cache_name)
01011 {
01012    std::string path;
01013    char *path_dir = getenv(CACHE_DIR_VAR); 
01014 
01015    if (!path_dir) 
01016    {
01017       if (!getDefaultCacheDir(path)) 
01018       {
01019          fprintf(stderr, "%s[%d]:  weird, failed to make $HOME/.dyninst/caches\n",
01020                FILE__, __LINE__);
01021          return false;
01022       }
01023    }
01024 
01025    // get size of file (this is encoded into cache name)
01026    struct stat statbuf;
01027 
01028    if (0 != stat(full_file_path.c_str(), &statbuf)) 
01029    {
01030       fprintf(stderr, "%s[%d]:  stat %s failed: %s\n", FILE__, __LINE__, 
01031             full_file_path.c_str(), strerror(errno));
01032       return false;
01033    }
01034 
01035    std::string short_name = extract_pathname_tail(full_file_path);
01036    serialize_printf("%s[%d]:  file %s short name: %s\n", FILE__, __LINE__, 
01037          full_file_path.c_str(), short_name.c_str());
01038 
01039    // construct cache name from cache path, cache prefix, short name, and size
01040    //  and now also platform, to prevent cache name collisions for configurations
01041    //  where the users home dir is shared.
01042 
01043    char sizestr[16];
01044    snprintf(sizestr, 16, "%d", (int)statbuf.st_size);
01045    cache_name = path + std::string("/") + std::string(CACHE_PREFIX) 
01046        + short_name 
01047       + std::string("_") 
01048       + std::string(sizestr);
01049 
01050    serialize_printf("%s[%d]:  constructed cache name: %s\n", FILE__, __LINE__, cache_name.c_str());
01051 
01052    if (0 != stat(cache_name.c_str(), &statbuf)) 
01053    {
01054       if (errno != ENOENT) 
01055       {
01056          //  Its OK if the file doesn't exist, but complain if we get a different
01057          // error
01058          fprintf(stderr, "%s[%d]:  stat %s failed: %s\n", FILE__, __LINE__, 
01059                cache_name.c_str(), strerror(errno));
01060       }
01061       serialize_printf("%s[%d]:  cache file %s does not exist\n", FILE__, __LINE__, 
01062             cache_name.c_str());
01063       return false;
01064    }
01065 
01066    serialize_printf("%s[%d]:  cache file %s exists\n", FILE__, __LINE__, cache_name.c_str());
01067    return true;
01068 }
01069 
01070 bool SerDesBin::cacheFileExists(std::string fname)
01071 {
01072    std::string cache_name;
01073    return resolveCachePath(fname, cache_name); 
01074 }
01075 
01076 void SerDesBin::readHeaderAndVerify(std::string full_file_path, std::string cache_name, FILE *fptr)
01077 {
01078    struct stat statbuf;
01079 
01080    if (0 != stat(full_file_path.c_str(), &statbuf)) 
01081    {
01082       char msg[1024];
01083       if (errno != ENOENT) 
01084       {
01085          //  Its OK if the file doesn't exist, but complain if we get a different
01086          // error
01087          snprintf(msg, 1024, "%s[%d]:  stat %s failed: %s\n", FILE__, __LINE__, 
01088                full_file_path.c_str(), strerror(errno));
01089       }
01090       SER_ERR(msg);
01091    }
01092 
01093    FILE *f = NULL;
01094    if (fptr) 
01095       f = fptr;
01096    else 
01097    {
01098        serialize_printf("%s[%d]:  trying to open %s\n", FILE__, __LINE__, 
01099                cache_name.c_str());
01100 
01101       f = fopen(cache_name.c_str(), "r");
01102 
01103       if (!f) 
01104       {
01105          char msg[1024];
01106          snprintf(msg, 1024, "%s[%d]:  failed to open file %s: %s\n", 
01107                FILE__, __LINE__, full_file_path.c_str(), strerror(errno));
01108          fprintf(stderr, "%s\n", msg);
01109          SER_ERR(msg);
01110       }
01111    }
01112 
01113    size_t source_file_size = statbuf.st_size;
01114 
01115    cache_header_t header;
01116 
01117    int rc = fread(&header, sizeof(cache_header_t), 1, f);
01118 
01119    if (1 != rc) 
01120    {
01121       char msg[1024];
01122       snprintf(msg, 1024, "%s[%d]:  failed to read header struct for %s: %s, rc = %d\n", 
01123             FILE__, __LINE__, cache_name.c_str(), strerror(errno), rc);
01124       SER_ERR(msg);
01125    }
01126 
01127    if (header.cache_magic != (unsigned) CACHE_MAGIC) 
01128    {
01129       char msg[1024];
01130       snprintf(msg, 1024, "%s[%d]:  magic number check failure for %s--%s: got %d, expected %d\n", 
01131             FILE__, __LINE__, full_file_path.c_str(), cache_name.c_str(), 
01132             header.cache_magic, CACHE_MAGIC);
01133       SER_ERR(msg);
01134    }
01135 
01136    if (header.source_file_size != source_file_size) 
01137    {
01138       char msg[1024];
01139       snprintf(msg, 1024, "%s[%d]:  size discrepancy found for %s/%s\n", 
01140             FILE__, __LINE__, full_file_path.c_str(), cache_name.c_str());
01141       SER_ERR(msg);
01142    }
01143 
01144    if (!verifyChecksum(full_file_path, header.sha1)) 
01145    {
01146       char msg[1024];
01147       snprintf(msg, 1024, "%s[%d]:  checksum discrepancy found for %s/%s\n", 
01148             FILE__, __LINE__, full_file_path.c_str(), cache_name.c_str());
01149 
01150       if (!invalidateCache(cache_name)) 
01151       {
01152          fprintf(stderr, "%s[%d]:  failed to invalidate cache for file %s/%s\n", 
01153                  FILE__, __LINE__, full_file_path.c_str(), cache_name.c_str());
01154       }
01155 
01156       SER_ERR(msg);
01157    }
01158 
01159    if (!fptr)
01160    {
01161        fprintf(stderr, "%s[%d]:  closing file pointer here\n", FILE__, __LINE__);
01162       fclose (f);
01163    }
01164 }
01165 
01166 
01167 void SerDesBin::writeHeaderPreamble(FILE *f, std::string full_file_path, 
01168         std::string /*cache_name*/)
01169 {
01170    serialize_printf("%s[%d]:  welcome to write header preamble for %s\n", 
01171            FILE__, __LINE__, full_file_path.c_str());
01172 
01173    //  get a few bits of info on this file to construct the header of the cache
01174    //  file...  checksum, size, ...  not mtime, since we don't care if someone 
01175    //  copies the file around
01176 
01177    struct stat statbuf;
01178 
01179    if (0 != stat(full_file_path.c_str(), &statbuf)) 
01180    {
01181       char msg[1024];
01182       snprintf(msg, 1024, "%s[%d]:  stat %s failed: %s\n", FILE__, __LINE__, 
01183             full_file_path.c_str(), strerror(errno));
01184       SER_ERR(msg);
01185    }
01186 
01187    cache_header_t header;
01188    header.cache_magic = CACHE_MAGIC;
01189    header.source_file_size = statbuf.st_size;
01190 
01191    if (NULL == sha1_file(full_file_path.c_str(), header.sha1)) 
01192    {
01193       char msg[1024];
01194       snprintf(msg, 1024, "sha1_file failed\n");
01195       SER_ERR(msg);
01196    }
01197 
01198    int rc = fwrite(&header, sizeof(cache_header_t), 1, f);
01199 
01200    if (1 != rc) 
01201       SER_ERR("fwrite");
01202 
01203 }
01204 
01205 bool SerDesBin::verifyChecksum(std::string &full_file_path, 
01206       const char comp_checksum[SHA1_DIGEST_LEN*2])
01207 {
01208    char new_checksum[SHA1_DIGEST_LEN*2]; 
01209 
01210    if (NULL == sha1_file(full_file_path.c_str(), new_checksum)) 
01211    {
01212       fprintf(stderr, "%s[%d]:  sha1_file(%s) failed \n", 
01213             FILE__, __LINE__, full_file_path.c_str());
01214       return false;
01215    }
01216 
01217    if (strncmp(comp_checksum, new_checksum, SHA1_DIGEST_LEN*2)) 
01218    {
01219       fprintf(stderr, "%s[%d]:  sha1_file(%s): checksum mismatch: \n\told:%s\n\tnew:%s\n", 
01220             FILE__, __LINE__, full_file_path.c_str(), comp_checksum, new_checksum);
01221       return false;
01222    }
01223 
01224    return true;
01225 }
01226 
01227 bool SerDesBin::invalidateCache(std::string cache_name) 
01228 {
01229    if (-1 == P_unlink(cache_name.c_str())) 
01230    {
01231       fprintf(stderr, "%s[%d]:  unlink(%s): %s\n", FILE__, __LINE__, 
01232             cache_name.c_str(), strerror(errno));
01233       return false;
01234    }
01235 
01236    return true;
01237 }
01238 
01239 void SerDesBin::file_start(std::string &/*full_file_path*/)
01240 {
01241 }
01242 
01243 void SerDesBin::vector_start(unsigned long &size, const char *) DECLTHROW (SerializerError)
01244 {
01245     if (iomode_ == sd_deserialize) 
01246         size = 0UL;
01247 
01248    //  before reading/writing a vector, we need to read its size
01249    //  (so we know how many elements to read/alloc on deserialize
01250 
01251     magic_check(FILE__, __LINE__);
01252    translate(size);
01253     magic_check(FILE__, __LINE__);
01254     if (iomode_ == sd_deserialize) 
01255     {
01256         serialize_printf("%s[%d]:  DESERIALIZE VECTOR START:  size = %lu\n", 
01257                 FILE__, __LINE__, size);
01258     }
01259     else
01260         serialize_printf("%s[%d]:  SERIALIZE VECTOR START:  size = %lu\n", 
01261                 FILE__, __LINE__, size);
01262 }
01263 
01264 void SerDesBin::vector_end()
01265 {
01266    //  don't need to do anything
01267 }
01268 
01269 void SerDesBin::multimap_start(unsigned long &size, const char *) DECLTHROW (SerializerError)
01270 {
01271    //  before reading/writing a multimap, we need to read its size
01272    //  (so we know how many elements to read/alloc on deserialize
01273    translate(size);
01274 }
01275 
01276 void SerDesBin::multimap_end()
01277 {
01278    //  don't need to do anything
01279 }
01280 
01281 void SerDesBin::pair_start(const char *) DECLTHROW (SerializerError)
01282 {
01283 }
01284 
01285 void SerDesBin::pair_end()
01286 {
01287    //  don't need to do anything
01288 }
01289 
01290 void SerDesBin::hash_map_start(unsigned long &size, const char *) DECLTHROW (SerializerError)
01291 {
01292    //  before reading/writing a hash map, we need to read its size
01293    //  (so we know how many elements to read/alloc on deserialize
01294    translate(size);
01295 }
01296 
01297 void SerDesBin::hash_map_end() 
01298 {
01299 }
01300 
01301 void SerDesBin::annotation_start(AnnotationClassID &a_id, void *&parent_id, 
01302         sparse_or_dense_anno_t &sod, const char *, const char *)
01303 {
01304     //serialize_printf("%s[%d]:  welcome to  annotation_start: aid = %d\n", FILE__, __LINE__, a_id);
01305 
01306     unsigned int lsod = 0;
01307     lsod = (int)sod;
01308     magic_check(FILE__, __LINE__);
01309     translate(a_id);
01310     assert(sizeof(Address) == sizeof(void *));
01311     translate((Address &)parent_id);
01312     //translate((unsigned short &)sod);
01313     translate(lsod);
01314     magic_check(FILE__, __LINE__);
01315 
01316     if (iomode() == sd_deserialize)
01317         sod = (sparse_or_dense_anno_t)lsod;
01318 
01319     serialize_printf("%s[%d]:  leaving %s annotation_start: aid = %d, id = %p\n", 
01320             FILE__, __LINE__, 
01321             (iomode_ == sd_serialize) ? "serialize" : "deserialize", a_id, parent_id);
01322 }
01323 
01324 void SerDesBin::annotation_end()
01325 {
01326     //magic_check(FILE__, __LINE__);
01327    //  don't need to do anything
01328 }
01329 
01330 void SerDesBin::annotation_container_start(void *&id)
01331 {
01332     magic_check(FILE__, __LINE__);
01333     assert(sizeof(Address) == sizeof(void *));
01334     translate((Address &)id);
01335     magic_check(FILE__, __LINE__);
01336 }
01337 
01338 void SerDesBin::annotation_container_end()
01339 {
01340     magic_check(FILE__, __LINE__);
01341    //  don't need to do anything
01342 }
01343 void SerDesBin::annotation_container_item_start(void *&id)
01344 {
01345     magic_check(FILE__, __LINE__);
01346     assert(sizeof(Address) == sizeof(void *));
01347     translate((Address &)id);
01348     magic_check(FILE__, __LINE__);
01349 }
01350 
01351 void SerDesBin::annotation_container_item_end()
01352 {
01353     magic_check(FILE__, __LINE__);
01354    //  don't need to do anything
01355 }
01356 
01357 void SerDesBin::magic_check(const char *file__, unsigned int line__)
01358 {
01359     unsigned short magic = 33;
01360     translate(magic);
01361     if (iomode_ == sd_deserialize)
01362     {
01363         if (magic != 33)
01364         {
01365             fprintf(stderr, "%s[%d]:  OUT OF SYNC HERE\n", file__, line__);
01366             if (isEOF())
01367                 fprintf(stderr, "%s[%d]:  GOT EOF\n", file__, line__);
01368             abort();
01369         }
01370     }
01371 }
01372 
01373 void SerDesBin::annotation_list_start(Address &id, unsigned long &nelem, const char *)
01374 {
01375    if (iomode_ == sd_deserialize) 
01376    {
01377        nelem = 0UL;
01378    }
01379 
01380     if (nelem)
01381     {
01382         serialize_printf("%s[%d]: enter annotation_list_start id = %p, nelem = %ld\n", 
01383                 FILE__, __LINE__, (void *)id, nelem);
01384     }
01385 
01386     magic_check(FILE__, __LINE__);
01387     translate(id);
01388     translate(nelem);
01389 
01390     if (nelem)
01391         serialize_printf("%s[%d]: leave annotation_list_start id = %p, nelem = %ld\n", FILE__, __LINE__, (void *)id, nelem);
01392 }
01393 
01394 void SerDesBin::annotation_list_end()
01395 {
01396    //  don't need to do anything
01397 }
01398 
01399 void SerDesBin::translate(bool &param, const char *tag)
01400 {
01401    int rc;
01402    if (iomode_ == sd_serialize) 
01403    {
01404       rc = fwrite(&param, sizeof(bool), 1, f);
01405 
01406       if (1 != rc) 
01407          SER_ERR("fwrite");
01408    }
01409    else 
01410    {
01411       rc = fread(&param, sizeof(bool), 1, f);
01412 
01413       if (1 != rc) 
01414          SER_ERR("fread");
01415    }
01416 
01417    if (noisy)
01418       serialize_printf("%s[%d]:  %sserialize %s=%s\n", FILE__, __LINE__,
01419             iomode_ == sd_serialize ? "" : "de", 
01420             tag ? tag : "no-tag",
01421             param ? "true": "false");
01422 }
01423 
01424 void SerDesBin::translate(char &param, const char *tag)
01425 {
01426    int rc;
01427 
01428    if (iomode_ == sd_serialize) 
01429    {
01430       rc = fwrite(&param, sizeof(char), 1, f);
01431 
01432       if (1 != rc) 
01433          SER_ERR("fwrite");
01434    }
01435    else 
01436    {
01437       rc = fread(&param, sizeof(char), 1, f);
01438 
01439       if (1 != rc) 
01440          SER_ERR("fread");
01441    }
01442 
01443    if (noisy)
01444       serialize_printf("%s[%d]:  %sserialize %s=%c\n", FILE__, __LINE__,
01445             iomode_ == sd_serialize ? "" : "de", 
01446             tag ? tag : "no-tag", param);
01447 }
01448 
01449 void SerDesBin::translate(int &param, const char *tag)
01450 {
01451    int rc;
01452    if (iomode_ == sd_serialize) 
01453    {
01454       rc = fwrite(&param, sizeof(int), 1, f);
01455 
01456       if (1 != rc) 
01457          SER_ERR("fwrite");
01458    }
01459    else 
01460    {
01461        errno = 0;
01462        rc = fread(&param, sizeof(int), 1, f);
01463 
01464       if (1 != rc) 
01465       {
01466           //fprintf(stderr, "%s[%d]:  failed to deserialize int-'%s', rc = %d:%s, noisy = %d\n", 
01467         //        FILE__, __LINE__, tag ? tag : "no_tag", rc, strerror(errno), noisy);
01468          // fprintf(stderr, "isEOF = %s\n", isEOF() ? "true" : "false");
01469          SER_ERR("fread");
01470       }
01471    }
01472 
01473    if (noisy)
01474       serialize_printf("%s[%d]:  %sserialize %s=%d\n", FILE__, __LINE__,
01475             iomode_ == sd_serialize ? "" : "de", 
01476             tag ? tag : "no-tag", param);
01477 }
01478 
01479 void SerDesBin::translate(long &param, const char *tag)
01480 {
01481    int rc;
01482    if (iomode_ == sd_serialize) 
01483    {
01484       rc = fwrite(&param, sizeof(long), 1, f);
01485 
01486       if (1 != rc) 
01487          SER_ERR("fwrite");
01488    }
01489    else 
01490    {
01491       rc = fread(&param, sizeof(long), 1, f);
01492 
01493       if (1 != rc) 
01494          SER_ERR("fread");
01495    }
01496 
01497    if (noisy)
01498       serialize_printf("%s[%d]:  %sserialize %s=%lu\n", FILE__, __LINE__,
01499             iomode_ == sd_serialize ? "" : "de", 
01500             tag ? tag : "no-tag", param);
01501 }
01502 
01503 void SerDesBin::translate(unsigned short &param, const char *tag)
01504 {
01505     short lshort = static_cast<short>(param);
01506     translate (lshort, tag);
01507     param = static_cast<unsigned short>(lshort);
01508 }
01509 
01510 void SerDesBin::translate(short &param, const char *tag)
01511 {
01512    int rc;
01513    if (iomode_ == sd_serialize) 
01514    {
01515       rc = fwrite(&param, sizeof(short), 1, f);
01516 
01517       if (1 != rc) 
01518          SER_ERR("fwrite");
01519    }
01520    else 
01521    {
01522       rc = fread(&param, sizeof(short), 1, f);
01523 
01524       if (1 != rc) 
01525          SER_ERR("fread");
01526    }
01527 
01528    if (noisy)
01529       serialize_printf("%s[%d]:  %sserialize %s=%d\n", FILE__, __LINE__,
01530             iomode_ == sd_serialize ? "" : "de", 
01531             tag ? tag : "no-tag", param);
01532 }
01533 
01534 void SerDesBin::translate(unsigned int &param, const char * tag)
01535 {
01536    //  overkill for a typecast??
01537    translate( (int &) param, tag);
01538 }
01539 
01540 void SerDesBin::translate(float &param, const char *tag)
01541 {
01542    int rc;
01543    if (iomode_ == sd_serialize) 
01544    {
01545       rc = fwrite(&param, sizeof(float), 1, f);
01546 
01547       if (1 != rc) 
01548          SER_ERR("fwrite");
01549    }
01550    else 
01551    {
01552       rc = fread(&param, sizeof(float), 1, f);
01553 
01554       if (1 != rc) 
01555          SER_ERR("fread");
01556    }
01557 
01558    if (noisy)
01559       serialize_printf("%s[%d]:  %sserialize %s=%e\n", FILE__, __LINE__,
01560             iomode_ == sd_serialize ? "" : "de", 
01561             tag ? tag : "no-tag", param);
01562 }
01563 
01564 void SerDesBin::translate(double &param, const char *tag)
01565 {
01566    int rc;
01567    if (iomode_ == sd_serialize) 
01568    {
01569       rc = fwrite(&param, sizeof(double), 1, f);
01570 
01571       if (1 != rc) 
01572          SER_ERR("fwrite");
01573    }
01574    else 
01575    {
01576       rc = fread(&param, sizeof(double), 1, f);
01577 
01578       if (1 != rc) 
01579          SER_ERR("fread");
01580    }
01581 
01582    if (noisy)
01583       serialize_printf("%s[%d]:  %sserialize %s=%g\n", FILE__, __LINE__,
01584             iomode_ == sd_serialize ? "" : "de", 
01585             tag ? tag : "no-tag", param);
01586 }
01587 
01588 void SerDesBin::translate(Address &param, const char *tag)
01589 {
01590    int rc;
01591    if (iomode_ == sd_serialize) 
01592    {
01593       rc = fwrite(&param, sizeof(Address), 1, f);
01594 
01595       if (1 != rc) 
01596          SER_ERR("fwrite");
01597    }
01598    else 
01599    {
01600        memset(&param, 0, sizeof(Address));
01601       rc = fread(&param, sizeof(Address), 1, f);
01602 
01603       if (1 != rc) 
01604          SER_ERR("fread");
01605    }
01606 
01607    if (noisy)
01608       serialize_printf("%s[%d]:  %sserialize %s=%lx\n", FILE__, __LINE__,
01609             iomode_ == sd_serialize ? "" : "de", 
01610             tag ? tag : "no-tag", param);
01611 }
01612 
01613 void SerDesBin::translate(void * &param, const char *tag)
01614 {
01615    int rc;
01616    if (iomode_ == sd_serialize) 
01617    {
01618       rc = fwrite(&param, sizeof(void *), 1, f);
01619 
01620       if (1 != rc) 
01621          SER_ERR("fwrite");
01622    }
01623    else 
01624    {
01625       rc = fread(&param, sizeof(void *), 1, f);
01626 
01627       if (1 != rc) 
01628          SER_ERR("fread");
01629    }
01630 
01631    if (noisy)
01632       serialize_printf("%s[%d]:  %sserialize %s=%p\n", FILE__, __LINE__,
01633             iomode_ == sd_serialize ? "" : "de", 
01634             tag ? tag : "no-tag", param);
01635 }
01636 
01637 void SerDesBin::translate(const char * &param, int bufsize, const char *tag)
01638 {
01639    //  string output format is
01640    //  [1]  length of string
01641    //  [2]  string data
01642    int rc, len;
01643    if (iomode_ == sd_serialize) 
01644    {
01645       len = strlen(param);
01646 
01647       rc = fwrite( &len, sizeof(int), 1, f);
01648 
01649       if (1 != rc) 
01650          SER_ERR("fwrite");
01651 
01652       rc = fwrite(param, sizeof(char), len, f);
01653 
01654       if (len != rc) 
01655          SER_ERR("fwrite");
01656    }
01657    else 
01658    {
01659       rc = fread(&len, sizeof(int), 1, f);
01660 
01661       if (1 != rc)  
01662       {
01663          fprintf(stderr, "%s[%d]:  fread, got %d not 1: %s\n", FILE__, __LINE__, rc,  strerror(errno));
01664          SER_ERR("fread");
01665       }
01666 
01667       if (len > bufsize) 
01668       {
01669          fprintf(stderr, "%s[%d]:  insufficient buffer: %d, need %d...  truncation....\n", FILE__, __LINE__, bufsize, len);
01670          len = bufsize;
01671 
01672          //char msg[1024];
01673          //snprintf(msg, 1024, "not enough space in string buffer, %d needed", len);
01674          //SER_ERR("msg");
01675       }
01676 
01677       if (len < 0) 
01678       {
01679          fprintf(stderr, "%s[%d]:  bad bufsize %d for %s\n", FILE__, __LINE__, len, tag ? tag : "no_tag");
01680          char msg[1024];
01681          snprintf(msg, 1024, "bad bufsize, %d ", len);
01682          SER_ERR("msg");
01683       }
01684 
01685       char *l_ptr = const_cast<char *> (param);
01686       if (len != 0)
01687       {
01688           rc = fread(l_ptr, sizeof(char), len, f);
01689 
01690           if (len != rc) 
01691           {
01692               fprintf(stderr, "%s[%d]:  fread, got %d not %d: %s\n", 
01693                       FILE__, __LINE__, rc, len, strerror(errno));
01694               SER_ERR("fread");
01695           }
01696       }
01697       else 
01698       {
01699           //  Zero length strings are allowed
01700           //fprintf(stderr, "%s[%d]:  WARN:  zero length string for %s\n", FILE__, __LINE__, tag ? tag : "no_tag_provided");
01701       }
01702 
01703       l_ptr[len] = '\0';
01704 
01705    }
01706 
01707    if (noisy)
01708       serialize_printf("%s[%d]:  %sserialize %s=%s\n", FILE__, __LINE__,
01709             iomode_ == sd_serialize ? "" : "de", 
01710             tag ? tag : "no-tag", param);
01711 }
01712 
01713 void SerDesBin::translate(char * &param, int bufsize, const char *tag)
01714 {
01715    const char * p = const_cast<const char *>(param);
01716    translate(p, bufsize, tag);
01717    param = const_cast<char *>(p);
01718 }
01719 
01720 void SerDesBin::translate(std::string &param, const char *tag)
01721 {
01722    if (iomode_ == sd_serialize) 
01723    {
01724       const char *cstr = param.c_str();
01725       translate(cstr, 0, tag);
01726    }
01727    else 
01728    {
01729       char buf[4096];
01730       const char *buf2 = buf;
01731       translate(buf2, 4096, tag);
01732       param = std::string(buf2);
01733    }
01734    if ((iomode_ == sd_deserialize) ||strstr(param.c_str(), "file")) 
01735    {
01736       serialize_printf("%s[%d]:  %sserializing string %s--%s, len = %lu\n", 
01737             FILE__, __LINE__, (iomode_ == sd_serialize) ? "" : "de", tag ? tag : "unnamed",
01738               param.c_str(), (unsigned long) param.length());
01739    }
01740 }
01741 
01742 void SerDesBin::translate(std::vector<std::string> &param, const char *tag, const char * elem_tag)
01743 {
01744    //  string list output format is
01745    //  [1]  length of list, n
01746    //  [2]  <n> strings
01747 
01748    unsigned long nelem = param.size();
01749    translate(nelem, tag);
01750 
01751    if (iomode_ == sd_serialize) 
01752    {
01753       for (unsigned long i = 0; i < nelem; ++i) 
01754       {
01755          translate(param[i], elem_tag);
01756       }
01757    }
01758    else 
01759    {
01760       param.resize(nelem);
01761       for (unsigned long i = 0; i < nelem; ++i) 
01762       {
01763          param[i] = "";
01764          translate(param[i], elem_tag);
01765       }
01766    }
01767 }
01768 
01769 SerializerBase *Serializable::lookupExistingSerializer()
01770 {
01771     //fprintf(stderr, "%s[%d]:  lookupExistingSerializer: index = %d, serializers.size() = %lu\n", FILE__, __LINE__, active_serializer_index, SerializerBase::active_serializers.size());
01772 
01773     if (active_serializer_index == (unsigned short) -1)
01774         return NULL;
01775 
01776     if (SerializerBase::active_serializers.size() <= active_serializer_index)
01777         return NULL;
01778 
01779     return SerializerBase::active_serializers[active_serializer_index];
01780 }
01781 
01782 namespace Dyninst {
01783 
01784 bool ser_operation(SerializerBase *sb, ser_post_op_t &op, const char *tag)
01785 {
01786     try 
01787     {
01788         gtranslate(sb, op, serPostOp2Str, tag);
01789     }
01790     catch (const Dyninst::SerializerError &)
01791     {   
01792         if (isEOF(sb))
01793         {   
01794             serialize_printf("%s[%d]:  got EOF\n", FILE__, __LINE__);
01795         }   
01796         else
01797         {
01798             fprintf(stderr, "%s[%d]:  SerializerError thrown\n", FILE__, __LINE__);
01799         }
01800         return false;
01801     }
01802     catch (...)
01803     {
01804         fprintf(stderr, "%s[%d]:  Unknown error thrown\n", FILE__, __LINE__);
01805         return false;
01806     }
01807 
01808     return true;
01809 
01810 }
01811 
01812 void throw_ser_err(const char *file__, unsigned int line, const char *msg)
01813 {
01814     throw SerializerError(file__, line, std::string(msg));
01815 }
01816 void serialize_annotatable_id(SerializerBase *sb, void *&id, const char *tag)
01817 {
01818     Address l_id = (Address &)id;
01819     gtranslate(sb, l_id, tag);
01820     id = (void *)l_id;
01821 }
01822 
01823 bool set_sb_annotatable_sparse_map(SerializerBase *sb, AnnotatableSparse *as, void *id)
01824 {
01825     sb->set_annotatable_sparse_map(as, id);
01826     return true;
01827 }
01828 
01829 bool set_sb_annotatable_dense_map(SerializerBase *sb, AnnotatableDense *ad, void *id)
01830 {
01831     sb->set_annotatable_dense_map(ad, id);
01832     return true;
01833 }
01834 
01835 void SerializerBase::set_annotatable_sparse_map(AnnotatableSparse *as, void *id)
01836 {
01837     (*sparse_annotatable_map)[id] = as;
01838 }
01839 
01840 void SerializerBase::set_annotatable_dense_map(AnnotatableDense *ad, void *id)
01841 {
01842     (*dense_annotatable_map)[id] = ad;
01843 }
01844 
01845 unsigned short get_serializer_index(SerializerBase *sb)
01846 {
01847     if (!sb) return (unsigned short) -1;
01848     return sb->getIndex();
01849 }
01850 } // namespace dyninst
01851 
01852 SerializerBase::SerializerBase(SerContextBase *scb, std::string name_, 
01853         std::string filename, 
01854         iomode_t dir, 
01855         bool verbose):
01856     sparse_annotatable_map(NULL),
01857     dense_annotatable_map(NULL)
01858 {
01859     if (!scb)
01860     {
01861         serializer_printf("%s[%d]:  ERROR:  no context for serializer\n", FILE__, __LINE__);
01862         return;
01863     }
01864 
01865     sparse_annotatable_map = new dyn_hash_map<void *, AnnotatableSparse *>();
01866     dense_annotatable_map = new dyn_hash_map<void *, AnnotatableDense *>();
01867     scon = scb;
01868     serializer_name = std::string(name_);
01869 
01870     serialize_printf("%s[%d]:  before new SerFile, scb = %p, name = %s/%s\n", 
01871             FILE__, __LINE__, scb, serializer_name.c_str(), filename.c_str());
01872 
01873     sf = new SerFile(std::string(filename), dir, verbose);
01874     assert(sf);
01875 
01876     sd = sf->getSD();
01877     if (!sd) 
01878     {
01879         fprintf(stderr, "%s[%d]:  failed to get sd here\n", FILE__, __LINE__);
01880     }
01881     assert(scb);
01882 
01883     scb->serfilename = sf->getCacheFileName();
01884     if (dir == sd_serialize)
01885     {
01886         ser_index = (unsigned short) active_serializers.size();
01887         active_serializers.push_back(this);
01888     }
01889 }
01890 
01891 SerializerBase::SerializerBase() : 
01892     ser_index((unsigned short) -1),
01893     sparse_annotatable_map(NULL),
01894     dense_annotatable_map(NULL)
01895 {
01896     fprintf(stderr, "%s[%d]:  WARN:  inside default ctor\n", FILE__, __LINE__);
01897     sparse_annotatable_map = new dyn_hash_map<void *, AnnotatableSparse *>();
01898     dense_annotatable_map = new dyn_hash_map<void *, AnnotatableDense *>();
01899 }
01900 
01901 SerializerBase::~SerializerBase()
01902 {
01903     serialize_printf("%s[%d]:  serializer %p-%sdtor\n", FILE__, __LINE__,
01904             this, serializer_name.c_str());
01905 }
01906 
01907 unsigned short get_serializer_index(SerializerBase *sb)
01908 {
01909     assert(sb);
01910     return sb->getIndex();
01911 }
01912 
01913 unsigned short SerializerBase::getIndex()
01914 {
01915     return ser_index;
01916 }
01917 
01918 void SerializerBase::globalDisable()
01919 {
01920     global_disable = true;
01921 }
01922 bool SerializerBase::serializationDisabled()
01923 {
01924     return global_disable;
01925 }
01926 
01927 void SerializerBase::globalEnable()
01928 {
01929     global_disable = false;
01930 }
01931 
01932 SerContextBase *SerializerBase::getContext() 
01933 {
01934     return scon;
01935 }
01936 
01937 bool SerializerBase::isInput () 
01938 {
01939     return iomode() == sd_deserialize;
01940 }
01941 
01942 bool SerializerBase::isOutput () 
01943 {
01944     return iomode() == sd_serialize;
01945 }
01946 
01947 SerializerBase *SerializerBase::getSerializer(std::string subsystem, std::string fname)
01948 {
01949     dyn_hash_map<std::string, subsystem_serializers_t>::iterator ssiter; 
01950     ssiter = all_serializers.find(subsystem);
01951 
01952     if (ssiter == all_serializers.end()) 
01953     {
01954         fprintf(stderr, "%s[%d]:  no serializer for subsystem %s\n", 
01955                 FILE__, __LINE__, subsystem.c_str());
01956         return NULL;
01957     }
01958 
01959     subsystem_serializers_t &subsys_map = ssiter->second;
01960 
01961     dyn_hash_map<std::string, SerializerBase *>::iterator sbiter;
01962     sbiter = subsys_map.find(fname);
01963     if (sbiter == subsys_map.end()) 
01964     {
01965         fprintf(stderr, "%s[%d]:  no serializer for filename %s\n", 
01966                 FILE__, __LINE__, fname.c_str());
01967         return NULL;
01968     }
01969 
01970     SerializerBase *sb =  sbiter->second;
01971     if (!sb) 
01972     {
01973         fprintf(stderr, "%s[%d]:  ERROR:  NULL serializer\n", FILE__, __LINE__);
01974         return NULL;
01975     }
01976 
01977     return sb;
01978 }
01979 
01980 bool SerializerBase::addSerializer(std::string subsystem, 
01981         std::string fname, SerializerBase *sb)
01982 {
01983    subsystem_serializers_t ss_serializers;
01984    dyn_hash_map<std::string, subsystem_serializers_t>::iterator ssiter; 
01985    ssiter =  all_serializers.find(subsystem);
01986 
01987    if (ssiter == all_serializers.end()) 
01988    {
01989       //  make an entry 
01990       all_serializers[subsystem] = ss_serializers;
01991    }
01992 
01993    ss_serializers = all_serializers[subsystem];
01994 
01995    dyn_hash_map<std::string, SerializerBase *>::iterator sbiter;
01996    sbiter = ss_serializers.find(fname);
01997    if (sbiter != ss_serializers.end()) 
01998    {
01999       serializer_printf("%s[%d]:  already have serializer for filename %s\n", 
02000             FILE__, __LINE__, fname.c_str());
02001       return false;
02002    }
02003 
02004    //  add serializer to map since it does not exist there already
02005 
02006    ss_serializers[fname] = sb;
02007    return true;
02008 }
02009 
02010 iomode_t SerializerBase::iomode()
02011 {
02012    if (sd) 
02013    {
02014       return sd->iomode();
02015    }
02016 
02017    fprintf(stderr, "%s[%d]:  no sd for iomode query\n", FILE__, __LINE__);
02018    return sd_serialize;
02019 }
02020 
02021 void SerializerBase::serialize_annotations(void *id, 
02022         std::vector<ser_rec_t> &sers, const char *tag)
02023 {
02024     Address id_add = (Address) id;
02025 
02026     unsigned long nelem = 0UL;
02027     if (isOutput())
02028         nelem = sers.size();
02029 
02030     getSD().annotation_list_start(id_add, nelem);
02031 
02032     if (nelem)
02033         serialize_printf("%s[%d]:  need to %s %lu annos\n", 
02034                 FILE__, __LINE__, isInput() ? "deserialize" : "serialize", nelem);
02035 
02036     if (sers.size())
02037         serialize_printf( "%s[%d]: serialize_annotations:  %s, id = %p, nelem = %lu\n", 
02038                 FILE__, __LINE__, isInput() ? "deserialize" : "serialize", 
02039                 (void *)id_add, nelem);
02040 
02041     for (unsigned long i = 0; i < nelem; ++i)
02042     {
02043         AnnotationClassBase *acb = NULL;
02044         void *my_anno = NULL;
02045         AnnotationClassID a_id = (AnnotationClassID) -1;
02046         void *lparent_id = NULL;
02047         sparse_or_dense_anno_t lsod = sparse;
02048 
02049         if (isOutput())
02050         {
02051             acb = sers[i].acb;
02052             assert(acb);
02053             a_id = acb->getID();
02054             my_anno = sers[i].data;
02055             lparent_id = sers[i].parent_id;
02056             lsod = sers[i].sod;
02057         }
02058 
02059         getSD().annotation_start(a_id, lparent_id, lsod, acb ? acb->getName().c_str() : NULL);
02060 
02061         if (isInput())
02062         {
02063             acb = AnnotationClassBase::findAnnotationClass(a_id);
02064 
02065             if (!acb)
02066             {
02067                 AnnotationClassBase::dumpAnnotationClasses();
02068                 fprintf(stderr, "%s[%d]:  FIXME:  cannot find annotation class for id %d\n", 
02069                         FILE__, __LINE__, a_id);
02070                 return;
02071             }
02072             else
02073             {
02074                 serialize_printf("%s[%d]:  got annotation type id=%d\n", 
02075                         FILE__, __LINE__, acb->getID());
02076             }
02077 
02078             //  when deserializing, we need to allocate an object
02079             //  of the type of the annotation before deserializing into it.
02080             serialize_printf("%s[%d]:  before allocation\n", FILE__, __LINE__);
02081             my_anno = acb->allocate();
02082             assert(my_anno);
02083 
02084             ser_rec_t sr;
02085             sr.data = my_anno;
02086             sr.acb = acb;
02087             sers.push_back(sr);
02088             serialize_printf("%s[%d]:  created deserialize rec: %p/%p\n", 
02089                     FILE__, __LINE__, my_anno, acb);
02090         }
02091 
02092         ser_func_t sf = acb->getSerializeFunc();
02093 
02094         assert(sf);
02095         assert(my_anno);
02096 
02097         //  execute the serialization function for this annotation
02098         serialize_printf("%s[%d]:  calling serialize func for type %s\n", 
02099                 FILE__, __LINE__, acb->getTypeName());
02100         (*sf)(my_anno, this, tag);
02101 
02102         getSD().annotation_end();
02103     }
02104     getSD().annotation_list_end();
02105 }
02106 
02107 namespace Dyninst {
02108 
02109 void annotation_start(SerializerBase *sb, AnnotationClassID &a_id, 
02110         void *&lparent_id, sparse_or_dense_anno_t &lsod, const char *)
02111 {
02112     sb->annotation_start(a_id, lparent_id, lsod, NULL);
02113     serialize_printf("%s[%d]:  leaving to annotation_start:  id = %d\n", 
02114             FILE__, __LINE__, a_id);
02115 }
02116 
02117 void annotation_end(SerializerBase *sb)
02118 {
02119     sb->annotation_end();
02120 }
02121 
02122 void annotation_container_start(SerializerBase *sb, void *&id)
02123 {
02124     sb->annotation_container_start(id);
02125 }
02126 
02127 void annotation_container_end(SerializerBase *sb)
02128 {
02129     sb->annotation_container_end();
02130 }
02131 
02132 void annotation_container_item_start(SerializerBase *sb, void *&id)
02133 {
02134     sb->annotation_container_item_start(id);
02135 }
02136 
02137 void annotation_container_item_end(SerializerBase *sb)
02138 {
02139     sb->annotation_container_item_end();
02140 }
02141 
02142 void vector_start(SerializerBase *sb, unsigned long &nelem, const char *tag)
02143 {   
02144     sb->vector_start(nelem, tag);
02145 }
02146 
02147 void vector_end(SerializerBase *sb)
02148 {
02149     sb->vector_end();
02150 }
02151 
02152 AnnotationContainerBase * get_container(void *parent_id)
02153 {
02154     AnnotationContainerBase *cont =  AnnotationContainerBase::getContainer(parent_id);
02155     if (!cont)
02156     {
02157         fprintf(stderr, "%s[%d]:  failed to find container with id %p\n", 
02158                 FILE__, __LINE__, parent_id);
02159     }
02160     return cont;
02161 }
02162 
02163 bool deserialize_container_item(AnnotationContainerBase *acb, SerializerBase *sb)
02164 {
02165     if (!acb->deserialize_item(sb))
02166     {
02167         fprintf(stderr, "%s[%d]:  failed to deserialize container item\n", FILE__, __LINE__);
02168         return false;
02169     }
02170     return true;
02171 }
02172 
02173 bool deserialize_container_item(SerializerBase *sb, void *parent_id)
02174 {
02175     AnnotationContainerBase *cont =  AnnotationContainerBase::getContainer(parent_id);
02176     if (!cont)
02177     {
02178         fprintf(stderr, "%s[%d]:  failed to find container with id %p\n", 
02179                 FILE__, __LINE__, parent_id);
02180         return false;
02181     }
02182 
02183     if (!cont->deserialize_item(sb))
02184     {
02185         fprintf(stderr, "%s[%d]:  failed to deserialize container item\n", 
02186                 FILE__, __LINE__);
02187         return false;
02188     }
02189     return true;
02190 
02191 }
02192 
02193 }
02194 
02195 void SerializerBase::annotation_start(AnnotationClassID &a_id, 
02196         void *&lparent_id, sparse_or_dense_anno_t &lsod, const char *)
02197 {
02198     getSD().annotation_start(a_id, lparent_id, lsod, NULL);
02199 
02200     serialize_printf("%s[%d]:  leaving to annotation_start:  id = %d, ser_id = %d\n",
02201             FILE__, __LINE__, a_id, ser_index);
02202 }
02203 
02204 void SerializerBase::annotation_end()
02205 {
02206     getSD().annotation_end();
02207 }
02208 
02209 void SerializerBase::annotation_container_start(void *&id)
02210 {
02211     getSD().annotation_container_start(id);
02212 }
02213 
02214 void SerializerBase::annotation_container_end()
02215 {
02216     getSD().annotation_container_end();
02217 }
02218 
02219 void SerializerBase::annotation_container_item_start(void *&id)
02220 {
02221     getSD().annotation_container_item_start(id);
02222 }
02223 
02224 void SerializerBase::annotation_container_item_end()
02225 {
02226     getSD().annotation_container_item_end();
02227 }
02228 
02229 void SerializerBase::magic_check(const char *file__, unsigned int line__)
02230 {
02231     getSD().magic_check(file__, line__);
02232 }
02233 
02234 bool SerializerBase::serialize_post_annotation(void *parent_id, void *anno, 
02235         AnnotationClassBase *acb, sparse_or_dense_anno_t sod, const char *tag)
02236 {
02237     serialize_printf("%s[%d]: serialize_post_annotation:  ser_id = %d, parent_id = %p\n", 
02238             FILE__, __LINE__, ser_index, parent_id);
02239 
02240     void *my_anno = NULL;
02241     AnnotationClassID a_id;
02242     sparse_or_dense_anno_t lsod = sod;
02243     void *lparent_id = parent_id;
02244 
02245     if (isOutput())
02246     {
02247         assert(acb);
02248         a_id = acb->getID();
02249         assert(anno);
02250         my_anno = anno;
02251     }
02252 
02253     getSD().annotation_start(a_id, lparent_id, lsod, acb ? acb->getName().c_str() : NULL);
02254 
02255     if (isInput())
02256     {
02257         acb = AnnotationClassBase::findAnnotationClass(a_id);
02258 
02259         if (!acb)
02260         {
02261             AnnotationClassBase::dumpAnnotationClasses();
02262             fprintf(stderr, "%s[%d]:  FIXME:  cannot find annotation class for id %d\n", 
02263                     FILE__, __LINE__, a_id);
02264             return false;
02265         }
02266         else
02267         {
02268             fprintf(stderr, "%s[%d]:  got annotation type id=%d\n", 
02269                     FILE__, __LINE__, acb->getID());
02270         }
02271 
02272         //  when deserializing, we need to allocate an object
02273         //  of the type of the annotation before deserializing into it.
02274         my_anno = acb->allocate();
02275         assert(my_anno);
02276         //parent_id = lparent_id;
02277         //sod = lsod;
02278     }
02279 
02280     ser_func_t sf = acb->getSerializeFunc();
02281 
02282     assert(sf);
02283     assert(my_anno);
02284 
02285     //  execute the serialization function for this annotation
02286     serialize_printf("%s[%d]:  calling serialize func for type %s\n", 
02287             FILE__, __LINE__, acb->getTypeName());
02288 
02289     (*sf)(my_anno, this, tag);
02290 
02291         getSD().annotation_end();
02292 
02293         if (isInput())
02294         {
02295             //  we have the (void *) annotation and the annotation type
02296             //  now lookup the object to which it belonged in the map of annotatable objects
02297             //  and add it as an annotation.
02298 
02299             if (lsod == sparse)
02300             {
02301                 dyn_hash_map<void *, AnnotatableSparse *>::iterator iter;
02302                 iter = sparse_annotatable_map->find(lparent_id);
02303                 if (iter == sparse_annotatable_map->end())
02304                 {
02305                     fprintf(stderr, "%s[%d]:  ERROR:  cant find parent to assign anno to\n", 
02306                             FILE__, __LINE__);
02307                 }
02308                 else
02309                 {
02310                     AnnotatableSparse *as = iter->second;
02311                     assert(as);
02312                     assert(acb);
02313                     fprintf(stderr, "%s[%d]:  readding post annotation\n", FILE__, __LINE__);
02314                     if (!as->addAnnotation(my_anno, acb->getID()))
02315                     {
02316                         fprintf(stderr, "%s[%d]:  ERROR:  failed to add annotation here\n", 
02317                                 FILE__, __LINE__);
02318                     }
02319                 }
02320             }
02321             else if (lsod == dense)
02322             {
02323                 dyn_hash_map<void *, AnnotatableDense *>::iterator iter;
02324                 iter = dense_annotatable_map->find(lparent_id);
02325                 if (iter == dense_annotatable_map->end())
02326                 {
02327                     fprintf(stderr, "%s[%d]:  ERROR:  cant find parent to assign anno to\n", 
02328                             FILE__, __LINE__);
02329                 }
02330                 else
02331                 {
02332                     AnnotatableDense *ad = iter->second;
02333                     assert(ad);
02334                     assert(acb);
02335                     fprintf(stderr, "%s[%d]:  readding post annotation\n", FILE__, __LINE__);
02336                     if (!ad->addAnnotation(my_anno, acb->getID()))
02337                     {
02338                         fprintf(stderr, "%s[%d]:  ERROR:  failed to add annotation here\n", 
02339                                 FILE__, __LINE__);
02340                     }
02341                 }
02342             }
02343             else
02344             {
02345                 fprintf(stderr, "%s[%d]:  ERROR:  sparse/dense not set properly\n", 
02346                         FILE__, __LINE__);
02347                 return false;
02348             }
02349         }
02350 
02351         return true;
02352 }
02353 
02354 void SerializerBase::vector_start(unsigned long &size, const char *tag) 
02355 {
02356    getSD().vector_start(size, tag);
02357 }
02358 
02359 
02360 void SerializerBase::vector_end() 
02361 {
02362    getSD().vector_end();
02363 }
02364 
02365 void SerializerBase::hash_map_start(unsigned long &size, const char *tag) 
02366 {
02367    getSD().hash_map_start(size, tag);
02368 }
02369 
02370 void SerializerBase::hash_map_end() 
02371 {
02372    getSD().hash_map_end();
02373 }
02374 
02375 void SerializerBase::multimap_start(unsigned long &size, const char *tag) 
02376 {
02377    getSD().multimap_start(size, tag);
02378 }
02379 
02380 void SerializerBase::multimap_end() 
02381 {
02382    getSD().multimap_end();
02383 }
02384 
02385 void SerializerBase::pair_start(const char *tag) 
02386 {
02387    getSD().pair_start(tag);
02388 }
02389 
02390 SerDes &SerializerBase::getSD()
02391 {
02392     assert(sd);
02393     return *sd;
02394 }
02395 
02396 SerFile &SerializerBase::getSF()
02397 {
02398     assert(sf);
02399     return *sf;
02400 }
02401 
02402 void SerializerBase::pair_end() 
02403 {
02404    getSD().pair_end();
02405 }
02406 
02407 void SerializerBase::translate_base(short &v, const char *&t)
02408 {
02409    getSD().translate(v, t);
02410 }
02411 
02412 void SerializerBase::translate_base(unsigned short &v, const char *&t)
02413 {
02414    getSD().translate(v, t);
02415 }
02416 
02417 void SerializerBase::translate_base(bool &v, const char *&t)
02418 {
02419    getSD().translate(v, t);
02420 }
02421 
02422 void SerializerBase::translate_base(char &v, const char *&t)
02423 {
02424    getSD().translate(v, t);
02425 }
02426 
02427 void SerializerBase::translate_base(int &v, const char *&t)
02428 {
02429    getSD().translate(v, t);
02430 }
02431 
02432 void SerializerBase::translate_base(unsigned int &v, const char *&t)
02433 {
02434    getSD().translate(v, t);
02435 }
02436 
02437 void SerializerBase::translate_base(long &v, const char *&t)
02438 {
02439    getSD().translate(v, t);
02440 }
02441 
02442 void SerializerBase::translate_base(unsigned long &v, const char *&t)
02443 {
02444    getSD().translate(v, t);
02445 }
02446 
02447 void SerializerBase::translate_base(float &v, const char *&t)
02448 {
02449    getSD().translate(v, t);
02450 }
02451 
02452 void SerializerBase::translate_base(double &v, const char *&t)
02453 {
02454    getSD().translate(v, t);
02455 }
02456 
02457 void SerializerBase::translate_base(const char *&v, int bufsize, const char *&t)
02458 {
02459    getSD().translate(v, bufsize, t);
02460 }
02461 
02462 void SerializerBase::translate_base(char *&v, int bufsize, const char *&t)
02463 {
02464    getSD().translate(v, bufsize, t);
02465 }
02466 
02467 void SerializerBase::translate_base(void *&v, const char *&t)
02468 {
02469    getSD().translate(v, t);
02470 }
02471 
02472 void SerializerBase::translate_base(std::string &v, const char *t)
02473 {
02474    getSD().translate(v, t);
02475 }
02476 
02477 #endif
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1