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