windows build fixes and some more work on symtab serialization
[dyninst.git] / common / h / serialize.h
1 /*
2  * Copyright (c) 1996-2007 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 namespace Dyninst {
61
62 #define CACHE_DIR_VAR "DYNINST_CACHE_DIR"
63 #define DEFAULT_DYNINST_DIR ".dyninstAPI"
64 #define DEFAULT_CACHE_DIR "caches"
65 #define CACHE_MAGIC 0x555
66 #define CACHE_PREFIX "cache_"
67
68 #ifndef PATH_MAX
69 #define PATH_MAX 512
70 #endif
71
72 //  SER_CATCH("string") is mostly for debugging...  it is just a default catch-block
73 //  that prints out a message and then throws another exception.  The idea is that,
74 //  when an exception is thrown, even though it comes with an informative message,
75 //  it is even more informative to know that call-path that produced it.
76 //  SER_CATCH provides a fairly non-intrusive way to add this functionality
77
78 #define SER_CATCH(x) catch (const SerializerError &err) { \
79    fprintf(stderr, "%s[%d]: %s from %s[%d]\n", FILE__, __LINE__, \
80          err.what(), err.file().c_str(), err.line()); \
81    SER_ERR(x); }
82
83 void COMMON_EXPORT serialize_debug_init();
84
85 class SerDes;
86 class SerFile;
87
88 class SerializerBase {
89
90         public:
91                 //  TODO:  make these private or protected
92    COMMON_EXPORT static dyn_hash_map<std::string, SerializerBase *> active_bin_serializers;
93    static bool global_disable;
94         private:
95
96    SerFile *sf;
97    SerDes *sd;
98
99    std::string serializer_name;
100
101    typedef dyn_hash_map<std::string, SerializerBase *> subsystem_serializers_t;
102    COMMON_EXPORT static dyn_hash_map<std::string, subsystem_serializers_t> all_serializers;
103
104    public:
105    COMMON_EXPORT static void globalDisable()
106    {
107            global_disable = true;
108    }
109    COMMON_EXPORT static bool serializationDisabled()
110    {
111            return global_disable; 
112    }
113
114    COMMON_EXPORT static void globalEnable()
115    {
116            global_disable = false;
117    }
118    COMMON_EXPORT virtual bool isXML() = 0;
119    COMMON_EXPORT virtual bool isBin ()= 0;
120    COMMON_EXPORT bool isInput () {return iomode() == sd_deserialize;}
121    COMMON_EXPORT bool isOutput () {return iomode() == sd_serialize;}
122
123    COMMON_EXPORT static void dumpActiveBinSerializers();
124
125    COMMON_EXPORT SerializerBase(const char *name_, std::string filename, 
126          iomode_t dir, bool verbose); 
127
128    COMMON_EXPORT SerializerBase();
129    
130    COMMON_EXPORT virtual ~SerializerBase() 
131    {
132       fprintf(stderr, "%s[%d]:  serializer %p-%sdtor\n", FILE__, __LINE__, 
133             this, serializer_name.c_str());
134    }
135
136    COMMON_EXPORT virtual SerDes &getSD()  { assert(sd); return *sd;}
137    COMMON_EXPORT SerFile &getSF() {assert(sf); return *sf;}
138    COMMON_EXPORT std::string &name() {return serializer_name;}
139    COMMON_EXPORT static SerializerBase *getSerializer(std::string subsystem, std::string fname);
140    COMMON_EXPORT static bool addSerializer(std::string subsystem, std::string fname, SerializerBase *sb);
141
142    COMMON_EXPORT virtual void vector_start(unsigned int &, const char * = NULL);
143    COMMON_EXPORT virtual void vector_end();
144    COMMON_EXPORT virtual void hash_map_start(unsigned int &size, const char *tag = NULL); 
145    COMMON_EXPORT virtual void hash_map_end();
146    COMMON_EXPORT void translate_base(bool &v, const char *&t);
147    COMMON_EXPORT void translate_base(short &v, const char *&t);
148    COMMON_EXPORT void translate_base(char &v, const char *&t);
149    COMMON_EXPORT void translate_base(int &v, const char *&t);
150    COMMON_EXPORT void translate_base(unsigned int &v, const char *&t);
151    COMMON_EXPORT void translate_base(unsigned long &v, const char *&t);
152    COMMON_EXPORT void translate_base(long &v, const char *&t);
153    COMMON_EXPORT void translate_base(float &v, const char *&t);
154    COMMON_EXPORT void translate_base(double &v, const char *&t);
155    COMMON_EXPORT void translate_base(const char * &v, int bufsize, const char *&t);
156    COMMON_EXPORT void translate_base(char * &v, int bufsize, const char *&t);
157    COMMON_EXPORT void translate_base(std::string &v, const char *t);
158
159    COMMON_EXPORT virtual iomode_t iomode(); 
160
161    protected:
162
163
164 };
165
166
167 template <class T>
168 class ScopedSerializerBase : public SerializerBase
169 {
170         T *scope;
171         public:
172         ScopedSerializerBase(T *scope_, const char *name_, std::string filename, 
173                         iomode_t dir, bool verbose) :
174                 SerializerBase(name_, filename, dir, verbose), scope(scope_) {}
175         ScopedSerializerBase(T *scope_) :
176                 SerializerBase(), scope(scope_) {}
177         virtual ~ScopedSerializerBase() {}
178         T *getScope() {return scope;}
179 };
180
181
182 class SerDes {
183
184         //  SerDes is a base class that provides generic serialization/deserialization
185         //  access primitives and a common interface, (a toolbox, if you will).
186         //  It is specialized (currently) by SerDesBin and SerDesXML, which implement the 
187         //  actual low-level ser-des routines 
188
189         //  anno_funcs is a mapping of annotation type
190         //  onto functions used to deserialize that type of annotation
191         //  NOTE:  annotation types identifiers might not be consistent between different
192         //  runs of dyninst, since annotation name->type mapping is determined dynamically
193         //  at runtime.  Thus, when deserializing annotations, a new mapping will have to be 
194    //  constructed.
195
196    public:
197
198 #if 0
199       COMMON_EXPORT static dyn_hash_map<std::string, AnnoFunc > anno_funcs;
200
201       //  old_anno_name_to_id_map keeps a running mapping of 
202       //  annotation names onto annotation ids that was used when building
203       //  the file that is being deserialized.  This info is used to 
204       //  rebuild annotations information, the name<->type mapping may change
205       //  between different runs of dyninst.
206       dyn_hash_map<unsigned, std::string> old_anno_name_to_id_map;
207 #endif
208
209    protected:
210
211       iomode_t iomode_;
212
213    public:
214
215 #if 0
216       COMMON_EXPORT AnnoFunc *findAnnoFunc(unsigned anno_type, 
217             std::string anno_name = AnnotatableBase::emptyString);
218
219       COMMON_EXPORT static bool addAnnoFunc(std::string type_name, AnnoFunc sf);
220 #endif
221
222       COMMON_EXPORT SerDes() {assert(0);}
223       COMMON_EXPORT SerDes(iomode_t mode) : iomode_(mode){}
224       COMMON_EXPORT virtual ~SerDes() {}
225
226       COMMON_EXPORT virtual void file_start(std::string &/*full_file_path*/) {}
227       COMMON_EXPORT virtual void vector_start(unsigned int &size, 
228             const char *tag = NULL) DECLTHROW(SerializerError) = 0;
229       COMMON_EXPORT virtual void vector_end() = 0;
230       COMMON_EXPORT virtual void multimap_start(unsigned int &size, 
231             const char *tag = NULL) DECLTHROW(SerializerError) = 0;
232       COMMON_EXPORT virtual void hash_map_start(unsigned int &size, 
233             const char *tag = NULL) DECLTHROW(SerializerError) = 0;
234       COMMON_EXPORT virtual void hash_map_end() = 0;
235       COMMON_EXPORT virtual void annotation_start(const char *string_id, 
236             const char *tag = NULL) = 0;
237       COMMON_EXPORT virtual void annotation_end() = 0;
238
239       COMMON_EXPORT virtual void multimap_end() = 0;
240
241       COMMON_EXPORT virtual void translate(bool &param, const char *tag = NULL) = 0;
242       COMMON_EXPORT virtual void translate(char &param, const char *tag = NULL) = 0;
243       COMMON_EXPORT virtual void translate(int &param, const char *tag = NULL) = 0;
244       COMMON_EXPORT virtual void translate(long &param, const char *tag = NULL) = 0;
245       COMMON_EXPORT virtual void translate(short &param, const char *tag = NULL) = 0;
246       COMMON_EXPORT virtual void translate(unsigned int &param, const char *tag = NULL) = 0;
247       COMMON_EXPORT virtual void translate(float &param, const char *tag = NULL) = 0;
248       COMMON_EXPORT virtual void translate(double &param, const char *tag = NULL) = 0;
249       COMMON_EXPORT virtual void translate(Address &param, const char *tag = NULL) = 0;
250       COMMON_EXPORT virtual void translate(const char * &param, int bufsize = 0, 
251             const char *tag = NULL) = 0;
252       COMMON_EXPORT virtual void translate(char * &param, int bufsize = 0, 
253             const char *tag = NULL) = 0;
254       COMMON_EXPORT virtual void translate(std::string &param, const char *tag = NULL) = 0;
255       COMMON_EXPORT virtual void translate(std::vector<std::string> &param, const char *tag = NULL,
256             const char *elem_tag = NULL) = 0;
257
258       COMMON_EXPORT virtual iomode_t iomode() {return iomode_;} 
259 };
260
261 class SerDesXML : public SerDes {
262    friend class SerFile;
263    friend bool COMMON_EXPORT ifxml_start_element(SerializerBase *, const char *);
264    friend bool COMMON_EXPORT ifxml_end_element(SerializerBase *, const char *);
265
266
267
268 #if defined (cap_have_libxml)
269       xmlTextWriterPtr writer;
270       COMMON_EXPORT SerDesXML(xmlTextWriterPtr w, iomode_t mode)  : SerDes(mode), writer(w) { }
271       COMMON_EXPORT static xmlTextWriterPtr init(std::string fname, iomode_t mode, bool verbose);
272 #else
273       void *writer;
274       COMMON_EXPORT SerDesXML(void * w, iomode_t mode)  : SerDes(mode), writer(w) { }
275 #endif
276
277    public:
278       COMMON_EXPORT SerDesXML() { assert(0);}
279       COMMON_EXPORT virtual ~SerDesXML();
280
281       COMMON_EXPORT virtual void vector_start(unsigned int &size, 
282             const char *tag = NULL) DECLTHROW(SerializerError);
283       COMMON_EXPORT virtual void vector_end();
284       COMMON_EXPORT virtual void multimap_start(unsigned int &size, 
285             const char *tag = NULL) DECLTHROW(SerializerError);
286       COMMON_EXPORT virtual void multimap_end();
287       COMMON_EXPORT virtual void hash_map_start(unsigned int &size, 
288             const char *tag = NULL) DECLTHROW(SerializerError);
289       COMMON_EXPORT virtual void hash_map_end();
290       COMMON_EXPORT virtual void annotation_start(const char *string_id, const char *tag = NULL);
291       COMMON_EXPORT virtual void annotation_end();
292       COMMON_EXPORT virtual void translate(bool &param, const char *tag = NULL);
293       COMMON_EXPORT virtual void translate(char &param, const char *tag = NULL);
294       COMMON_EXPORT virtual void translate(int &param, const char *tag = NULL);
295       COMMON_EXPORT virtual void translate(long &param, const char *tag = NULL);
296       COMMON_EXPORT virtual void translate(short &param, const char *tag = NULL);
297       COMMON_EXPORT virtual void translate(unsigned int &param, const char *tag = NULL);
298       COMMON_EXPORT virtual void translate(float &param, const char *tag = NULL);
299       COMMON_EXPORT virtual void translate(double &param, const char *tag = NULL);
300       COMMON_EXPORT virtual void translate(Address &param, const char *tag = NULL);
301       COMMON_EXPORT virtual void translate(const char * &param, int bufsize = 0, 
302             const char *tag = NULL);
303       COMMON_EXPORT virtual void translate(char * &param, int bufsize = 0, const char *tag = NULL);
304       COMMON_EXPORT virtual void translate(std::string &param, const char *tag = NULL);
305       COMMON_EXPORT virtual void translate(std::vector<std::string> &param, const char *tag = NULL,
306             const char *elem_tag = NULL);
307
308 #if 0
309       COMMON_EXPORT void start_element(const char *tag);
310       COMMON_EXPORT void end_element();
311       COMMON_EXPORT void xml_value(const char *val, const char *tag);
312 #endif
313 };
314
315 //class AnnotatableBase;
316
317 class SerDesBin : public SerDes {
318
319    typedef struct {
320       unsigned int cache_magic;
321       unsigned int source_file_size; //  if size is different, don't bother with checksum
322       char sha1[SHA1_DIGEST_LEN];
323    } cache_header_t;
324
325    FILE *f;
326
327    bool noisy;
328
329    public:
330
331    //COMMON_EXPORT static dyn_hash_map<Address, AnnotatableBase *> annotatable_id_map;
332    COMMON_EXPORT static FILE *init(std::string fname, iomode_t mode, bool verbose);
333
334    COMMON_EXPORT SerDesBin() {assert(0);}
335
336    COMMON_EXPORT SerDesBin(FILE *ff, iomode_t mode, bool verbose) : 
337       SerDes(mode), 
338       f(ff),  
339       noisy(verbose) {}
340
341    COMMON_EXPORT virtual ~SerDesBin();
342
343    //COMMON_EXPORT static AnnotatableBase *findAnnotatee(void *id); 
344
345    COMMON_EXPORT virtual void file_start(std::string &full_file_path);
346    COMMON_EXPORT virtual void vector_start(unsigned int &size, 
347          const char *tag = NULL) DECLTHROW(SerializerError);
348    COMMON_EXPORT virtual void vector_end();
349    COMMON_EXPORT virtual void multimap_start(unsigned int &size, 
350          const char *tag = NULL) DECLTHROW(SerializerError);
351    COMMON_EXPORT virtual void multimap_end();
352    COMMON_EXPORT virtual void hash_map_start(unsigned int &size, 
353          const char *tag = NULL) DECLTHROW(SerializerError);
354    COMMON_EXPORT virtual void hash_map_end();
355    COMMON_EXPORT virtual void annotation_start(const char *string_id, const char *tag = NULL);
356    COMMON_EXPORT virtual void annotation_end();
357    COMMON_EXPORT virtual void translate(bool &param, const char *tag = NULL);
358    COMMON_EXPORT virtual void translate(char &param, const char *tag = NULL);
359    COMMON_EXPORT virtual void translate(int &param, const char *tag = NULL);
360    COMMON_EXPORT virtual void translate(long &param, const char *tag = NULL);
361    COMMON_EXPORT virtual void translate(short &param, const char *tag = NULL);
362    COMMON_EXPORT virtual void translate(unsigned int &param, const char *tag = NULL);
363    COMMON_EXPORT virtual void translate(float &param, const char *tag = NULL);
364    COMMON_EXPORT virtual void translate(double &param, const char *tag = NULL);
365    COMMON_EXPORT virtual void translate(Address &param, const char *tag = NULL);
366    COMMON_EXPORT virtual void translate(const char * &param, 
367          int bufsize = 0, const char *tag = NULL);
368    COMMON_EXPORT virtual void translate(char * &param, int bufsize = 0, const char *tag = NULL);
369    COMMON_EXPORT virtual void translate(std::string &param, const char *tag = NULL);
370    COMMON_EXPORT virtual void translate(std::vector<std::string> &param, const char *tag = NULL,
371          const char *elem_tag = NULL);
372
373    // readHeaderAndVerify just opens, verifies (checksum, magic compare), and closes
374    // cache file, unless the FILE * is provided, in which case the file pointer is
375    // advanced past the preamble and is not closed;
376
377    COMMON_EXPORT static void readHeaderAndVerify(std::string full_file_path, 
378          std::string cache_name, FILE *f = NULL);
379
380    COMMON_EXPORT static void writeHeaderPreamble(FILE *f, std::string full_file_path, 
381          std::string cache_name);
382
383    COMMON_EXPORT static bool getDefaultCacheDir(std::string &cache_dir);
384    COMMON_EXPORT static bool resolveCachePath(std::string fname, std::string &cache_name);
385    COMMON_EXPORT static bool verifyChecksum(std::string &filename, 
386          const char comp_checksum[SHA1_DIGEST_LEN]);
387    COMMON_EXPORT static bool cacheFileExists(std::string fname);
388    COMMON_EXPORT static bool invalidateCache(std::string cache_name);
389
390 };
391
392 bool start_xml_elem(void *writer, const char *tag);
393 bool end_xml_elem(void *);
394
395 template <class T>
396 class SerializerXML : public ScopedSerializerBase<T> 
397 {
398    public:
399    COMMON_EXPORT virtual bool isXML() {return true;}
400    COMMON_EXPORT virtual bool isBin () {return false;}
401
402       COMMON_EXPORT SerializerXML(T *t, const char *name_, std::string filename, 
403             iomode_t dir, bool verbose) :
404          ScopedSerializerBase<T>(t, name_, filename, dir, verbose) {}
405
406       COMMON_EXPORT virtual ~SerializerXML() {}
407
408       COMMON_EXPORT SerDesXML &getSD_xml()
409           {
410                   SerializerBase *sb = this;
411                   SerDes &sd = sb->getSD();
412                   SerDesXML *sdxml = dynamic_cast<SerDesXML *> (&sd);
413                   assert(sdxml);
414                   return *sdxml;
415           }
416
417       COMMON_EXPORT static bool start_xml_element(SerializerBase *sb, const char *tag)
418           {
419                   SerializerXML<T> *sxml = dynamic_cast<SerializerXML<T> *>(sb);
420
421                   if (!sxml)
422                   {
423                           fprintf(stderr, "%s[%d]:  FIXME:  called xml function with non xml serializer\n",
424                                           FILE__, __LINE__);
425                           return false;
426                   }
427
428                   SerDesXML sdxml = sxml->getSD_xml();
429                   start_xml_elem(sdxml.writer, tag);
430                   return true;
431           }
432
433       COMMON_EXPORT static bool end_xml_element(SerializerBase *sb, const char *)
434           {
435                   SerializerXML<T> *sxml = dynamic_cast<SerializerXML<T> *>(sb);
436
437                   if (!sxml)
438                   {
439                           fprintf(stderr, "%s[%d]:  FIXME:  called xml function with non xml serializer\n",
440                                           FILE__, __LINE__);
441                           return false;
442                   }
443
444                   SerDesXML sdxml = sxml->getSD_xml();
445                   end_xml_elem(sdxml.writer);
446
447                   return true;
448           }
449 };
450
451 template <class T>
452 class SerializerBin : public ScopedSerializerBase<T> {
453    friend class SerDesBin;
454
455
456    public:
457    virtual bool isXML() {return false;}
458    virtual bool isBin () {return true;}
459
460    SerializerBin(T *t)  :
461            ScopedSerializerBase<T>(t) {}
462
463    SerializerBin(T *t, const char *name_, std::string filename, 
464          iomode_t dir, bool verbose) :
465            ScopedSerializerBase<T>(t, name_, filename, dir, verbose)
466
467    {
468            SerializerBase *sb = this;
469            if (sb->serializationDisabled())
470            {
471                    fprintf(stderr, "%s[%d]:  Failing to construct Bin Translator:  global disable set\n",
472                                    FILE__, __LINE__);
473
474                    throw SerializerError(FILE__, __LINE__,
475                                    std::string("serialization disabled"),
476                                    SerializerError::ser_err_disabled);
477            }
478
479            dyn_hash_map<std::string, SerializerBase *>::iterator iter;
480
481            iter = sb->active_bin_serializers.find(std::string(name_));
482
483            if (iter == sb->active_bin_serializers.end())
484            {
485                    fprintf(stderr, "%s[%d]:  Adding Active serializer for name %s\n",
486                                    FILE__, __LINE__, name_);
487
488                    sb->active_bin_serializers[std::string(name_)] = this;
489            }
490            else
491            {
492                    fprintf(stderr, "%s[%d]:  Weird, already have active serializer for name %s\n",
493                                    FILE__, __LINE__, name_);
494            }
495
496
497    }
498
499    virtual ~SerializerBin()
500    {
501            fprintf(stderr, "%s[%d]:  WELCOME TO SERIALIZER_BIN dtor\n", FILE__, __LINE__);
502            dyn_hash_map<std::string, SerializerBase *>::iterator iter;
503
504            SerializerBase *sb = this;
505            iter = sb->active_bin_serializers.find(sb->name());
506
507            if (iter == sb->active_bin_serializers.end())
508            {
509                    fprintf(stderr, "%s[%d]:  Weird, no static ptr for name %s\n",
510                                    FILE__, __LINE__, sb->name().c_str());
511            }
512            else
513            {
514                    fprintf(stderr, "%s[%d]:  Removing active serializer for name %s\n",
515                                    FILE__, __LINE__, sb->name().c_str());
516                    sb->active_bin_serializers.erase(iter);
517            }
518
519    }
520
521    SerDesBin &getSD_bin()
522    {
523            SerializerBase *sb = this;
524            SerDes &sd = sb->getSD();
525            SerDesBin *sdbin = dynamic_cast<SerDesBin *> (&sd);
526            assert(sdbin);
527            return *sdbin;
528    }
529
530
531    static SerializerBin *findSerializerByName(const char *name_)
532    {
533            dyn_hash_map<std::string, SerializerBase *>::iterator iter;
534
535            iter = SerializerBase::active_bin_serializers.find(std::string(name_));
536
537            if (iter == SerializerBase::active_bin_serializers.end())
538            {
539                    fprintf(stderr, "%s[%d]:  No static ptr for name %s\n",
540                                    FILE__, __LINE__, name_);
541                    SerializerBase::dumpActiveBinSerializers();
542            }
543            else
544            {
545                    fprintf(stderr, "%s[%d]:  Found active serializer for name %s\n",
546                                    FILE__, __LINE__, name_);
547
548                    return iter->second;
549            }
550
551            return NULL;
552    }
553
554
555 };
556
557
558 //COMMON_EXPORT SerializationFunctionBase *findSerDesFuncForAnno(unsigned anno_type);
559 //COMMON_EXPORT SerFunc *findSerFuncForAnno(unsigned anno_type);
560
561
562
563 class SerFile {
564
565    SerDes *sd;
566 #if defined (cap_have_libxml)
567    xmlTextWriterPtr writer;
568 #else
569    void * writer;
570 #endif
571    FILE *f;
572
573    public:
574
575    COMMON_EXPORT SerDes *getSD() 
576    {
577       return sd;
578    }
579
580    COMMON_EXPORT SerFile(std::string fname, iomode_t mode, bool verbose = false) :
581       writer (NULL), 
582       f(NULL), 
583       iomode_(mode), 
584       noisy(verbose) 
585    {
586       char file_path[PATH_MAX];
587
588       if (!resolve_file_path(fname.c_str(), file_path)) 
589       {
590          char msg[128];
591          sprintf(msg, "failed to resolve path for '%s'\n", fname.c_str());
592          SER_ERR(msg);
593       }
594
595       filename = std::string(file_path);
596       serialize_debug_init();
597
598       if (strstr(filename.c_str(), "xml")) 
599       {
600          fprintf(stderr, "%s[%d]:  opening xml file %s for %s\n", FILE__, __LINE__, 
601                filename.c_str(), mode == sd_serialize ? "output" : "input");
602
603          if (mode == sd_deserialize) 
604          {
605             fprintf(stderr, "%s[%d]:  ERROR:  deserializing xml not supported\n", 
606                   FILE__, __LINE__);
607             assert(0);
608          }
609
610 #if defined (cap_have_libxml)
611          writer = SerDesXML::init(fname, mode, verbose);
612
613          if (!writer) 
614          {
615             fprintf(stderr, "%s[%d]:  ERROR:  failed to init xml writer\n", FILE__, __LINE__);
616             assert(0);
617          }
618 #else
619          writer = NULL;
620 #endif
621
622          sd = new SerDesXML(writer, mode);
623
624       }
625       else 
626       {
627          fprintf(stderr, "%s[%d]:  opening %s file for %s\n", FILE__, __LINE__, 
628                filename.c_str(), mode == sd_serialize ? "output" : "input");
629
630          f = SerDesBin::init(fname, mode, verbose);
631
632          if (!f) 
633          {
634             fprintf(stderr, "%s[%d]:  failed to init file i/o\n", FILE__, __LINE__);
635             assert(0);
636          }
637
638          sd = new SerDesBin(f,mode, verbose);
639       }
640    }
641
642    COMMON_EXPORT iomode_t iomode() 
643    {
644       return iomode_;
645    }
646
647    static bool validCacheExistsFor(std::string full_file_path);
648
649    protected:
650
651    std::string filename;
652    iomode_t iomode_;
653
654    public:
655
656    bool noisy;
657
658 };
659
660 template <class S, class T>
661 class SpecAdaptor {
662
663    public:
664
665       COMMON_EXPORT SpecAdaptor() {}
666
667       COMMON_EXPORT T *operator()(S *s, T &t, const char *tag) 
668       {
669          s->translate_base(t, tag);
670          return &t;
671       }
672 };
673
674 template <class S, class T>
675 class SpecAdaptor<S, T *> {
676
677    public:
678
679       COMMON_EXPORT SpecAdaptor() {}
680
681       COMMON_EXPORT T* operator()(S *s, T *t, const char *tag) 
682       {
683          assert(t);
684          assert(s);
685          s->translate_base(*t, tag);
686          return t;
687       }
688 };
689
690 template <class S, class T> 
691 void sd_translate(S *sd, T &it, const char * tag) 
692 {
693    fprintf(stderr, "%s[%d]:  welcome to sd_translate<%s, %s>(%p)\n", 
694          FILE__, __LINE__, 
695          typeid(S).name(), 
696          typeid(T).name(), &it);
697
698    SpecAdaptor<S,T> saf;
699
700    if (NULL == saf(sd, it, tag)) 
701    {
702       fprintf(stderr, "%s[%d]:  ERROR here\n", FILE__, __LINE__);
703    }
704
705    return;
706 }
707
708
709 template<class S, class T, class TT2> 
710 class trans_adaptor<S, dyn_hash_map<T, TT2> > {
711
712    public:
713
714       COMMON_EXPORT trans_adaptor() 
715       {
716          fprintf(stderr, "%s[%d]:  welcome to trans_adaptor<%s, hash<%s, %s> >()\n",
717                FILE__, __LINE__,
718                typeid(S).name(),
719                typeid(T).name(), typeid(TT2).name() );
720       }
721
722       COMMON_EXPORT dyn_hash_map<T, TT2> * operator()(S *ser, dyn_hash_map<T, TT2> &m, 
723             const char *tag = NULL, const char *tag2 = NULL) 
724       {
725          fprintf(stderr, "%s[%d]:  hash_size = %d\n", FILE__, __LINE__, m.size());
726          translate_hash_map(ser, m, tag, tag2);
727
728          //  maybe catch errors here?
729          return &m;
730       }
731 };
732
733
734
735 #if 0
736 class SerTest : public Serializable {
737
738    int my_int;
739
740    public:
741
742    SerTest() 
743    { 
744       my_int = 777;
745    }
746
747    ~SerTest() {}
748
749    void serialize(SerializerBase *s, const char * = NULL) 
750    {
751       try 
752       {
753          gtranslate(s, my_int);
754       }  SER_CATCH("SerTest");
755    }
756
757    void testit() 
758    {
759       SerializerBase sb("SerTest", std::string("boogabooga"), sd_serialize, true);
760       serialize( &sb);
761    }
762 };
763 #endif
764 } /*namespace Dyninst*/
765 #endif