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