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 

Generated on Mon Mar 20 22:00:09 2006 for GT2005 by doxygen 1.3.6