serialize.hh revision 2
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2003 The Regents of The University of Michigan 311308Santhony.gutierrez@amd.com * All rights reserved. 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 611308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are 711308Santhony.gutierrez@amd.com * met: redistributions of source code must retain the above copyright 811308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer; 911308Santhony.gutierrez@amd.com * redistributions in binary form must reproduce the above copyright 1011308Santhony.gutierrez@amd.com * notice, this list of conditions and the following disclaimer in the 1111308Santhony.gutierrez@amd.com * documentation and/or other materials provided with the distribution; 1211308Santhony.gutierrez@amd.com * neither the name of the copyright holders nor the names of its 1311308Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from 1411308Santhony.gutierrez@amd.com * this software without specific prior written permission. 1511308Santhony.gutierrez@amd.com * 1611308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711308Santhony.gutierrez@amd.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811308Santhony.gutierrez@amd.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911308Santhony.gutierrez@amd.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011308Santhony.gutierrez@amd.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111308Santhony.gutierrez@amd.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211308Santhony.gutierrez@amd.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311308Santhony.gutierrez@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411308Santhony.gutierrez@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511308Santhony.gutierrez@amd.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611308Santhony.gutierrez@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711308Santhony.gutierrez@amd.com */ 2811308Santhony.gutierrez@amd.com 2911308Santhony.gutierrez@amd.com/* @file 3011308Santhony.gutierrez@amd.com * Serialization Interface Declarations 3111308Santhony.gutierrez@amd.com */ 3211308Santhony.gutierrez@amd.com 3311308Santhony.gutierrez@amd.com#ifndef __SERIALIZE_HH__ 3411308Santhony.gutierrez@amd.com#define __SERIALIZE_HH__ 3511308Santhony.gutierrez@amd.com 3611308Santhony.gutierrez@amd.com 3711308Santhony.gutierrez@amd.com#include <list> 3811308Santhony.gutierrez@amd.com#include <iostream> 3911308Santhony.gutierrez@amd.com 4011308Santhony.gutierrez@amd.com#include "host.hh" 4111308Santhony.gutierrez@amd.com#include "configfile.hh" 4211308Santhony.gutierrez@amd.com 4311308Santhony.gutierrez@amd.comclass IniFile; 4411692Santhony.gutierrez@amd.com 4511534Sjohn.kalamatianos@amd.com/* 4611692Santhony.gutierrez@amd.com * Basic support for object serialization. 4711692Santhony.gutierrez@amd.com */ 4811308Santhony.gutierrez@amd.comclass Serializeable 4911534Sjohn.kalamatianos@amd.com{ 5011534Sjohn.kalamatianos@amd.com public: 5111534Sjohn.kalamatianos@amd.com // To allow other classes to do some of the serialization work. 5211534Sjohn.kalamatianos@amd.com class Proxy { 5311534Sjohn.kalamatianos@amd.com private: 5411534Sjohn.kalamatianos@amd.com Serializeable *obj; 5511534Sjohn.kalamatianos@amd.com 5611534Sjohn.kalamatianos@amd.com // Make it so only Serializables can construct one of these. 5711534Sjohn.kalamatianos@amd.com Proxy(Serializeable *o) : obj(o) {}; 5811534Sjohn.kalamatianos@amd.com 5911534Sjohn.kalamatianos@amd.com friend class Serializeable; 6011534Sjohn.kalamatianos@amd.com 6111534Sjohn.kalamatianos@amd.com public: 6211534Sjohn.kalamatianos@amd.com template <class T> 6311534Sjohn.kalamatianos@amd.com void paramOut(const std::string &name, const T& param) const { 6411534Sjohn.kalamatianos@amd.com obj->paramOut(name, param); 6511534Sjohn.kalamatianos@amd.com }; 6611534Sjohn.kalamatianos@amd.com }; 6711308Santhony.gutierrez@amd.com 6811308Santhony.gutierrez@amd.com friend class Serializer; 6911308Santhony.gutierrez@amd.com friend class Proxy; 7011692Santhony.gutierrez@amd.com 7111308Santhony.gutierrez@amd.com private: 7211692Santhony.gutierrez@amd.com Proxy proxy; 7311308Santhony.gutierrez@amd.com 7411308Santhony.gutierrez@amd.com protected: 7511308Santhony.gutierrez@amd.com const Proxy &getProxy() { return(proxy); }; 7611308Santhony.gutierrez@amd.com 7711308Santhony.gutierrez@amd.com // object name: should be unique 7811692Santhony.gutierrez@amd.com std::string objName; 7911308Santhony.gutierrez@amd.com 8011308Santhony.gutierrez@amd.com bool serialized; 8111308Santhony.gutierrez@amd.com static Serializer *serializer; 8211308Santhony.gutierrez@amd.com 8311308Santhony.gutierrez@amd.com void mark(); 8411692Santhony.gutierrez@amd.com void nameOut(); 8511308Santhony.gutierrez@amd.com void nameOut(const std::string &_name); 8611308Santhony.gutierrez@amd.com void childOut(const std::string &name, Serializeable *child); 8711308Santhony.gutierrez@amd.com template <class T> 8811308Santhony.gutierrez@amd.com void paramOut(const std::string &name, const T& param); 8911308Santhony.gutierrez@amd.com 9011692Santhony.gutierrez@amd.com std::ostream &out() const; 9111308Santhony.gutierrez@amd.com 9211308Santhony.gutierrez@amd.com public: 9311308Santhony.gutierrez@amd.com Serializeable(const std::string &n); 9411308Santhony.gutierrez@amd.com virtual ~Serializeable(); 9511308Santhony.gutierrez@amd.com 9611692Santhony.gutierrez@amd.com void setName(const std::string &name); 9711308Santhony.gutierrez@amd.com 9811308Santhony.gutierrez@amd.com // return name 9911308Santhony.gutierrez@amd.com const std::string &name() const { return objName; } 10011308Santhony.gutierrez@amd.com 10111308Santhony.gutierrez@amd.com virtual void nameChildren() {} 10211692Santhony.gutierrez@amd.com virtual void serialize() {} 10311308Santhony.gutierrez@amd.com virtual void unserialize(IniFile &db, const std::string &category, 10411308Santhony.gutierrez@amd.com ConfigNode *node = NULL) 10511699Santhony.gutierrez@amd.com { 10611699Santhony.gutierrez@amd.com std::cout << name() << " is being unserialized" << std::endl; 10711699Santhony.gutierrez@amd.com } 10811699Santhony.gutierrez@amd.com}; 10911699Santhony.gutierrez@amd.com 11011699Santhony.gutierrez@amd.comclass Serializer 11111308Santhony.gutierrez@amd.com{ 11211699Santhony.gutierrez@amd.com friend class Serializeable; 11311308Santhony.gutierrez@amd.com 11411699Santhony.gutierrez@amd.com protected: 11511308Santhony.gutierrez@amd.com typedef std::list<Serializeable *> serlist_t; 11611308Santhony.gutierrez@amd.com serlist_t objects; 11711308Santhony.gutierrez@amd.com std::string file; 11811308Santhony.gutierrez@amd.com std::ostream *output; 11911308Santhony.gutierrez@amd.com std::ostream &out() const; 12011692Santhony.gutierrez@amd.com 12111308Santhony.gutierrez@amd.com public: 12211308Santhony.gutierrez@amd.com Serializer(); 12311308Santhony.gutierrez@amd.com virtual ~Serializer(); 12411308Santhony.gutierrez@amd.com 12511308Santhony.gutierrez@amd.com private: 12611692Santhony.gutierrez@amd.com void add_object(Serializeable *obj); 12711308Santhony.gutierrez@amd.com void add_objects(); 12811308Santhony.gutierrez@amd.com 12911308Santhony.gutierrez@amd.com public: 13011308Santhony.gutierrez@amd.com void serialize(const std::string &file); 13111308Santhony.gutierrez@amd.com const std::string &filename() const { return file; } 13211692Santhony.gutierrez@amd.com}; 13311308Santhony.gutierrez@amd.com 13411308Santhony.gutierrez@amd.comtemplate <class T> 13511308Santhony.gutierrez@amd.cominline void 13611308Santhony.gutierrez@amd.comSerializeable::paramOut(const std::string &name, const T& param) 13711308Santhony.gutierrez@amd.com{ 13811692Santhony.gutierrez@amd.com out() << name << "=" << param << "\n"; 13911308Santhony.gutierrez@amd.com} 14011308Santhony.gutierrez@amd.com 14111308Santhony.gutierrez@amd.comtemplate <> void 14211308Santhony.gutierrez@amd.comSerializeable::paramOut(const std::string &name, const uint64_t& param); 14311308Santhony.gutierrez@amd.com 14411308Santhony.gutierrez@amd.com 14511308Santhony.gutierrez@amd.com// 14611308Santhony.gutierrez@amd.com// A SerializeableBuilder serves as an evaluation context for a set of 14711308Santhony.gutierrez@amd.com// parameters that describe a specific instance of a Serializeable. This 14811308Santhony.gutierrez@amd.com// evaluation context corresponds to a section in the .ini file (as 14911308Santhony.gutierrez@amd.com// with the base ParamContext) plus an optional node in the 15011692Santhony.gutierrez@amd.com// configuration hierarchy (the configNode member) for resolving 15111308Santhony.gutierrez@amd.com// Serializeable references. SerializeableBuilder is an abstract superclass; 15211308Santhony.gutierrez@amd.com// derived classes specialize the class for particular subclasses of 15311308Santhony.gutierrez@amd.com// Serializeable (e.g., BaseCache). 15411308Santhony.gutierrez@amd.com// 15511308Santhony.gutierrez@amd.com// For typical usage, see the definition of 15611308Santhony.gutierrez@amd.com// SerializeableClass::createObject(). 15711308Santhony.gutierrez@amd.com// 15811308Santhony.gutierrez@amd.comclass SerializeableBuilder 15911308Santhony.gutierrez@amd.com{ 16011692Santhony.gutierrez@amd.com public: 16111308Santhony.gutierrez@amd.com 16211308Santhony.gutierrez@amd.com SerializeableBuilder() {} 16311308Santhony.gutierrez@amd.com 16411693Santhony.gutierrez@amd.com virtual ~SerializeableBuilder() {} 16511693Santhony.gutierrez@amd.com 16611693Santhony.gutierrez@amd.com // Create the actual Serializeable corresponding to the parameter 16711693Santhony.gutierrez@amd.com // values in this context. This function is overridden in derived 16811693Santhony.gutierrez@amd.com // classes to call a specific constructor for a particular 16911693Santhony.gutierrez@amd.com // subclass of Serializeable. 17011692Santhony.gutierrez@amd.com virtual Serializeable *create() = 0; 17111692Santhony.gutierrez@amd.com}; 17211692Santhony.gutierrez@amd.com 17311692Santhony.gutierrez@amd.com// 17411308Santhony.gutierrez@amd.com// An instance of SerializeableClass corresponds to a class derived from 17511692Santhony.gutierrez@amd.com// Serializeable. The SerializeableClass instance serves to bind the string 17611308Santhony.gutierrez@amd.com// name (found in the config file) to a function that creates an 17711692Santhony.gutierrez@amd.com// instance of the appropriate derived class. 17811692Santhony.gutierrez@amd.com// 17911692Santhony.gutierrez@amd.com// This would be much cleaner in Smalltalk or Objective-C, where types 18011692Santhony.gutierrez@amd.com// are first-class objects themselves. 18111692Santhony.gutierrez@amd.com// 18211692Santhony.gutierrez@amd.comclass SerializeableClass 18311692Santhony.gutierrez@amd.com{ 18411692Santhony.gutierrez@amd.com public: 18511692Santhony.gutierrez@amd.com 18611692Santhony.gutierrez@amd.com // Type CreateFunc is a pointer to a function that creates a new 18711692Santhony.gutierrez@amd.com // simulation object builder based on a .ini-file parameter 18811692Santhony.gutierrez@amd.com // section (specified by the first string argument), a unique name 18911692Santhony.gutierrez@amd.com // for the object (specified by the second string argument), and 19011692Santhony.gutierrez@amd.com // an optional config hierarchy node (specified by the third 19111692Santhony.gutierrez@amd.com // argument). A pointer to the new SerializeableBuilder is returned. 19211692Santhony.gutierrez@amd.com typedef SerializeableBuilder *(*CreateFunc)(); 19311692Santhony.gutierrez@amd.com 19411692Santhony.gutierrez@amd.com static std::map<std::string,CreateFunc> *classMap; 19511692Santhony.gutierrez@amd.com 19611692Santhony.gutierrez@amd.com // Constructor. For example: 19711692Santhony.gutierrez@amd.com // 19811692Santhony.gutierrez@amd.com // SerializeableClass baseCacheSerializeableClass("BaseCacheSerializeable", 19911692Santhony.gutierrez@amd.com // newBaseCacheSerializeableBuilder); 20011692Santhony.gutierrez@amd.com // 20111692Santhony.gutierrez@amd.com SerializeableClass(const std::string &className, CreateFunc createFunc); 20211692Santhony.gutierrez@amd.com 20311692Santhony.gutierrez@amd.com // create Serializeable given name of class and pointer to 20411692Santhony.gutierrez@amd.com // configuration hierarchy node 20511692Santhony.gutierrez@amd.com static Serializeable *createObject(IniFile &configDB, 20611692Santhony.gutierrez@amd.com const std::string &configClassName); 20711692Santhony.gutierrez@amd.com 20811692Santhony.gutierrez@amd.com}; 20911692Santhony.gutierrez@amd.com 21011692Santhony.gutierrez@amd.com// 21111692Santhony.gutierrez@amd.com// Macros to encapsulate the magic of declaring & defining 21211692Santhony.gutierrez@amd.com// SerializeableBuilder and SerializeableClass objects 21311692Santhony.gutierrez@amd.com// 21411692Santhony.gutierrez@amd.com 21511692Santhony.gutierrez@amd.com#define CREATE_SERIALIZEABLE(OBJ_CLASS) \ 21611692Santhony.gutierrez@amd.comOBJ_CLASS *OBJ_CLASS##Builder::create() 21711692Santhony.gutierrez@amd.com 21811692Santhony.gutierrez@amd.com#define REGISTER_SERIALIZEABLE(CLASS_NAME, OBJ_CLASS) \ 21911692Santhony.gutierrez@amd.comclass OBJ_CLASS##Builder : public SerializeableBuilder \ 22011692Santhony.gutierrez@amd.com{ \ 22111692Santhony.gutierrez@amd.com public: \ 22211692Santhony.gutierrez@amd.com \ 22311692Santhony.gutierrez@amd.com OBJ_CLASS##Builder() {} \ 22411692Santhony.gutierrez@amd.com virtual ~OBJ_CLASS##Builder() {} \ 22511692Santhony.gutierrez@amd.com \ 22611692Santhony.gutierrez@amd.com OBJ_CLASS *create(); \ 22711692Santhony.gutierrez@amd.com}; \ 22811692Santhony.gutierrez@amd.com \ 22911692Santhony.gutierrez@amd.com \ 23011692Santhony.gutierrez@amd.comSerializeableBuilder * \ 23111692Santhony.gutierrez@amd.comnew##OBJ_CLASS##Builder() \ 23211692Santhony.gutierrez@amd.com{ \ 23311692Santhony.gutierrez@amd.com return new OBJ_CLASS##Builder(); \ 23411692Santhony.gutierrez@amd.com} \ 23511692Santhony.gutierrez@amd.com \ 23611692Santhony.gutierrez@amd.comSerializeableClass the##OBJ_CLASS##Class(CLASS_NAME, \ 23711692Santhony.gutierrez@amd.com new##OBJ_CLASS##Builder); 23811692Santhony.gutierrez@amd.com 23911692Santhony.gutierrez@amd.com 24011692Santhony.gutierrez@amd.com 24111692Santhony.gutierrez@amd.com#endif // __SERIALIZE_HH__ 24211692Santhony.gutierrez@amd.com