Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

# Tools/Streams/StreamHandler.h

Go to the documentation of this file.

    00001 #ifndef __StreamHandler_h_
    00002 #define __StreamHandler_h_
    00003
    00004 #include "Tools/Streams/InOut.h"
    00005 #include "Tools/Streams/Streamable.h"
    00006
    00007 #ifndef NEWDEBUGGING
    00008 #define STREAM_REGISTER_BEGIN_EXT( s)
    00009
    00010 #define STREAM_EXT( stream, s) \
    00011   streamObject( stream ,s);
    00012
    00013 #define STREAM_ENUMASINT_EXT( stream, s) \
    00014   streamEnum( stream , s);
    00015
    00016 #define STREAM_ENUM_EXT( stream, s, numberOfEnumElements, getNameFunctionPtr) \
    00017   streamEnum( stream , s);
    00018
    00019 #define STREAM_BASE_EXT( stream, s) \
    00020   streamObject( stream, s);
    00021
    00022 #define STREAM_ARRAY_EXT( stream, s) \
    00023   streamStaticArray( stream, s, sizeof(s));
    00024
    00025 #define STREAM_DYN_ARRAY_EXT( stream, s, count) \
    00026   streamDynamicArray( stream, s, count);
    00027
    00028 #define STREAM_REGISTER_BEGIN()
    00029
    00030 #define STREAM_BASE( s) \
    00031   if( in){ \
    00032     if(dynamic_cast< s *>(this)) \
    00033       this-> s ::serialize( in, out); \
    00034     else \
    00035       *in >> (*this); \
    00036   }else{ \
    00037     if(dynamic_cast< s *>(this)) \
    00038       this-> s ::serialize( in, out); \
    00039     else \
    00040       *out << (*this); \
    00041   }
    00042
    00043 #define STREAM( s) \
    00044    if( in){ \
    00045       *in >> s; \
    00046     }else{ \
    00047       *out << s; \
    00048     }
    00049
    00050 #define STREAM_ENUMASINT( s) \
    00051   if( in){ \
    00052     streamEnum( *in , s);\
    00053   }else{ \
    00054     streamEnum( *out , s);\
    00055   }
    00056
    00057 #define STREAM_ENUM( s, numberOfEnumElements, getNameFunctionPtr) \
    00058   if( in){ \
    00059     streamEnum( *in , s);\
    00060   }else{ \
    00061     streamEnum( *out , s);\
    00062   }
    00063
    00064 #define STREAM_ARRAY( s) \
    00065   if(in) \
    00066     streamStaticArray( *in, s, sizeof(s)); \
    00067   else \
    00068     streamStaticArray( *out, s, sizeof(s));
    00069
    00070 #define STREAM_DYN_ARRAY( s, count) \
    00071   if(in) \
    00072     streamDynamicArray( *in, s, count); \
    00073   else \
    00074     streamDynamicArray( *out, s, count);
    00075
    00076 #define STREAM_REGISTER_FINISH()
    00077
    00078
    00079 #else // #ifdef NEWDEBUGGING
    00080
    00081 #define STREAM_REGISTER_BEGIN_EXT( s) \
    00082   getStreamHandler().startRegistration( typeid(s).name(), true);
    00083
    00084 #define STREAM_EXT( stream, s) \
    00085   getStreamHandler().registerWithSpecification( #s, s); \
    00086   streamObject( stream ,s);
    00087
    00088 #define STREAM_ENUMASINT_EXT( stream, s) \
    00089   { int ____xyzstreamhandlertemp; getStreamHandler().registerWithSpecification( #s, ____xyzstreamhandlertemp); }\
    00090   streamEnum( stream , s);
    00091
    00092 #define STREAM_ENUM_EXT( stream, s, numberOfEnumElements, getNameFunctionPtr) \
    00093   getStreamHandler().registerEnumWithSpecification( #s, s, numberOfEnumElements, getNameFunctionPtr); \
    00094   streamEnum( stream , s);
    00095
    00096 #define STREAM_BASE_EXT( stream, s) \
    00097   getStreamHandler().registerBase(); \
    00098   streamObject( stream, s);
    00099
    00100 #define STREAM_ARRAY_EXT( stream, s) \
    00101   getStreamHandler().registerWithSpecification( #s, s); \
    00102   streamStaticArray( stream, s, sizeof(s));
    00103
    00104 #define STREAM_DYN_ARRAY_EXT( stream, s, count) \
    00105   getStreamHandler().registerDynamicArrayWithSpecification( #s, s); \
    00106   streamDynamicArray( stream, s, count);
    00107
    00108 #define STREAM_REGISTER_BEGIN() \
    00109   getStreamHandler().startRegistration( typeid(*this).name(), false);
    00110
    00111 #define STREAM_BASE( s) \
    00112   getStreamHandler().registerBase(); \
    00113   if( in){ \
    00114     if(dynamic_cast< s *>(this)) \
    00115       this-> s ::serialize( in, out); \
    00116     else \
    00117       *in >> (*this); \
    00118   }else{ \
    00119     if(dynamic_cast< s *>(this)) \
    00120       this-> s ::serialize( in, out); \
    00121     else \
    00122       *out << (*this); \
    00123   }
    00124
    00125 #define STREAM( s) \
    00126   getStreamHandler().registerWithSpecification( #s, s); \
    00127     if( in){ \
    00128       *in >> s; \
    00129     }else{ \
    00130       *out << s; \
    00131     }
    00132
    00133 #define STREAM_ENUMASINT( s) \
    00134   { int ____xyzstreamhandlertemp; getStreamHandler().registerWithSpecification( #s, ____xyzstreamhandlertemp); }\
    00135   if( in){ \
    00136     streamEnum( *in , s);\
    00137   }else{ \
    00138     streamEnum( *out , s);\
    00139   }
    00140
    00141 #define STREAM_ENUM( s, numberOfEnumElements, getNameFunctionPtr) \
    00142   getStreamHandler().registerEnumWithSpecification( #s, s, numberOfEnumElements, getNameFunctionPtr); \
    00143   if( in){ \
    00144     streamEnum( *in , s);\
    00145   }else{ \
    00146     streamEnum( *out , s);\
    00147   }
    00148
    00149 #define STREAM_ARRAY( s) \
    00150   getStreamHandler().registerWithSpecification( #s, s); \
    00151   if(in) \
    00152     streamStaticArray( *in, s, sizeof(s)); \
    00153   else \
    00154     streamStaticArray( *out, s, sizeof(s));
    00155
    00156 #define STREAM_DYN_ARRAY( s, count) \
    00157   getStreamHandler().registerDynamicArrayWithSpecification( #s, s); \
    00158   if(in) \
    00159     streamDynamicArray( *in, s, count); \
    00160   else \
    00161     streamDynamicArray( *out, s, count);
    00162
    00163 #define STREAM_REGISTER_FINISH() \
    00164   getStreamHandler().finishRegistration();
    00165
    00166 #endif // #ifndef NEWDEBUGGING
    00167
    00168 #include <vector>
    00169 #include <stack>
    00170 #ifdef WIN32
    00171   #pragma warning(disable:4786)
    00172   #include <typeinfo.h>
    00173   #if _MSC_VER > 1200
    00174     #include <hash_map>
    00175     using stdext::hash_map;
    00176   #else
    00177     #include <map>
    00178     #define hash_map map
    00179     using std::map;
    00180   #endif
    00181 #else
    00182   #include <typeinfo>
    00183   #include <ext/hash_map>
    00184   using __gnu_cxx::hash_map;
    00185 #endif
    00186
    00187   struct RegisteringAttributes{
    00188     bool registering;
    00189     bool baseClass;
    00190     bool externalOperator;
    00191   } ;
    00192 class StreamHandler
    00193 {
    00194   friend Out& operator<<(Out&, const StreamHandler&);
    00195   hash_map<const char*,const char*> basicTypeSpecification;
    00196   hash_map<const char*, std::vector<std::pair< std::string, const char*> > >specification;
    00197
    00198   hash_map<const char*, std::vector<const char*> > enumSpecification;
    00199
    00200   std::stack< std::pair< hash_map<const char*, std::vector<std::pair< std::string, const char*> > >::iterator, RegisteringAttributes> > currentRegisteringEntryStack;
    00201
    00202 public:
    00203   bool registering;
    00204   bool registeringBase;
    00205   StreamHandler():registering(false),registeringBase(false)
    00206   {
    00207     basicTypeSpecification[ typeid(double).name()]  = "double";
    00208     basicTypeSpecification[ typeid(bool).name()]  = "bool";
    00209     basicTypeSpecification[ typeid(float).name()]  = "float";
    00210     basicTypeSpecification[ typeid(int).name()]  = "int";
    00211     basicTypeSpecification[ typeid(unsigned int).name()]  = "unsigned int";
    00212     basicTypeSpecification[ typeid(long).name()]  = "long";
    00213     basicTypeSpecification[ typeid(unsigned long).name()]  = "unsigned long";
    00214     basicTypeSpecification[ typeid(char).name()]  = "char";
    00215     basicTypeSpecification[ typeid(unsigned char).name()]  = "unsigned char";
    00216   }
    00217
    00218   void startRegistration(const char* name, bool registerWithExternalOperator);
    00219   void registerBase(){ registeringBase=true;}
    00220   void finishRegistration()
    00221   {
    00222     if( currentRegisteringEntryStack.size() > 0)
    00223     {
    00224       if( !currentRegisteringEntryStack.top().second.baseClass)
    00225         currentRegisteringEntryStack.pop();
    00226       else
    00227         currentRegisteringEntryStack.top().second.baseClass = false;
    00228     }
    00229     if( currentRegisteringEntryStack.size() <= 0)
    00230       registering = false;
    00231     else
    00232       registering = currentRegisteringEntryStack.top().second.registering;
    00233     registeringBase = false;
    00234   }
    00235
    00236   template<class T>
    00237   void registerWithSpecification(const char* name, T& t)
    00238   {
    00239     if(registering  == true && currentRegisteringEntryStack.top().second.registering)
    00240     {
    00241       std::string nameString = name;
    00242       if(currentRegisteringEntryStack.top().second.externalOperator)
    00243       {
    00244         nameString.erase( 0, nameString.find(".")+1);
    00245         std::pair< std::string, const char*> names ( nameString, typeid(t).name());
    00246         currentRegisteringEntryStack.top().first->second.push_back(names);
    00247
    00248       }
    00249       else
    00250       {
    00251         std::pair< std::string, const char*> names ( name, typeid(t).name());
    00252         currentRegisteringEntryStack.top().first->second.push_back(names);
    00253       }
    00254     }
    00255   }
    00256   template<class T>
    00257   void registerDynamicArrayWithSpecification(const char* name, T& t)
    00258   {
    00259     if(registering  == true && currentRegisteringEntryStack.top().second.registering)
    00260     {
    00261       std::string nameString = name;
    00262       if(currentRegisteringEntryStack.top().second.externalOperator)
    00263       {
    00264         nameString.erase( 0, nameString.find(".")+1);
    00265         std::pair< std::string, const char*> names ( nameString,  typeid(&*t).name());
    00266         currentRegisteringEntryStack.top().first->second.push_back(names);
    00267       }
    00268       else
    00269       {
    00270         std::pair< std::string, const char*> names ( name, typeid(&*t).name());
    00271         currentRegisteringEntryStack.top().first->second.push_back(names);
    00272       }
    00273     }
    00274   }
    00275
    00276   template<class T>
    00277   void registerEnumWithSpecification(const char* name, const T& t, T numberOfEnumElements, const char* (*fp)(T))
    00278   {
    00279     if(registering  == true && currentRegisteringEntryStack.top().second.registering)
    00280     {
    00281       std::string nameString = name;
    00282       if(currentRegisteringEntryStack.top().second.externalOperator)
    00283       {
    00284         nameString.erase( 0, nameString.find(".")+1);
    00285         std::pair< std::string, const char*> names ( nameString,  typeid(t).name());
    00286         currentRegisteringEntryStack.top().first->second.push_back(names);
    00287       }
    00288       else
    00289       {
    00290         std::pair< std::string, const char*> names ( name, typeid(t).name());
    00291         currentRegisteringEntryStack.top().first->second.push_back(names);
    00292       }
    00293
    00294
    00295       // register enum if necessary
    00296 //      hash_map<const char*, std::vector<const char*> >::iterator enumSpecificationEntry;
    00297 //      enumSpecificationEntry = enumSpecification.find( typeid(t).name());
    00298       if(enumSpecification.find( typeid(t).name()) == enumSpecification.end())
    00299       {
    00300         enumSpecification[ typeid(t).name()];
    00301         for( int i = 0; i < (int) numberOfEnumElements; ++i)
    00302         {
    00303           enumSpecification[ typeid(t).name()].push_back( (*fp)((T)i));
    00304         }
    00305       }
    00306     }
    00307   }
    00308
    00309   template<class T>
    00310     void registerEnum( const T& t, T numberOfEnumElements, const char* (*fp)(T))
    00311   {
    00312     if(enumSpecification.find( typeid(t).name()) == enumSpecification.end())
    00313     {
    00314       enumSpecification[ typeid(t).name()];
    00315       for( int i = 0; i < (int) numberOfEnumElements; ++i)
    00316       {
    00317         enumSpecification[ typeid(t).name()].push_back( (*fp)((T)i));
    00318       }
    00319     }
    00320   }
    00321 };
    00322
    00323 // In& operator>>(In& in, StreamHandler& streamHandler);
    00324 Out& operator<<(Out& out, const StreamHandler& streamHandler);
    00325
    00326
    00327 In& operator>>(In& in, bool& inBool);
    00328 Out& operator<<(Out& out, bool& outBool);
    00329
    00330 template<class T>
    00331 In& streamStaticArray(In& in, T inArray[], int size)
    00332 {
    00333   int numberOfEntries = size/sizeof(T);
    00334   for(int i = 0; i < numberOfEntries;++i)
    00335   {
    00336       in >> inArray[i];
    00337   }
    00338   return in;
    00339 }
    00340 template<class T>
    00341 Out& streamStaticArray(Out& out, T outArray[], int size)
    00342 {
    00343   int numberOfEntries = size/sizeof(T);
    00344   for(int i = 0; i < numberOfEntries;++i)
    00345   {
    00346       out << outArray[i];
    00347   }
    00348   return out;
    00349 }
    00350
    00351 template<class T>
    00352 In& streamDynamicArray(In& in, T* inArray, int& numberOfEntries)
    00353 {
    00354   in >> numberOfEntries;
    00355   for(int i = 0; i < numberOfEntries;++i)
    00356   {
    00357       in >> inArray[i];
    00358   }
    00359   return in;
    00360 }
    00361 template<class T>
    00362 Out& streamDynamicArray(Out& out, T* outArray, int numberOfEntries)
    00363 {
    00364   out << numberOfEntries;
    00365   for(int i = 0; i < numberOfEntries;++i)
    00366   {
    00367       out << outArray[i];
    00368   }
    00369   return out;
    00370 }
    00371
    00372
    00373 // global StreamHandler stuff
    00374 // global StreamHandler Object
    00375 void initStreamHandler(StreamHandler* streamHandlerPtr);
    00376 StreamHandler& getStreamHandler();
    00377
    00378 template<class T>
    00379 void streamObject(In& in, T& t)
    00380 {
    00381   in >> t;
    00382 }
    00383 template<class T>
    00384 void streamObject(Out& out, T& t)
    00385 {
    00386   out << t;
    00387 }
    00388 template<class T>
    00389 void streamEnum(In& in, T& t)
    00390 {
    00391   int i;
    00392   in >> i;
    00393   t = (T) i;
    00394 }
    00395 template<class T>
    00396 void streamEnum(Out& out, T& t)
    00397 {
    00398   int i = (int) t;
    00399   out << i;
    00400 }
    00401
    00402
    00403
    00404 #ifdef hash_map
    00405 #undef hash_map
    00406 #endif
    00407 #endif // __StreamHandler_h_
    00408