serialize.hh revision 56
16145Snate@binkert.org/*
26145Snate@binkert.org * Copyright (c) 2003 The Regents of The University of Michigan
36145Snate@binkert.org * All rights reserved.
46145Snate@binkert.org *
56145Snate@binkert.org * Redistribution and use in source and binary forms, with or without
66145Snate@binkert.org * modification, are permitted provided that the following conditions are
76145Snate@binkert.org * met: redistributions of source code must retain the above copyright
86145Snate@binkert.org * notice, this list of conditions and the following disclaimer;
96145Snate@binkert.org * redistributions in binary form must reproduce the above copyright
106145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
116145Snate@binkert.org * documentation and/or other materials provided with the distribution;
126145Snate@binkert.org * neither the name of the copyright holders nor the names of its
136145Snate@binkert.org * contributors may be used to endorse or promote products derived from
146145Snate@binkert.org * this software without specific prior written permission.
156145Snate@binkert.org *
166145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276145Snate@binkert.org */
286145Snate@binkert.org
296154Snate@binkert.org/* @file
306145Snate@binkert.org * Serialization Interface Declarations
317039Snate@binkert.org */
327055Snate@binkert.org
336145Snate@binkert.org#ifndef __SERIALIZE_HH__
347039Snate@binkert.org#define __SERIALIZE_HH__
357039Snate@binkert.org
367039Snate@binkert.org
377039Snate@binkert.org#include <list>
387055Snate@binkert.org#include <iostream>
396145Snate@binkert.org
406145Snate@binkert.org#include "sim/host.hh"
417039Snate@binkert.org#include "sim/configfile.hh"
427055Snate@binkert.org
436145Snate@binkert.orgclass IniFile;
447039Snate@binkert.org
457039Snate@binkert.org/*
467039Snate@binkert.org * Basic support for object serialization.
477039Snate@binkert.org */
487055Snate@binkert.orgclass Serializeable
496145Snate@binkert.org{
506145Snate@binkert.org  public:
516145Snate@binkert.org    // To allow other classes to do some of the serialization work.
526145Snate@binkert.org    class Proxy {
537039Snate@binkert.org      private:
546145Snate@binkert.org        Serializeable *obj;
556145Snate@binkert.org
567039Snate@binkert.org        // Make it so only Serializables can construct one of these.
577039Snate@binkert.org        Proxy(Serializeable *o) : obj(o) {};
586145Snate@binkert.org
597039Snate@binkert.org        friend class Serializeable;
607039Snate@binkert.org
617039Snate@binkert.org      public:
627039Snate@binkert.org        template <class T>
637039Snate@binkert.org        void paramOut(const std::string &name, const T& param) const {
647039Snate@binkert.org            obj->paramOut(name, param);
656145Snate@binkert.org        };
666145Snate@binkert.org    };
67
68    friend class Serializer;
69    friend class Proxy;
70
71  private:
72    Proxy proxy;
73
74  protected:
75    const Proxy &getProxy() { return(proxy); };
76
77    // object name: should be unique
78    std::string objName;
79
80    bool serialized;
81    static Serializer *serializer;
82
83    void mark();
84    void nameOut();
85    void nameOut(const std::string &_name);
86    void childOut(const std::string &name, Serializeable *child);
87    template <class T>
88    void paramOut(const std::string &name, const T& param);
89
90    std::ostream &out() const;
91
92  public:
93    Serializeable(const std::string &n);
94    virtual ~Serializeable();
95
96    void setName(const std::string &name);
97
98    // return name
99    const std::string &name() const { return objName; }
100
101    virtual void nameChildren() {}
102    virtual void serialize() {}
103    virtual void unserialize(IniFile &db, const std::string &category,
104                             ConfigNode *node = NULL)
105    {
106        std::cout << name() << " is being unserialized" << std::endl;
107    }
108};
109
110class Serializer
111{
112    friend class Serializeable;
113
114  protected:
115    typedef std::list<Serializeable *> serlist_t;
116    serlist_t objects;
117    std::string file;
118    std::ostream *output;
119    std::ostream &out() const;
120
121  public:
122    Serializer();
123    virtual ~Serializer();
124
125  private:
126    void add_object(Serializeable *obj);
127    void add_objects();
128
129  public:
130    void serialize(const std::string &file);
131    const std::string &filename() const { return file; }
132};
133
134template <class T>
135inline void
136Serializeable::paramOut(const std::string &name, const T& param)
137{
138    out() << name << "=" << param << "\n";
139}
140
141template <> void
142Serializeable::paramOut(const std::string &name, const uint64_t& param);
143
144
145//
146// A SerializeableBuilder serves as an evaluation context for a set of
147// parameters that describe a specific instance of a Serializeable.  This
148// evaluation context corresponds to a section in the .ini file (as
149// with the base ParamContext) plus an optional node in the
150// configuration hierarchy (the configNode member) for resolving
151// Serializeable references.  SerializeableBuilder is an abstract superclass;
152// derived classes specialize the class for particular subclasses of
153// Serializeable (e.g., BaseCache).
154//
155// For typical usage, see the definition of
156// SerializeableClass::createObject().
157//
158class SerializeableBuilder
159{
160  public:
161
162    SerializeableBuilder() {}
163
164    virtual ~SerializeableBuilder() {}
165
166    // Create the actual Serializeable corresponding to the parameter
167    // values in this context.  This function is overridden in derived
168    // classes to call a specific constructor for a particular
169    // subclass of Serializeable.
170    virtual Serializeable *create() = 0;
171};
172
173//
174// An instance of SerializeableClass corresponds to a class derived from
175// Serializeable.  The SerializeableClass instance serves to bind the string
176// name (found in the config file) to a function that creates an
177// instance of the appropriate derived class.
178//
179// This would be much cleaner in Smalltalk or Objective-C, where types
180// are first-class objects themselves.
181//
182class SerializeableClass
183{
184  public:
185
186    // Type CreateFunc is a pointer to a function that creates a new
187    // simulation object builder based on a .ini-file parameter
188    // section (specified by the first string argument), a unique name
189    // for the object (specified by the second string argument), and
190    // an optional config hierarchy node (specified by the third
191    // argument).  A pointer to the new SerializeableBuilder is returned.
192    typedef SerializeableBuilder *(*CreateFunc)();
193
194    static std::map<std::string,CreateFunc> *classMap;
195
196    // Constructor.  For example:
197    //
198    // SerializeableClass baseCacheSerializeableClass("BaseCacheSerializeable",
199    //                         newBaseCacheSerializeableBuilder);
200    //
201    SerializeableClass(const std::string &className, CreateFunc createFunc);
202
203    // create Serializeable given name of class and pointer to
204    // configuration hierarchy node
205    static Serializeable *createObject(IniFile &configDB,
206                                       const std::string &configClassName);
207
208};
209
210//
211// Macros to encapsulate the magic of declaring & defining
212// SerializeableBuilder and SerializeableClass objects
213//
214
215#define CREATE_SERIALIZEABLE(OBJ_CLASS)				\
216OBJ_CLASS *OBJ_CLASS##Builder::create()
217
218#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS)		\
219class OBJ_CLASS##Builder : public SerializeableBuilder		\
220{								\
221  public: 							\
222                                                                \
223    OBJ_CLASS##Builder() {}					\
224    virtual ~OBJ_CLASS##Builder() {}				\
225                                                                \
226    OBJ_CLASS *create();					\
227};								\
228                                                                \
229                                                                \
230SerializeableBuilder *						\
231new##OBJ_CLASS##Builder()					\
232{								\
233    return new OBJ_CLASS##Builder();				\
234}								\
235                                                                \
236SerializeableClass the##OBJ_CLASS##Class(CLASS_NAME,		\
237                                     new##OBJ_CLASS##Builder);
238
239
240
241#endif // __SERIALIZE_HH__
242