From: <sv...@ww...> - 2004-06-21 07:11:16
|
Author: mkrose Date: 2004-06-21 00:11:10 -0700 (Mon, 21 Jun 2004) New Revision: 1059 Added: trunk/CSP/SimData/Include/SimData/TaggedRecordRegistry.h Modified: trunk/CSP/SimData/CHANGES.current trunk/CSP/SimData/Include/SimData/TaggedRecord.h Log: Updated docs in TaggedRecord.h. Added a global registry for tagged records. Browse at: https://www.zerobar.net/viewcvs/viewcvs.cgi?view=rev&rev=1059 Modified: trunk/CSP/SimData/CHANGES.current =================================================================== --- trunk/CSP/SimData/CHANGES.current 2004-06-21 07:02:44 UTC (rev 1058) +++ trunk/CSP/SimData/CHANGES.current 2004-06-21 07:11:10 UTC (rev 1059) @@ -22,6 +22,9 @@ generate the record class id. The single 64-bit id was being truncated when used to construct the simdata::hasht identifier. + * Updated docs in TaggedRecord.h. Added a global registry for + tagged records. + 2004-06-16: onsight * Doxygen cleanups. Modified: trunk/CSP/SimData/Include/SimData/TaggedRecord.h =================================================================== --- trunk/CSP/SimData/Include/SimData/TaggedRecord.h 2004-06-21 07:02:44 UTC (rev 1058) +++ trunk/CSP/SimData/Include/SimData/TaggedRecord.h 2004-06-21 07:11:10 UTC (rev 1059) @@ -24,7 +24,22 @@ * @brief Base classes for tagged records. */ +// TODO ============================================================= +// pack tags; group them at the start of the record: +// bit 7: packed (1) or offset (0) +// packed: +// bits 0-6 indicate which of the next 7 tags are present (1) or +// absent (0) +// offset: +// bits 0-6 are the offset to the next tag, relative to the last +// known tag. (1-127) +// special cases: +// 0: reserved +// 101-126: reserved +// 127: offset is greater than 100, is contained in the next +// two bytes + #ifndef __SIMDATA_TAGGED_RECORD_H__ #define __SIMDATA_TAGGED_RECORD_H__ @@ -47,8 +62,7 @@ typedef hasht int64; -/** - * Simple Writer class for serializing to a string buffer. +/** Simple Writer class for serializing to a string buffer. */ class StringWriter: public Writer { std::string _buffer; @@ -118,12 +132,11 @@ } }; -/** - * Simple Reader class for serializing from a string buffer. +/** Simple Reader class for serializing from a string buffer. */ class StringReader: public Reader { const unsigned char *_data; - int _bytes; + unsigned int _bytes; public: StringReader(std::string const &buffer) : _data(reinterpret_cast<const unsigned char *>(buffer.data())), @@ -199,7 +212,7 @@ return *this; } virtual Reader & operator>>(char * &x) { - assert(0); + assert(0); // avoid allocation issues for now -- no char*'s return *this; } virtual Reader & operator>>(BaseType &x) { @@ -207,7 +220,7 @@ return *this; } virtual Reader & operator>>(std::string &x) { - int length = readLength(); + unsigned int length = readLength(); assert(_bytes >= length); x.clear(); x.append(reinterpret_cast<const char*>(_data), length); @@ -218,9 +231,8 @@ }; -/** - * Base class for TagWriter and TagReader which manages a stack - * of nested records. +/** Base class for TagWriter and TagReader which manages a stack + * of nested records. */ class TagBase { protected: @@ -232,8 +244,7 @@ }; -/** - * Class for writing tagged records to wire format. +/** Class for writing tagged records to wire format. */ class TagWriter: public TagBase { public: @@ -270,8 +281,7 @@ }; -/** - * Class for reading tagged records from wire format. +/** Class for reading tagged records from wire format. */ class TagReader: public TagBase { public: @@ -311,10 +321,9 @@ }; -/** - * Base class for auto-generated record classes that can be serialized - * to a tagged binary format. Subclasses are generated by compiling - * record definitions with the TaggedRecordCompiler. +/** Base class for auto-generated record classes that can be serialized + * to a tagged binary format. Subclasses are generated by compiling + * record definitions with the TaggedRecordCompiler. */ class TaggedRecord: public Referenced { public: @@ -337,8 +346,7 @@ } -/** - * Small helper class for indenting TaggedRecord dumps. +/** Small helper class for indenting TaggedRecord dumps. */ class Indent { public: @@ -348,8 +356,8 @@ Indent & operator--() { --level; return *this; } }; -std::ostream & operator << (std::ostream &os, Indent const &indent) { - for (int i = 0; i < indent.level; ++i) os << " "; +inline std::ostream & operator << (std::ostream &os, Indent const &indent) { + for (int i = 0; i < indent.level; ++i) os << " "; return os; } Added: trunk/CSP/SimData/Include/SimData/TaggedRecordRegistry.h =================================================================== --- trunk/CSP/SimData/Include/SimData/TaggedRecordRegistry.h 2004-06-21 07:02:44 UTC (rev 1058) +++ trunk/CSP/SimData/Include/SimData/TaggedRecordRegistry.h 2004-06-21 07:11:10 UTC (rev 1059) @@ -0,0 +1,175 @@ +/* SimData: Data Infrastructure for Simulations + * Copyright (C) 2004 Mark Rose <mk...@us...> + * + * This file is part of SimData. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +/** + * @file TaggedRecordRegistry.h + * @brief Classes for storing and accessing tagged record factories. + */ + + +#ifndef __SIMDATA_TAGGEDRECORDREGISTRY_H__ +#define __SIMDATA_TAGGEDRECORDREGISTRY_H__ + +#include <string> +#include <vector> +#include <map> + +#include <SimData/Export.h> +#include <SimData/HashUtility.h> +#include <SimData/TaggedRecord.h> +#include <SimData/Singleton.h> +#include <SimData/Namespace.h> +#include <SimData/ExceptionBase.h> + + +NAMESPACE_SIMDATA + + +/** Abstract interface for TaggedRecord factories. + * + * Automatically registers with the TaggedRecordRegistry when instantiated. + */ +class SIMDATA_EXPORT TaggedRecordFactoryBase { +public: + TaggedRecordFactoryBase() { } + virtual Ref<TaggedRecord> create() const=0; + virtual std::string getName() const=0; + virtual int getVersion() const=0; + virtual int64 getId() const=0; + virtual ~TaggedRecordFactoryBase() { } +}; + + +/** Singleton class to store and access all TaggedRecords in the application. + * + * TaggedRecord classes automatically register themselves with the global instance + * of this class at startup. + * + * @author Mark Rose <mr...@st...> + */ +class SIMDATA_EXPORT TaggedRecordRegistry: public Singleton<TaggedRecordRegistry> { + +friend class Singleton<TaggedRecordRegistry>; + +template <class RECORD> friend class TaggedRecordFactory; + +public: + typedef std::vector<TaggedRecordFactoryBase *> FactoryList; + + /** Get an object interface by object class name. + * + * @returns 0 if the interface is not found. + */ + Ref<TaggedRecord> createRecord(std::string const &name) const { + FactoryMap::const_iterator it = _map.find(name); + if (it != _map.end()) return it->second->create(); + return 0; + } + + /** Get an object interface by object class hash. + * + * @returns 0 if the interface is not found. + */ + Ref<TaggedRecord> createRecord(hasht key) const { + FactoryIdMap::const_iterator it = _id_map.find(key); + if (it != _id_map.end()) return it->second->create(); + return 0; + } + + /** Test if an object interface is registered. + * + * @param name The object class name. + */ + bool hasFactory(std::string const &name) const { + FactoryMap::const_iterator it = _map.find(name); + return it != _map.end(); + } + + /** Test if an object interface is registered. + * + * @param key The object class hash. + */ + bool hasFactory(hasht key) const { + FactoryIdMap::const_iterator it = _id_map.find(key); + return it != _id_map.end(); + } + + /** Get a list of all interfaces in the registry. + */ + std::vector<TaggedRecordFactoryBase *> getFactories() const { + std::vector<TaggedRecordFactoryBase *> list; + FactoryIdMap::const_iterator it = _id_map.begin(); + for (; it != _id_map.end(); ++it) { + list.push_back(it->second); + } + return list; + } + + /** Get the interface registry singleton. + */ + static TaggedRecordRegistry &getTaggedRecordRegistry() { + return getInstance(); + } + +private: + + ~TaggedRecordRegistry() { } + + /** Register a factory with the registry. + */ + void registerFactory(TaggedRecordFactoryBase *factory) { + assert(factory != 0); + assert(!hasFactory(factory->getName())); + SIMDATA_LOG(LOG_ALL, LOG_INFO, "Registering TaggedRecordFactory<" << factory->getName() << "> [" << factory->getId() << "]"); + _map[factory->getName()] = factory; + _id_map[factory->getId()] = factory; + } + + TaggedRecordRegistry() { } + + typedef HASH_MAPS<std::string, TaggedRecordFactoryBase*, hashstring, eqstring>::Type FactoryMap; + typedef HASHT_MAP<TaggedRecordFactoryBase*>::Type FactoryIdMap; + + FactoryMap _map; + FactoryIdMap _id_map; + +}; + + +/** Factory template for creating TaggedRecord subclasses. + */ +template <class RECORD> +class SIMDATA_EXPORT TaggedRecordFactory: public TaggedRecordFactoryBase { +public: + TaggedRecordFactory(): TaggedRecordFactoryBase() { + TaggedRecordRegistry ®istry = TaggedRecordRegistry::getInstance(); + registry.registerFactory(this); + } + virtual Ref<TaggedRecord> create() const { return new RECORD(); } + virtual std::string getName() const { return RECORD::_getName(); } + virtual int getVersion() const { return RECORD::_getVersion(); } + virtual int64 getId() const { return RECORD::_getId(); }; +}; + + +NAMESPACE_SIMDATA_END + +#endif // __SIMDATA_TAGGEDRECORDREGISTRY_H__ |