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