serialize.hh revision 2
1/*
2 * Copyright (c) 2003 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/* @file
30 * Serialization Interface Declarations
31 */
32
33#ifndef __SERIALIZE_HH__
34#define __SERIALIZE_HH__
35
36
37#include <list>
38#include <iostream>
39
40#include "host.hh"
41#include "configfile.hh"
42
43class IniFile;
44
45/*
46 * Basic support for object serialization.
47 */
48class Serializeable
49{
50  public:
51    // To allow other classes to do some of the serialization work.
52    class Proxy {
53      private:
54        Serializeable *obj;
55
56        // Make it so only Serializables can construct one of these.
57        Proxy(Serializeable *o) : obj(o) {};
58
59        friend class Serializeable;
60
61      public:
62        template <class T>
63        void paramOut(const std::string &name, const T& param) const {
64            obj->paramOut(name, param);
65        };
66    };
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