00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "stdmisc.h"
00027
00028 #include "nel/misc/stream.h"
00029
00030 using namespace std;
00031
00032
00033 namespace NLMISC
00034 {
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 EStream::EStream( const IStream &f ) : Exception( "In Stream: " + f.getStreamName() + string(": Stream Error") )
00046 {
00047 StreamName= f.getStreamName();
00048 }
00049
00050 EStream::EStream( const IStream &f, const std::string& str )
00051 : Exception( "In Stream: " + f.getStreamName() + ": " + str )
00052 {
00053 StreamName= f.getStreamName();
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 bool IStream::_ThrowOnOlder=false;
00066 bool IStream::_ThrowOnNewer=true;
00067
00068
00069
00070 void IStream::setVersionException(bool throwOnOlder, bool throwOnNewer)
00071 {
00072 _ThrowOnOlder=throwOnOlder;
00073 _ThrowOnNewer=throwOnNewer;
00074 }
00075
00076
00077 void IStream::getVersionException(bool &throwOnOlder, bool &throwOnNewer)
00078 {
00079 throwOnOlder=_ThrowOnOlder;
00080 throwOnNewer=_ThrowOnNewer;
00081 }
00082
00083
00084
00085
00086
00087
00088 IStream::IStream( const IStream& other )
00089 {
00090 operator=( other );
00091
00092
00093 _XML = false;
00094 }
00095
00096
00097
00098
00099
00100 IStream& IStream::operator=( const IStream& other )
00101 {
00102 _InputStream = other._InputStream;
00103 return *this;
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113 void IStream::serialIStreamable(IStreamable* &ptr)
00114 {
00115 uint64 node=0;
00116
00117
00118 xmlPushBegin ("POLYPTR");
00119
00120 if(isReading())
00121 {
00122
00123 xmlSetAttrib ("id");
00124
00125 serial(node);
00126
00127 if(node==0)
00128 {
00129 ptr=NULL;
00130
00131
00132 xmlPushEnd ();
00133 }
00134 else
00135 {
00136 ItIdMap it;
00137 it= _IdMap.find(node);
00138
00139
00140 if( it==_IdMap.end() )
00141 {
00142
00143 string className;
00144
00145
00146 xmlSetAttrib ("class");
00147
00148 serial(className);
00149
00150
00151 xmlPushEnd ();
00152
00153
00154 ptr= dynamic_cast<IStreamable*> (CClassRegistry::create(className));
00155 if(ptr==NULL)
00156 #ifdef NL_DEBUG
00157 throw EUnregisteredClass(className);
00158 #else
00159 throw EUnregisteredClass();
00160 #endif
00161
00162
00163 #ifdef NL_DEBUG
00164 nlassert(CClassRegistry::checkObject(ptr));
00165 #endif
00166
00167
00168 _IdMap.insert( ValueIdMap(node, ptr) );
00169
00170
00171 ptr->serial(*this);
00172 }
00173 else
00174 {
00175 ptr= static_cast<IStreamable*>(it->second);
00176
00177
00178 xmlPushEnd ();
00179 }
00180 }
00181 }
00182 else
00183 {
00184 if(ptr==NULL)
00185 {
00186 node= 0;
00187
00188
00189 xmlSetAttrib ("id");
00190
00191 serial(node);
00192
00193
00194 xmlPushEnd ();
00195 }
00196 else
00197 {
00198
00199 nlassert(sizeof(uint) == sizeof(void *));
00200 node= (uint64)((uint)ptr);
00201
00202
00203 xmlSetAttrib ("id");
00204
00205 serial(node);
00206
00207
00208
00209 if( _IdMap.insert( ValueIdMap(node, ptr) ).second==true )
00210 {
00211 #ifdef NL_DEBUG
00212 nlassert(CClassRegistry::checkObject(ptr));
00213 #endif
00214
00215
00216 string className=ptr->getClassName();
00217
00218
00219 xmlSetAttrib ("class");
00220
00221 serial(className);
00222
00223
00224 xmlPushEnd ();
00225
00226
00227 ptr->serial(*this);
00228 }
00229 else
00230 {
00231
00232 xmlPushEnd ();
00233 }
00234 }
00235 }
00236
00237
00238 xmlPop ();
00239 }
00240
00241 void IStream::resetPtrTable()
00242 {
00243 _IdMap.clear();
00244 }
00245
00246
00247
00248
00249
00250
00251
00252
00253 uint IStream::serialVersion(uint currentVersion)
00254 {
00255 uint8 b=0;
00256 uint32 v=0;
00257 uint streamVersion;
00258
00259
00260 xmlPush ("VERSION");
00261
00262 if(isReading())
00263 {
00264 serial(b);
00265 if(b==0xFF)
00266 serial(v);
00267 else
00268 v=b;
00269 streamVersion=v;
00270
00271
00272 if(_ThrowOnOlder && streamVersion < currentVersion)
00273 throw EOlderStream(*this);
00274 if(_ThrowOnNewer && streamVersion > currentVersion)
00275 throw ENewerStream(*this);
00276 }
00277 else
00278 {
00279 v= streamVersion=currentVersion;
00280 if(v>=0xFF)
00281 {
00282 b=0xFF;
00283 serial(b);
00284 serial(v);
00285 }
00286 else
00287 {
00288 b= (uint8)v;
00289 serial(b);
00290 }
00291 }
00292
00293
00294 xmlPop ();
00295
00296 return streamVersion;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305 void IStream::serialCont(vector<uint8> &cont)
00306 {
00307 sint32 len=0;
00308 if(isReading())
00309 {
00310 serial(len);
00311 cont.resize(len);
00312 if (len != 0)
00313 serialBuffer( (uint8*)&(*cont.begin()) , len);
00314 }
00315 else
00316 {
00317 len= cont.size();
00318 serial(len);
00319 if (len != 0)
00320 serialBuffer( (uint8*)&(*cont.begin()) , len);
00321 }
00322 }
00323
00324 void IStream::serialCont(vector<sint8> &cont)
00325 {
00326 sint32 len=0;
00327 if(isReading())
00328 {
00329 serial(len);
00330 cont.resize(len);
00331 if (len != 0)
00332 serialBuffer( (uint8*)&(*cont.begin()) , len);
00333 }
00334 else
00335 {
00336 len= cont.size();
00337 serial(len);
00338 if (len != 0)
00339 serialBuffer( (uint8*)&(*cont.begin()) , len);
00340 }
00341 }
00342
00343 void IStream::serialCont(vector<bool> &cont)
00344 {
00345 sint32 len=0;
00346 vector<uint8> vec;
00347
00348 if(isReading())
00349 {
00350 serial(len);
00351 cont.resize(len);
00352
00353 if (len != 0)
00354 {
00355
00356 sint lb= (len+7)/8;
00357 vec.resize(lb);
00358 serialBuffer( (uint8*)&(*vec.begin()) , lb);
00359 for(sint i=0;i<len;i++)
00360 {
00361 uint bit= (vec[i>>3]>>(i&7)) & 1;
00362 cont[i]= bit?true:false;
00363 }
00364 }
00365 }
00366 else
00367 {
00368 len= cont.size();
00369 serial(len);
00370
00371 if (len != 0)
00372 {
00373
00374 sint lb= (len+7)/8;
00375 vec.resize(lb);
00376 fill_n(vec.begin(), lb, 0);
00377 for(sint i=0;i<len;i++)
00378 {
00379 uint bit= cont[i]?1:0;
00380 vec[i>>3]|= bit<<(i&7);
00381 }
00382 serialBuffer( (uint8*)&(*vec.begin()) , lb);
00383 }
00384 }
00385
00386 }
00387
00388 bool IStream::seek (sint32 offset, TSeekOrigin origin)
00389 {
00390 throw ESeekNotSupported(*this);
00391 return false;
00392 }
00393
00394 sint32 IStream::getPos ()
00395 {
00396 throw ESeekNotSupported(*this);
00397 }
00398
00399
00400 void IStream::setInOut(bool inputStream)
00401 {
00402 _InputStream= inputStream;
00403 }
00404
00405
00406
00407 string IStream::getStreamName() const
00408 {
00409 return "";
00410 }
00411
00412
00413
00414 void IStream::setXMLMode (bool on)
00415 {
00416 _XML = on;
00417 }
00418
00419
00420 }
00421