TypeCollection.h

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 #ifndef __OASYS_TYPE_COLLECTION_H__
00039 #define __OASYS_TYPE_COLLECTION_H__
00040 
00041 #include <map>
00042 
00043 #include "../debug/Logger.h"
00044 #include "Serialize.h"
00045 #include "MarshalSerialize.h"
00046 
00047 namespace oasys {
00048 
00099 class TypeCollectionHelper;
00100 
00101 namespace TypeCollectionErr {
00102 enum {
00103     TYPECODE = 1,
00104     MEMORY,
00105 };
00106 };
00107 
00111 class TypeCollectionHelper {
00112 public:
00113     virtual SerializableObject* new_object() = 0;
00114     virtual const char* name() const = 0;
00115     virtual ~TypeCollectionHelper() {}
00116 };
00117 
00123 template<typename _Collection, typename _Type> class TypeCollectionCode;
00124 
00128 class TypeCollection {
00129 public:
00131     typedef u_int32_t TypeCode_t;
00132 
00133     enum {
00134         UNKNOWN_TYPE = 0xffffffff
00135     };
00136 
00138     typedef int (*Allocator_t)(TypeCode_t typecode,
00139                                SerializableObject** data);
00140     
00141     TypeCollection() {}
00142 
00143     void reg(TypeCode_t typecode, TypeCollectionHelper* helper) {
00144         ASSERT(dispatch_.find(typecode) == dispatch_.end());
00145         dispatch_[typecode] = helper;
00146     }
00147 
00151     const char* type_name(TypeCode_t typecode) {
00152         if(dispatch_.find(typecode) == dispatch_.end()) {
00153             return "";
00154         } 
00155 
00156         return dispatch_[typecode]->name();
00157     }
00158 
00159 protected:
00160     std::map<TypeCode_t, TypeCollectionHelper*> dispatch_;
00161 };
00162 
00163 template<typename _Collection>
00164 class TypeCollectionInstance : public TypeCollection {
00165 public:    
00171     static TypeCollectionInstance<_Collection>* instance() {
00172         if(!instance_) {
00173             instance_ = new TypeCollectionInstance<_Collection>();
00174         }        
00175         return instance_;
00176     }
00177 
00185     template<typename _Type>
00186     int new_object(TypeCode_t typecode, _Type** obj, bool check_type = true)
00187     {
00188         // Check that the given typecode is within the legal bounds
00189         // for the _Type of the return
00190         if(check_type && 
00191            (TypeCollectionCode<_Collection, _Type>::TYPECODE_LOW  > typecode ||
00192             TypeCollectionCode<_Collection, _Type>::TYPECODE_HIGH < typecode))
00193         {
00194             return TypeCollectionErr::TYPECODE;
00195         }
00196 
00197         // Based on the lookup in the dispatch, create a new object
00198         // and cast it to the given type. Note the use of dynamic cast to 
00199         // safely downcast.
00200         ASSERT(dispatch_.find(typecode) != dispatch_.end());
00201         *obj = dynamic_cast<_Type*>(dispatch_[typecode]->new_object());
00202         if (*obj == NULL) {
00203             log_crit("/oasys/type_collection", "out of memory");
00204             return TypeCollectionErr::MEMORY;
00205         }
00206         
00207         return 0;
00208     }
00209 
00210 private:
00211     static TypeCollectionInstance<_Collection>* instance_;
00212 };
00213 
00219 template<typename _Collection, typename _Class>
00220 class TypeCollectionDispatch : public TypeCollectionHelper {
00221 public:
00223     TypeCollectionDispatch<_Collection, _Class>(TypeCollection::TypeCode_t typecode,
00224                                                 const char* name)
00225         : name_(name)
00226     {
00227         TypeCollectionInstance<_Collection>::instance()->reg(typecode, this);
00228     }
00229 
00240     SerializableObject* new_object() {
00241         return static_cast<SerializableObject*>
00242             (new _Class(Builder()));
00243     }
00244 
00245     const char* name() const { return name_; }
00246 
00247 private:
00248     const char* name_;
00249 };
00250 
00254 #define TYPE_COLLECTION_DEFINE(_collection, _class, _typecode)          \
00255     oasys::TypeCollectionDispatch<_collection, _class>                  \
00256         _class ## TypeCollectionInstance(_typecode, #_collection "::" #_class);
00257 
00261 #define TYPE_COLLECTION_DECLARE(_Collection, _Class, _code)     \
00262 namespace oasys {                                               \
00263     template<>                                                  \
00264     struct TypeCollectionCode<_Collection, _Class> {            \
00265         enum {                                                  \
00266             TYPECODE_LOW  = _code,                              \
00267             TYPECODE_HIGH = _code                               \
00268         };                                                      \
00269         enum {                                                  \
00270             TYPECODE = _code                                    \
00271         };                                                      \
00272     };                                                          \
00273 }
00274 
00285 #define TYPE_COLLECTION_GROUP(_Collection, _Class, _low, _high) \
00286 namespace oasys {                                               \
00287     template<>                                                  \
00288     struct TypeCollectionCode<_Collection, _Class> {            \
00289         enum {                                                  \
00290             TYPECODE_LOW  = _low,                               \
00291             TYPECODE_HIGH = _high,                              \
00292         };                                                      \
00293     };                                                          \
00294 }
00295 
00299 #define TYPE_COLLECTION_INSTANTIATE(_Collection)                \
00300 template<> class oasys::TypeCollectionInstance<_Collection>*    \
00301    oasys::TypeCollectionInstance<_Collection>::instance_ = 0
00302 
00303 }; // namespace oasys
00304 
00305 #endif //__OASYS_TYPE_COLLECTION_H__

Generated on Fri Dec 22 14:48:01 2006 for DTN Reference Implementation by  doxygen 1.5.1