serialize.hh revision 217
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#include <map>
40
41#include "sim/host.hh"
42#include "sim/configfile.hh"
43
44class IniFile;
45
46template <class T>
47void paramOut(std::ostream &os, const std::string &name, const T& param);
48
49template <class T>
50void paramIn(IniFile &db, const std::string &section,
51             const std::string &name, T& param);
52
53template <class T>
54void arrayParamOut(std::ostream &os, const std::string &name,
55                   const T *param, int size);
56
57template <class T>
58void arrayParamIn(IniFile &db, const std::string &section,
59                  const std::string &name, T *param, int size);
60
61//
62// These macros are streamlined to use in serialize/unserialize
63// functions.  It's assumed that serialize() has a parameter 'os' for
64// the ostream, and unserialize() has parameters 'db' and 'section'.
65#define SERIALIZE_MEMBER(member)	paramOut(os, #member, member)
66
67#define UNSERIALIZE_MEMBER(member)	paramIn(db, section, #member, member)
68
69#define SERIALIZE_ARRAY(member, size)	\
70        arrayParamOut(os, #member, member, size)
71
72#define UNSERIALIZE_ARRAY(member, size)	\
73        arrayParamIn(db, section, #member, member, size)
74
75/*
76 * Basic support for object serialization.
77 */
78class Serializeable
79{
80  public:
81
82    friend class Serializer;
83
84  protected:
85    // object name: should be unique
86    std::string objName;
87
88    bool serialized;
89    static Serializer *serializer;
90
91    void mark();
92    void nameOut(std::ostream& os);
93    void nameOut(std::ostream& os, const std::string &_name);
94
95  public:
96    Serializeable(const std::string &n);
97    virtual ~Serializeable();
98
99    void setName(const std::string &name);
100
101    // return name
102    const std::string &name() const { return objName; }
103
104    virtual void nameChildren() {}
105    virtual void serialize(std::ostream& os) {}
106    virtual void unserialize(IniFile &db, const std::string &section) {}
107};
108
109class Serializer
110{
111    friend class Serializeable;
112
113  protected:
114    typedef std::list<Serializeable *> serlist_t;
115    serlist_t objects;
116    std::string file;
117    std::ostream *output;
118    std::ostream &out() const;
119
120  public:
121    Serializer();
122    virtual ~Serializer();
123
124  private:
125    void add_object(Serializeable *obj);
126    void add_objects();
127
128  public:
129    void serialize(const std::string &file);
130    const std::string &filename() const { return file; }
131};
132
133//
134// A SerializeableBuilder serves as an evaluation context for a set of
135// parameters that describe a specific instance of a Serializeable.  This
136// evaluation context corresponds to a section in the .ini file (as
137// with the base ParamContext) plus an optional node in the
138// configuration hierarchy (the configNode member) for resolving
139// Serializeable references.  SerializeableBuilder is an abstract superclass;
140// derived classes specialize the class for particular subclasses of
141// Serializeable (e.g., BaseCache).
142//
143// For typical usage, see the definition of
144// SerializeableClass::createObject().
145//
146class SerializeableBuilder
147{
148  public:
149
150    SerializeableBuilder() {}
151
152    virtual ~SerializeableBuilder() {}
153
154    // Create the actual Serializeable corresponding to the parameter
155    // values in this context.  This function is overridden in derived
156    // classes to call a specific constructor for a particular
157    // subclass of Serializeable.
158    virtual Serializeable *create() = 0;
159};
160
161//
162// An instance of SerializeableClass corresponds to a class derived from
163// Serializeable.  The SerializeableClass instance serves to bind the string
164// name (found in the config file) to a function that creates an
165// instance of the appropriate derived class.
166//
167// This would be much cleaner in Smalltalk or Objective-C, where types
168// are first-class objects themselves.
169//
170class SerializeableClass
171{
172  public:
173
174    // Type CreateFunc is a pointer to a function that creates a new
175    // simulation object builder based on a .ini-file parameter
176    // section (specified by the first string argument), a unique name
177    // for the object (specified by the second string argument), and
178    // an optional config hierarchy node (specified by the third
179    // argument).  A pointer to the new SerializeableBuilder is returned.
180    typedef SerializeableBuilder *(*CreateFunc)();
181
182    static std::map<std::string,CreateFunc> *classMap;
183
184    // Constructor.  For example:
185    //
186    // SerializeableClass baseCacheSerializeableClass("BaseCacheSerializeable",
187    //                         newBaseCacheSerializeableBuilder);
188    //
189    SerializeableClass(const std::string &className, CreateFunc createFunc);
190
191    // create Serializeable given name of class and pointer to
192    // configuration hierarchy node
193    static Serializeable *createObject(IniFile &configDB,
194                                       const std::string &configClassName);
195
196};
197
198//
199// Macros to encapsulate the magic of declaring & defining
200// SerializeableBuilder and SerializeableClass objects
201//
202
203#define CREATE_SERIALIZEABLE(OBJ_CLASS)				\
204OBJ_CLASS *OBJ_CLASS##Builder::create()
205
206#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS)		\
207class OBJ_CLASS##Builder : public SerializeableBuilder		\
208{								\
209  public: 							\
210                                                                \
211    OBJ_CLASS##Builder() {}					\
212    virtual ~OBJ_CLASS##Builder() {}				\
213                                                                \
214    OBJ_CLASS *create();					\
215};								\
216                                                                \
217                                                                \
218SerializeableBuilder *						\
219new##OBJ_CLASS##Builder()					\
220{								\
221    return new OBJ_CLASS##Builder();				\
222}								\
223                                                                \
224SerializeableClass the##OBJ_CLASS##Class(CLASS_NAME,		\
225                                     new##OBJ_CLASS##Builder);
226
227
228
229#endif // __SERIALIZE_HH__
230