Update copyright to LGPL on all files
[dyninst.git] / common / h / serialize.h
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #ifndef __SERDES_H__
33 #define __SERDES_H__
34 #include "common/h/headers.h"
35
36 #include <string>
37 #include <vector>
38 #include <map>
39 #include <stdexcept>
40 #include <stdio.h>
41
42 #if defined(os_windows)
43 #if defined (cap_have_libxml)
44 #include <libxml/xmlversion.h>
45 #undef LIBXML_ICONV_ENABLED
46 #endif
47 #endif
48
49 #if defined (cap_have_libxml)
50 #include <libxml/xmlwriter.h>
51 #endif
52
53 #include "dynutil/h/util.h"
54 #include "dynutil/h/Annotatable.h"
55 #include "dynutil/h/Serialization.h"
56 #include "common/h/Types.h"
57 #include "common/h/sha1.h"
58 #include "common/h/pathName.h"
59
60
61 #define SERIALIZE_ENABLE_FLAG (short) 1
62 #define DESERIALIZE_ENABLE_FLAG (short) 2
63 #define DESERIALIZE_ENFORCE_FLAG (short) 4
64
65 //  SER_ERR("msg") -- an attempt at "graceful" failure.  If debug flag is set
66 //  it will assert, otherwise it throws...  leaving the "graceful" aspect
67 //  to the next (hopefully top-level) exception handler.
68 //  UPDATE -- due to vtable recognition probs between modules (dyninst libs and
69 //  testsuite executables) no longer asserts.
70
71
72
73 #define SER_ERR(cmsg) \
74         do { \
75                 if (serializer_debug_flag()) { \
76                         serialize_printf("SER_ERR: %s", cmsg); \
77                         throw SerializerError(__FILE__, __LINE__, std::string(cmsg)); \
78                 } else { \
79                         throw SerializerError(__FILE__, __LINE__, std::string(cmsg)); \
80                 } \
81         } while (0)
82
83 namespace Dyninst {
84
85 #define CACHE_DIR_VAR "DYNINST_CACHE_DIR"
86 #define DEFAULT_DYNINST_DIR ".dyninstAPI"
87 #define DEFAULT_CACHE_DIR "caches"
88 #define CACHE_MAGIC 0x555
89 #define CACHE_PREFIX "cache_"
90
91 #ifndef PATH_MAX
92 #define PATH_MAX 512
93 #endif
94
95 //  SER_CATCH("string") is mostly for debugging...  it is just a default catch-block
96 //  that prints out a message and then throws another exception.  The idea is that,
97 //  when an exception is thrown, even though it comes with an informative message,
98 //  it is even more informative to know that call-path that produced it.
99 //  SER_CATCH provides a fairly non-intrusive way to add this functionality
100
101 #define SER_CATCH(x) catch (const SerializerError &err) { \
102    fprintf(stderr, "%s[%d]: %s from %s[%d]\n", FILE__, __LINE__, \
103          err.what(), err.file().c_str(), err.line()); \
104    SER_ERR(x); }
105
106 void COMMON_EXPORT serialize_debug_init();
107
108 class SerDes;
109 class SerFile;
110
111 #if 0
112 class SerializerBase {
113         friend class Serializable;
114
115         public:
116                 static std::vector<SerializerBase *> active_serializers;
117                 //  TODO:  make these private or protected
118                 COMMON_EXPORT static dyn_hash_map<std::string, SerializerBase *> active_bin_serializers;
119                 static bool global_disable;
120         private:
121
122                 SerFile *sf;
123                 SerDes *sd;
124                 SerContextBase *scon;
125                 unsigned short ser_index;
126
127                 std::string serializer_name;
128
129                 typedef dyn_hash_map<std::string, SerializerBase *> subsystem_serializers_t;
130                 COMMON_EXPORT static dyn_hash_map<std::string, subsystem_serializers_t> all_serializers;
131
132                 dyn_hash_map<void *, AnnotatableSparse *> *sparse_annotatable_map;
133                 dyn_hash_map<void *, AnnotatableDense *> *dense_annotatable_map;
134         public:
135                 COMMON_EXPORT void set_annotatable_sparse_map(AnnotatableSparse *, void *);
136                 COMMON_EXPORT void set_annotatable_dense_map(AnnotatableDense *, void *);
137                 COMMON_EXPORT unsigned short getIndex();
138                 COMMON_EXPORT static void globalDisable();
139                 COMMON_EXPORT static bool serializationDisabled();
140                 COMMON_EXPORT static void globalEnable();
141
142                 COMMON_EXPORT virtual bool isXML() = 0;
143                 COMMON_EXPORT virtual bool isBin ()= 0;
144                 COMMON_EXPORT bool isEOF();
145
146                 COMMON_EXPORT SerContextBase *getContext();
147                 COMMON_EXPORT bool isInput ();
148                 COMMON_EXPORT bool isOutput ();
149                 COMMON_EXPORT AnnotatableSparse *findSparseAnnotatable(void *id);
150                 COMMON_EXPORT AnnotatableDense *findDenseAnnotatable(void *id);
151
152                 COMMON_EXPORT static void dumpActiveBinSerializers();
153
154                 COMMON_EXPORT SerializerBase(SerContextBase *scb, std::string name_, std::string filename, 
155                                 iomode_t dir, bool verbose);
156
157                 COMMON_EXPORT SerializerBase();
158
159                 COMMON_EXPORT virtual ~SerializerBase();
160
161                 COMMON_EXPORT virtual SerDes &getSD()  { assert(sd); return *sd;}
162                 COMMON_EXPORT SerFile &getSF() {assert(sf); return *sf;}
163                 COMMON_EXPORT std::string &name() {return serializer_name;}
164                 COMMON_EXPORT static SerializerBase *getSerializer(std::string subsystem, std::string fname);
165                 COMMON_EXPORT static bool addSerializer(std::string subsystem, std::string fname, SerializerBase *sb);
166
167                 COMMON_EXPORT virtual void vector_start(unsigned int &, const char * = NULL);
168                 COMMON_EXPORT virtual void vector_end();
169                 COMMON_EXPORT virtual void hash_map_start(unsigned int &size, const char *tag = NULL);
170                 COMMON_EXPORT virtual void hash_map_end();
171                 COMMON_EXPORT virtual void annotation_start(AnnotationClassID &a_id, void *&lparent_id, sparse_or_dense_anno_t &lsod, const char *);
172                 COMMON_EXPORT virtual void annotation_end();
173                 COMMON_EXPORT virtual void annotation_container_start(void *&id);
174                 COMMON_EXPORT virtual void annotation_container_end();
175                 COMMON_EXPORT virtual void annotation_container_item_start(void *&id);
176                 COMMON_EXPORT virtual void annotation_container_item_end();
177                 COMMON_EXPORT void translate_base(bool &v, const char *&t);
178                 COMMON_EXPORT void translate_base(short &v, const char *&t);
179                 COMMON_EXPORT void translate_base(unsigned short &v, const char *&t);
180                 COMMON_EXPORT void translate_base(char &v, const char *&t);
181                 COMMON_EXPORT void translate_base(int &v, const char *&t);
182                 COMMON_EXPORT void translate_base(unsigned int &v, const char *&t);
183                 COMMON_EXPORT void translate_base(unsigned long &v, const char *&t);
184                 COMMON_EXPORT void translate_base(long &v, const char *&t);
185                 COMMON_EXPORT void translate_base(float &v, const char *&t);
186                 COMMON_EXPORT void translate_base(double &v, const char *&t);
187                 COMMON_EXPORT void translate_base(const char * &v, int bufsize, const char *&t);
188                 COMMON_EXPORT void translate_base(char * &v, int bufsize, const char *&t);
189                 COMMON_EXPORT void translate_base(void * &v, const char *&t);
190                 COMMON_EXPORT void translate_base(std::string &v, const char *t);
191
192                 COMMON_EXPORT virtual iomode_t iomode();
193
194                 COMMON_EXPORT void serialize_annotations(void *, std::vector<ser_rec_t> &sers, const char * = NULL);
195                 COMMON_EXPORT bool serialize_post_annotation(void *parent_id, void *anno, AnnotationClassBase *acb, sparse_or_dense_anno_t , const char * = NULL);
196 };
197 #endif
198
199 class SerDesXML;
200
201 class SerializerXML : public SerializerBase
202 {
203         public:
204                 COMMON_EXPORT virtual bool isXML() {return true;}
205                 COMMON_EXPORT virtual bool isBin () {return false;}
206
207                 COMMON_EXPORT SerializerXML(SerContextBase *sc, std::string name_, std::string filename,
208                                 iomode_t dir, bool verbose) :
209                         SerializerBase(sc, name_, filename, dir, verbose) {}
210
211                 COMMON_EXPORT virtual ~SerializerXML() {}
212
213                 COMMON_EXPORT SerDesXML &getSD_xml();
214
215                 COMMON_EXPORT static bool start_xml_element(SerializerBase *sb, const char *tag);
216                 COMMON_EXPORT static bool end_xml_element(SerializerBase *sb, const char *);
217 };
218
219 class SerDesBin;
220
221 class SerializerBin : public SerializerBase {
222         friend class SerDesBin;
223
224         public:
225         COMMON_EXPORT virtual bool isXML() {return false;}
226         COMMON_EXPORT virtual bool isBin () {return true;}
227
228         COMMON_EXPORT SerializerBin()  :
229                 SerializerBase() {}
230
231
232         COMMON_EXPORT SerializerBin(SerContextBase *s, std::string name_, std::string filename,
233                         iomode_t dir, bool verbose);
234
235         COMMON_EXPORT virtual ~SerializerBin();
236
237         COMMON_EXPORT SerDesBin &getSD_bin();
238
239 #if 0
240         static SerializerBin *findSerializerByName(const char *name_);
241 #endif
242
243 };
244
245
246 #if 0
247         class SerializerBase {
248
249                 public:
250                         //  TODO:  make these private or protected
251                         COMMON_EXPORT static dyn_hash_map<std::string, SerializerBase *> active_bin_serializers;
252                         static bool global_disable;
253                 private:
254
255                         SerFile *sf;
256                         SerDes *sd;
257                         SerContextBase *scon;
258
259                 std::string serializer_name;
260
261                 typedef dyn_hash_map<std::string, SerializerBase *> subsystem_serializers_t;
262                 COMMON_EXPORT static dyn_hash_map<std::string, subsystem_serializers_t> all_serializers;
263
264         public:
265                 COMMON_EXPORT static void globalDisable()
266                 {
267                         global_disable = true;
268                 }
269                 COMMON_EXPORT static bool serializationDisabled()
270    {
271            return global_disable; 
272    }
273
274    COMMON_EXPORT static void globalEnable()
275    {
276            global_disable = false;
277    }
278
279    COMMON_EXPORT SerContextBase *getContext() {return scon;}
280    COMMON_EXPORT virtual bool isXML() = 0;
281    COMMON_EXPORT virtual bool isBin ()= 0;
282    COMMON_EXPORT bool isInput () {return iomode() == sd_deserialize;}
283    COMMON_EXPORT bool isOutput () {return iomode() == sd_serialize;}
284
285    COMMON_EXPORT static void dumpActiveBinSerializers();
286
287    COMMON_EXPORT SerializerBase(SerContextBase *scb, const char *name_, std::string filename, 
288          iomode_t dir, bool verbose); 
289
290    COMMON_EXPORT SerializerBase();
291    
292    COMMON_EXPORT virtual ~SerializerBase() 
293    {
294       serialize_printf("%s[%d]:  serializer %p-%sdtor\n", FILE__, __LINE__, 
295             this, serializer_name.c_str());
296    }
297
298    COMMON_EXPORT virtual SerDes &getSD()  { assert(sd); return *sd;}
299    COMMON_EXPORT SerFile &getSF() {assert(sf); return *sf;}
300    COMMON_EXPORT std::string &name() {return serializer_name;}
301    COMMON_EXPORT static SerializerBase *getSerializer(std::string subsystem, std::string fname);
302    COMMON_EXPORT static bool addSerializer(std::string subsystem, std::string fname, SerializerBase *sb);
303
304    COMMON_EXPORT virtual void vector_start(unsigned int &, const char * = NULL);
305    COMMON_EXPORT virtual void vector_end();
306    COMMON_EXPORT virtual void hash_map_start(unsigned int &size, const char *tag = NULL); 
307    COMMON_EXPORT virtual void hash_map_end();
308    COMMON_EXPORT void translate_base(bool &v, const char *&t);
309    COMMON_EXPORT void translate_base(short &v, const char *&t);
310    COMMON_EXPORT void translate_base(char &v, const char *&t);
311    COMMON_EXPORT void translate_base(int &v, const char *&t);
312    COMMON_EXPORT void translate_base(unsigned int &v, const char *&t);
313    COMMON_EXPORT void translate_base(unsigned long &v, const char *&t);
314    COMMON_EXPORT void translate_base(long &v, const char *&t);
315    COMMON_EXPORT void translate_base(float &v, const char *&t);
316    COMMON_EXPORT void translate_base(double &v, const char *&t);
317    COMMON_EXPORT void translate_base(const char * &v, int bufsize, const char *&t);
318    COMMON_EXPORT void translate_base(char * &v, int bufsize, const char *&t);
319    COMMON_EXPORT void translate_base(void * &v, const char *&t);
320    COMMON_EXPORT void translate_base(std::string &v, const char *t);
321
322    COMMON_EXPORT virtual iomode_t iomode(); 
323
324    protected:
325
326
327 };
328 #endif
329
330 class SerDes {
331
332         //  SerDes is a base class that provides generic serialization/deserialization
333         //  access primitives and a common interface, (a toolbox, if you will).
334         //  It is specialized (currently) by SerDesBin and SerDesXML, which implement the 
335         //  actual low-level ser-des routines 
336
337         //  anno_funcs is a mapping of annotation type
338         //  onto functions used to deserialize that type of annotation
339         //  NOTE:  annotation types identifiers might not be consistent between different
340         //  runs of dyninst, since annotation name->type mapping is determined dynamically
341         //  at runtime.  Thus, when deserializing annotations, a new mapping will have to be 
342    //  constructed.
343
344    public:
345
346 #if 0
347       COMMON_EXPORT static dyn_hash_map<std::string, AnnoFunc > anno_funcs;
348
349       //  old_anno_name_to_id_map keeps a running mapping of 
350       //  annotation names onto annotation ids that was used when building
351       //  the file that is being deserialized.  This info is used to 
352       //  rebuild annotations information, the name<->type mapping may change
353       //  between different runs of dyninst.
354       dyn_hash_map<unsigned, std::string> old_anno_name_to_id_map;
355 #endif
356
357    protected:
358
359       iomode_t iomode_;
360
361    public:
362
363 #if 0
364       COMMON_EXPORT AnnoFunc *findAnnoFunc(unsigned anno_type, 
365             std::string anno_name = AnnotatableBase::emptyString);
366
367       COMMON_EXPORT static bool addAnnoFunc(std::string type_name, AnnoFunc sf);
368 #endif
369
370       COMMON_EXPORT SerDes() {assert(0);}
371       COMMON_EXPORT SerDes(iomode_t mode) : iomode_(mode){}
372       COMMON_EXPORT virtual ~SerDes() {}
373
374       COMMON_EXPORT virtual void file_start(std::string &/*full_file_path*/) {}
375       COMMON_EXPORT virtual void vector_start(unsigned long &size, 
376             const char *tag = NULL) DECLTHROW(SerializerError) = 0;
377       COMMON_EXPORT virtual void vector_end() = 0;
378       COMMON_EXPORT virtual void multimap_start(unsigned long &size, 
379             const char *tag = NULL) DECLTHROW(SerializerError) = 0;
380       COMMON_EXPORT virtual void multimap_end() = 0;
381           COMMON_EXPORT virtual void pair_start( 
382                           const char *tag = NULL) DECLTHROW(SerializerError) = 0;
383           COMMON_EXPORT virtual void pair_end() = 0;
384       COMMON_EXPORT virtual void hash_map_start(unsigned long &size, 
385             const char *tag = NULL) DECLTHROW(SerializerError) = 0;
386       COMMON_EXPORT virtual void hash_map_end() = 0;
387       COMMON_EXPORT virtual void annotation_start(Dyninst::AnnotationClassID &a_id, void *&parent_id, sparse_or_dense_anno_t &, const char *string_id, 
388             const char *tag = "Annotation") = 0;
389       COMMON_EXPORT virtual void annotation_end() = 0;
390
391       COMMON_EXPORT virtual void annotation_container_start(void *&id) = 0;
392       COMMON_EXPORT virtual void annotation_container_end() = 0;
393       COMMON_EXPORT virtual void annotation_container_item_start(void *&id) = 0;
394       COMMON_EXPORT virtual void annotation_container_item_end() = 0;
395       COMMON_EXPORT virtual void annotation_list_start(Address &id, unsigned long &nelem,
396             const char *tag = "AnnotationList") = 0;
397       COMMON_EXPORT virtual void annotation_list_end() = 0;
398
399       COMMON_EXPORT virtual void translate(bool &param, const char *tag = NULL) = 0;
400       COMMON_EXPORT virtual void translate(char &param, const char *tag = NULL) = 0;
401       COMMON_EXPORT virtual void translate(int &param, const char *tag = NULL) = 0;
402       COMMON_EXPORT virtual void translate(long &param, const char *tag = NULL) = 0;
403       //COMMON_EXPORT virtual void translate(unsigned long &param, const char *tag = NULL);
404       COMMON_EXPORT virtual void translate(short &param, const char *tag = NULL) = 0;
405       COMMON_EXPORT virtual void translate(unsigned short &param, const char *tag = NULL) = 0; 
406       COMMON_EXPORT virtual void translate(unsigned int &param, const char *tag = NULL) = 0;
407       COMMON_EXPORT virtual void translate(float &param, const char *tag = NULL) = 0;
408       COMMON_EXPORT virtual void translate(double &param, const char *tag = NULL) = 0;
409       COMMON_EXPORT virtual void translate(Address &param, const char *tag = NULL) = 0;
410       COMMON_EXPORT virtual void translate(void * &param, const char *tag = NULL) = 0;
411       COMMON_EXPORT virtual void translate(const char * &param, int bufsize = 0, 
412             const char *tag = NULL) = 0;
413       COMMON_EXPORT virtual void translate(char * &param, int bufsize = 0, 
414             const char *tag = NULL) = 0;
415       COMMON_EXPORT virtual void translate(std::string &param, const char *tag = NULL) = 0;
416       COMMON_EXPORT virtual void translate(std::vector<std::string> &param, const char *tag = NULL,
417             const char *elem_tag = NULL) = 0;
418           COMMON_EXPORT virtual void magic_check(const char *file__, unsigned int line__) = 0; 
419
420       COMMON_EXPORT virtual iomode_t iomode() {return iomode_;} 
421       COMMON_EXPORT virtual bool isEOF() {return false;} 
422 };
423
424 class SerDesXML : public SerDes {
425    friend class SerFile;
426    friend class SerializerXML;
427    friend bool COMMON_EXPORT ifxml_start_element(SerializerBase *, const char *);
428    friend bool COMMON_EXPORT ifxml_end_element(SerializerBase *, const char *);
429    friend bool COMMON_EXPORT start_xml_elem(SerDesXML &, const char *);
430    friend bool COMMON_EXPORT end_xml_elem(SerDesXML &);
431
432
433
434 #if defined (cap_have_libxml)
435       xmlTextWriterPtr writer;
436       COMMON_EXPORT SerDesXML(xmlTextWriterPtr w, iomode_t mode)  : SerDes(mode), writer(w) { }
437       COMMON_EXPORT static xmlTextWriterPtr init(std::string fname, iomode_t mode, bool verbose);
438 #else
439       void *writer;
440       COMMON_EXPORT SerDesXML(void * w, iomode_t mode)  : SerDes(mode), writer(w) { }
441 #endif
442
443    public:
444       COMMON_EXPORT SerDesXML() { assert(0);}
445       COMMON_EXPORT virtual ~SerDesXML();
446
447       COMMON_EXPORT virtual void vector_start(unsigned long &size, 
448             const char *tag = NULL) DECLTHROW(SerializerError);
449       COMMON_EXPORT virtual void vector_end();
450       COMMON_EXPORT virtual void multimap_start(unsigned long &size, 
451             const char *tag = NULL) DECLTHROW(SerializerError);
452       COMMON_EXPORT virtual void multimap_end();
453           COMMON_EXPORT virtual void pair_start( 
454                           const char *tag = NULL) DECLTHROW(SerializerError);
455           COMMON_EXPORT virtual void pair_end();
456       COMMON_EXPORT virtual void hash_map_start(unsigned long &size, 
457             const char *tag = NULL) DECLTHROW(SerializerError);
458       COMMON_EXPORT virtual void hash_map_end();
459       COMMON_EXPORT virtual void annotation_start(Dyninst::AnnotationClassID &a_id, void *&, sparse_or_dense_anno_t &, const char *string_id, const char *tag = NULL);
460       COMMON_EXPORT virtual void annotation_end();
461       COMMON_EXPORT virtual void annotation_container_start(void *&id);
462       COMMON_EXPORT virtual void annotation_container_end();
463       COMMON_EXPORT virtual void annotation_container_item_start(void *&id);
464       COMMON_EXPORT virtual void annotation_container_item_end();
465       COMMON_EXPORT virtual void annotation_list_start(Address &id, unsigned long &nelem,
466             const char *tag = "AnnotationList");
467       COMMON_EXPORT virtual void annotation_list_end();
468       COMMON_EXPORT virtual void translate(bool &param, const char *tag = NULL);
469       COMMON_EXPORT virtual void translate(char &param, const char *tag = NULL);
470       COMMON_EXPORT virtual void translate(int &param, const char *tag = NULL);
471       COMMON_EXPORT virtual void translate(long &param, const char *tag = NULL);
472       COMMON_EXPORT virtual void translate(short &param, const char *tag = NULL);
473       COMMON_EXPORT virtual void translate(unsigned short &param, const char *tag = NULL);
474       COMMON_EXPORT virtual void translate(unsigned int &param, const char *tag = NULL);
475       COMMON_EXPORT virtual void translate(float &param, const char *tag = NULL);
476       COMMON_EXPORT virtual void translate(double &param, const char *tag = NULL);
477       COMMON_EXPORT virtual void translate(Address &param, const char *tag = NULL);
478       COMMON_EXPORT virtual void translate(void * &param, const char *tag = NULL);
479       COMMON_EXPORT virtual void translate(const char * &param, int bufsize = 0, 
480             const char *tag = NULL);
481       COMMON_EXPORT virtual void translate(char * &param, int bufsize = 0, const char *tag = NULL);
482       COMMON_EXPORT virtual void translate(std::string &param, const char *tag = NULL);
483       COMMON_EXPORT virtual void translate(std::vector<std::string> &param, const char *tag = NULL,
484             const char *elem_tag = NULL);
485           COMMON_EXPORT virtual void magic_check(const char *, unsigned int ) {}
486
487 #if 0
488       COMMON_EXPORT void start_element(const char *tag);
489       COMMON_EXPORT void end_element();
490       COMMON_EXPORT void xml_value(const char *val, const char *tag);
491 #endif
492 };
493
494 //class AnnotatableBase;
495
496 class SerDesBin : public SerDes {
497
498    typedef struct {
499       unsigned int cache_magic;
500       unsigned int source_file_size; //  if size is different, don't bother with checksum
501       char sha1[SHA1_DIGEST_LEN*2];
502    } cache_header_t;
503
504    FILE *f;
505
506    bool noisy;
507
508    public:
509
510    //COMMON_EXPORT static dyn_hash_map<Address, AnnotatableBase *> annotatable_id_map;
511    COMMON_EXPORT static FILE *init(std::string fname, iomode_t mode, bool verbose);
512
513    COMMON_EXPORT SerDesBin() {assert(0);}
514
515    COMMON_EXPORT SerDesBin(FILE *ff, iomode_t mode, bool verbose = false) : 
516       SerDes(mode), 
517       f(ff),  
518       noisy(verbose) {}
519
520    COMMON_EXPORT virtual ~SerDesBin();
521
522    COMMON_EXPORT bool isEOF();
523    //COMMON_EXPORT static AnnotatableBase *findAnnotatee(void *id); 
524
525    COMMON_EXPORT virtual void file_start(std::string &full_file_path);
526    COMMON_EXPORT virtual void vector_start(unsigned long &size, 
527          const char *tag = NULL) DECLTHROW(SerializerError);
528    COMMON_EXPORT virtual void vector_end();
529    COMMON_EXPORT virtual void multimap_start(unsigned long &size, 
530          const char *tag = NULL) DECLTHROW(SerializerError);
531    COMMON_EXPORT virtual void multimap_end();
532    COMMON_EXPORT virtual void pair_start( 
533          const char *tag = NULL) DECLTHROW(SerializerError);
534    COMMON_EXPORT virtual void pair_end();
535    COMMON_EXPORT virtual void hash_map_start(unsigned long &size, 
536          const char *tag = NULL) DECLTHROW(SerializerError);
537    COMMON_EXPORT virtual void hash_map_end();
538    COMMON_EXPORT virtual void annotation_start(Dyninst::AnnotationClassID &a_id, void *&, sparse_or_dense_anno_t &, const char *string_id, const char *tag = NULL);
539    COMMON_EXPORT virtual void annotation_end();
540    COMMON_EXPORT virtual void annotation_container_start(void *&id);
541    COMMON_EXPORT virtual void annotation_container_end();
542    COMMON_EXPORT virtual void annotation_container_item_start(void *&id);
543    COMMON_EXPORT virtual void annotation_container_item_end();
544    COMMON_EXPORT virtual void annotation_list_start(Address &id, unsigned long &nelem,
545                    const char *tag = "AnnotationList");
546    COMMON_EXPORT virtual void annotation_list_end();
547    COMMON_EXPORT virtual void translate(bool &param, const char *tag = NULL);
548    COMMON_EXPORT virtual void translate(char &param, const char *tag = NULL);
549    COMMON_EXPORT virtual void translate(int &param, const char *tag = NULL);
550    COMMON_EXPORT virtual void translate(long &param, const char *tag = NULL);
551    COMMON_EXPORT virtual void translate(short &param, const char *tag = NULL);
552    COMMON_EXPORT virtual void translate(unsigned short &param, const char *tag = NULL);
553    COMMON_EXPORT virtual void translate(unsigned int &param, const char *tag = NULL);
554    COMMON_EXPORT virtual void translate(float &param, const char *tag = NULL);
555    COMMON_EXPORT virtual void translate(double &param, const char *tag = NULL);
556    COMMON_EXPORT virtual void translate(Address &param, const char *tag = NULL);
557    COMMON_EXPORT virtual void translate(void * &param, const char *tag = NULL);
558    COMMON_EXPORT virtual void translate(const char * &param, 
559          int bufsize = 0, const char *tag = NULL);
560    COMMON_EXPORT virtual void translate(char * &param, int bufsize = 0, const char *tag = NULL);
561    COMMON_EXPORT virtual void translate(std::string &param, const char *tag = NULL);
562    COMMON_EXPORT virtual void translate(std::vector<std::string> &param, const char *tag = NULL,
563          const char *elem_tag = NULL);
564    COMMON_EXPORT virtual void magic_check(const char *file__, unsigned int line__);
565
566    // readHeaderAndVerify just opens, verifies (checksum, magic compare), and closes
567    // cache file, unless the FILE * is provided, in which case the file pointer is
568    // advanced past the preamble and is not closed;
569
570    COMMON_EXPORT static void readHeaderAndVerify(std::string full_file_path, 
571          std::string cache_name, FILE *f = NULL);
572
573    COMMON_EXPORT static void writeHeaderPreamble(FILE *f, std::string full_file_path, 
574          std::string cache_name);
575
576    COMMON_EXPORT static bool getDefaultCacheDir(std::string &cache_dir);
577    COMMON_EXPORT static bool resolveCachePath(std::string fname, std::string &cache_name);
578    COMMON_EXPORT static bool verifyChecksum(std::string &filename, 
579          const char comp_checksum[SHA1_DIGEST_LEN]);
580    COMMON_EXPORT static bool cacheFileExists(std::string fname);
581    COMMON_EXPORT static bool invalidateCache(std::string cache_name);
582
583 };
584
585 bool start_xml_elem(void *writer, const char *tag);
586 bool end_xml_elem(void *);
587
588 class SerFile {
589
590    SerDes *sd;
591 #if defined (cap_have_libxml)
592    xmlTextWriterPtr writer;
593 #else
594    void * writer;
595 #endif
596    FILE *f;
597
598    public:
599
600    COMMON_EXPORT SerDes *getSD();
601    COMMON_EXPORT SerFile(std::string fname, iomode_t mode, bool verbose = false); 
602    COMMON_EXPORT iomode_t iomode();
603
604    static bool validCacheExistsFor(std::string full_file_path);
605
606    protected:
607
608    std::string filename;
609    iomode_t iomode_;
610
611    public:
612
613    bool noisy;
614    std::string getFileName() {return filename;}
615    std::string getCacheFileName(); 
616
617 };
618
619 template <class S, class T>
620 class SpecAdaptor {
621
622    public:
623
624       COMMON_EXPORT SpecAdaptor() {}
625
626       COMMON_EXPORT T *operator()(S *s, T &t, const char *tag) 
627       {
628          s->translate_base(t, tag);
629          return &t;
630       }
631 };
632
633 template <class S, class T>
634 class SpecAdaptor<S, T *> {
635
636    public:
637
638       COMMON_EXPORT SpecAdaptor() {}
639
640       COMMON_EXPORT T* operator()(S *s, T *t, const char *tag) 
641       {
642          assert(t);
643          assert(s);
644          s->translate_base(*t, tag);
645          return t;
646       }
647 };
648
649 template <class S, class T> 
650 void sd_translate(S *sd, T &it, const char * tag) 
651 {
652    fprintf(stderr, "%s[%d]:  welcome to sd_translate<%s, %s>(%p)\n", 
653          FILE__, __LINE__, 
654          typeid(S).name(), 
655          typeid(T).name(), &it);
656
657    SpecAdaptor<S,T> saf;
658
659    if (NULL == saf(sd, it, tag)) 
660    {
661       fprintf(stderr, "%s[%d]:  ERROR here\n", FILE__, __LINE__);
662    }
663
664    return;
665 }
666
667
668 #if 0
669 template<class S, class T, class TT2> 
670 class trans_adaptor<S, dyn_hash_map<T, TT2> > {
671
672    public:
673
674       COMMON_EXPORT trans_adaptor() 
675       {
676          fprintf(stderr, "%s[%d]:  welcome to trans_adaptor<%s, hash<%s, %s> >()\n",
677                FILE__, __LINE__,
678                typeid(S).name(),
679                typeid(T).name(), typeid(TT2).name() );
680       }
681
682       COMMON_EXPORT dyn_hash_map<T, TT2> * operator()(S *ser, dyn_hash_map<T, TT2> &m, 
683             const char *tag = NULL, const char *tag2 = NULL) 
684       {
685          fprintf(stderr, "%s[%d]:  hash_size = %d\n", FILE__, __LINE__, m.size());
686          translate_hash_map(ser, m, tag, tag2);
687
688          //  maybe catch errors here?
689          return &m;
690       }
691 };
692 #endif
693
694
695
696 #if 0
697 class SerTest : public Serializable {
698
699    int my_int;
700
701    public:
702
703    SerTest() 
704    { 
705       my_int = 777;
706    }
707
708    ~SerTest() {}
709
710    void serialize(SerializerBase *s, const char * = NULL) 
711    {
712       try 
713       {
714          gtranslate(s, my_int);
715       }  SER_CATCH("SerTest");
716    }
717
718    void testit() 
719    {
720       SerializerBase sb("SerTest", std::string("boogabooga"), sd_serialize, true);
721       serialize( &sb);
722    }
723 };
724 #endif
725 } /*namespace Dyninst*/
726 #endif