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/bit_mem_stream.h"
00029
00030 using namespace std;
00031
00032
00033 namespace NLMISC {
00034
00035
00036
00037
00038
00039 CBitMemStream::CBitMemStream( bool inputStream, uint32 defaultcapacity ) :
00040 CMemStream( inputStream, false, defaultcapacity ),
00041 _FreeBits( 8 )
00042 {
00043 _BufPos--;
00044 }
00045
00046
00047
00048
00049
00050 CBitMemStream::CBitMemStream( const CBitMemStream& other ) :
00051 CMemStream( other ),
00052 _FreeBits( other._FreeBits )
00053 {
00054 }
00055
00056
00057
00058
00059
00060 void CBitMemStream::serialBuffer( uint8 *buf, uint len )
00061 {
00062 uint i;
00063 uint32 v;
00064 if ( isReading() )
00065 {
00066 for ( i=0; i!=len; ++i )
00067 {
00068 serial( v, 8 );
00069 buf[i] = (uint8)v;
00070 }
00071 }
00072 else
00073 {
00074 for ( i=0; i!=len; ++i )
00075 {
00076 v = (uint32)buf[i];
00077 serial( v, 8 );
00078 }
00079 }
00080 }
00081
00082
00083
00084
00085
00086 void CBitMemStream::serialBit( bool& bit )
00087 {
00088 uint32 ubit=0;
00089 if ( isReading() )
00090 {
00091 serial( ubit, 1 );
00092 bit = ( ubit!=0 );
00093 }
00094 else
00095 {
00096 ubit = bit;
00097 serial( ubit, 1 );
00098 }
00099 }
00100
00101
00102
00103
00104
00105 #define displayByteBits(a,b,c)
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 #define displayDwordBits(a,b,c)
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 void CBitMemStream::serial( uint32& value, uint nbits, bool resetvalue )
00147 {
00148
00149 if (nbits>32 || nbits==0)
00150 throw EMemStream (string("trying to serial ")+toString(nbits)+string(" %d bits"));
00151
00152 if ( isReading() )
00153 {
00154
00155 if (getPosInBit() + nbits > lengthR() * 8)
00156 {
00157 throw EStreamOverflow();
00158 }
00159
00160 if ( resetvalue )
00161 {
00162 value = 0;
00163 }
00164
00165
00166 uint8 v = *_BufPos & ((1 << _FreeBits) - 1);
00167
00168 if ( nbits > _FreeBits )
00169 {
00170
00171 value |= (v << (nbits-_FreeBits));
00172 ++_BufPos;
00173 uint readbits = _FreeBits;
00174 displayByteBits( *_BufPos, 8, readbits-1 );
00175 _FreeBits = 8;
00176 serial( value, nbits - readbits, false );
00177 }
00178 else
00179 {
00180
00181
00182 value |= (v >> (_FreeBits-nbits));
00183 displayByteBits( *_BufPos, 8, _FreeBits-1 );
00184 if ( _FreeBits == nbits )
00185 {
00186 _FreeBits = 8;
00187 ++_BufPos;
00188 }
00189 else
00190 {
00191 _FreeBits -= nbits;
00192 }
00193 }
00194 }
00195 else
00196 {
00197
00198 if ( _FreeBits == 8 )
00199 {
00200 if (_BufPos == _Buffer.getPtr()+_Buffer.size() - 1)
00201 {
00202
00203 _Buffer.resize(_Buffer.size()*2+1);
00204 _BufPos = _Buffer.getPtr() + ((_Buffer.size()-1)/2);
00205 }
00206 else
00207 {
00208 _BufPos++;
00209 }
00210
00211
00212 *_BufPos = 0;
00213 }
00214
00215
00216
00217
00218
00219 uint32 v;
00220 if ( nbits != 32 )
00221 {
00222 uint32 mask = (1 << nbits) - 1;
00223 v = value & mask;
00224 }
00225 else
00226 {
00227 v = value;
00228 }
00229
00230
00231 if ( nbits > _FreeBits )
00232 {
00233
00234
00235 displayDwordBits( value, 32, nbits-1 );
00236 *_BufPos |= (v >> (nbits - _FreeBits));
00237 uint filledbits = _FreeBits;
00238 displayByteBits( *_BufPos, 8, filledbits-1 );
00239 _FreeBits = 8;
00240 serial( v, nbits - filledbits );
00241 }
00242 else
00243 {
00244
00245
00246 displayByteBits( *_BufPos, 8, 7 );
00247 *_BufPos |= (v << (_FreeBits-nbits));
00248 displayByteBits( *_BufPos, 8, _FreeBits-1 );
00249 _FreeBits = ((_FreeBits-1 - nbits) % 8) + 1;
00250 }
00251
00252 }
00253
00254 }
00255
00256
00257
00258
00259
00260 void CBitMemStream::serial(float &b)
00261 {
00262 uint32 uf=0;
00263 if ( isReading() )
00264 {
00265 serial( uf );
00266 b = *(float*)&uf;
00267 }
00268 else
00269 {
00270 uf = *(uint32*)&b;
00271 serial( uf );
00272 }
00273 }
00274
00275
00276
00277
00278
00279 void CBitMemStream::serial(std::string &b)
00280 {
00281 uint32 len=0;
00282
00283
00284 if ( isReading() )
00285 {
00286 serial( len );
00287 if (len > length()-getPos())
00288 {
00289 nlwarning("string maximum length reached, perhaps invalid string size (%d)", len);
00290 throw NLMISC::EInvalidDataStream();
00291 }
00292 b.resize( len );
00293 }
00294 else
00295 {
00296 len = b.size();
00297 serial( len );
00298 }
00299
00300
00301 if ( len != 0 )
00302 {
00303 serialBuffer( (uint8*)(&*b.begin()), len );
00304 }
00305 }
00306
00307
00308
00309
00310 void CBitMemStream::serial(CBitMemStream &b)
00311 {
00312 uint32 len=0;
00313
00314
00315 if ( isReading() )
00316 {
00317
00318 serial (len);
00319 if (len > length()-getPos())
00320 {
00321 nlwarning("bitmemstream maximum length reached, perhaps invalid bitmemstream size (%d)", len);
00322 throw NLMISC::EInvalidDataStream();
00323 }
00324
00325 serialBuffer (b.bufferToFill (len), len);
00326 b.resetBufPos ();
00327 }
00328 else
00329 {
00330
00331 len = b.length();
00332
00333 serial( len );
00334 serialBuffer( (uint8*) b.buffer (), len );
00335 }
00336
00337 }
00338
00339
00340
00341
00342 void CBitMemStream::serialCont(std::vector<bool> &cont)
00343 {
00344 sint32 len=0;
00345 if(isReading())
00346 {
00347 serial(len);
00348 if (len/8 > (sint32)(length()-getPos()))
00349 {
00350 nlwarning("stl container maximum length reached, perhaps invalid container size (%d)", len);
00351 throw NLMISC::EInvalidDataStream();
00352 }
00353
00354 contReset(cont);
00355 cont.reserve(len);
00356
00357 for(sint i=0;i<len;i++)
00358 {
00359 bool v;
00360 serialBit(v);
00361 cont.insert(cont.end(), v);
00362 }
00363 }
00364 else
00365 {
00366 len= cont.size();
00367 serial(len);
00368
00369 std::vector<bool>::iterator it= cont.begin();
00370 for(sint i=0;i<len;i++, it++)
00371 {
00372 bool b = *it;
00373 serialBit( b );
00374 }
00375 }
00376 }
00377
00378
00379
00380 }