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
00296
00297
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
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
00374
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