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