00001
00002
00003
00004
00005
00006
00007
00008 #if defined(_MSC_VER) && _MSC_VER < 1299 // VC6 doesn't support template specialization
00009 #include "BitStream_NoTemplate.cpp"
00010 #else
00011
00012 #include "BitStream.h"
00013 #include <stdio.h>
00014 #include <string.h>
00015 #include <stdlib.h>
00016
00017 #include "SocketIncludes.h"
00018
00019 #if defined(_XBOX) || defined(X360)
00020
00021 #elif defined(_WIN32)
00022 #include <winsock2.h>
00023 #include <memory.h>
00024 #include <cmath>
00025 #include <float.h>
00026 #elif defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3)
00027
00028 #else
00029 #include <arpa/inet.h>
00030 #include <memory.h>
00031 #include <cmath>
00032 #include <float.h>
00033 #endif
00034
00035
00036 #ifndef _WIN32
00037 #define _copysign copysign
00038 #endif
00039
00040
00041
00042 using namespace RakNet;
00043
00044 #ifdef _MSC_VER
00045 #pragma warning( push )
00046 #endif
00047
00048 BitStream::BitStream()
00049 {
00050 numberOfBitsUsed = 0;
00051
00052 numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE * 8;
00053 readOffset = 0;
00054
00055 data = ( unsigned char* ) stackData;
00056
00057 #ifdef _DEBUG
00058
00059 #endif
00060
00061 copyData = true;
00062 }
00063
00064 BitStream::BitStream( const unsigned int initialBytesToAllocate )
00065 {
00066 numberOfBitsUsed = 0;
00067 readOffset = 0;
00068 if (initialBytesToAllocate <= BITSTREAM_STACK_ALLOCATION_SIZE)
00069 {
00070 data = ( unsigned char* ) stackData;
00071 numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE * 8;
00072 }
00073 else
00074 {
00075 data = ( unsigned char* ) rakMalloc_Ex( (size_t) initialBytesToAllocate, __FILE__, __LINE__ );
00076 numberOfBitsAllocated = initialBytesToAllocate << 3;
00077 }
00078 #ifdef _DEBUG
00079 RakAssert( data );
00080 #endif
00081
00082 copyData = true;
00083 }
00084
00085 BitStream::BitStream( unsigned char* _data, const unsigned int lengthInBytes, bool _copyData )
00086 {
00087 numberOfBitsUsed = lengthInBytes << 3;
00088 readOffset = 0;
00089 copyData = _copyData;
00090 numberOfBitsAllocated = lengthInBytes << 3;
00091
00092 if ( copyData )
00093 {
00094 if ( lengthInBytes > 0 )
00095 {
00096 if (lengthInBytes < BITSTREAM_STACK_ALLOCATION_SIZE)
00097 {
00098 data = ( unsigned char* ) stackData;
00099 numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE << 3;
00100 }
00101 else
00102 {
00103 data = ( unsigned char* ) rakMalloc_Ex( (size_t) lengthInBytes, __FILE__, __LINE__ );
00104 }
00105 #ifdef _DEBUG
00106 RakAssert( data );
00107 #endif
00108 memcpy( data, _data, (size_t) lengthInBytes );
00109 }
00110 else
00111 data = 0;
00112 }
00113 else
00114 data = ( unsigned char* ) _data;
00115 }
00116
00117
00118 void BitStream::SetNumberOfBitsAllocated( const BitSize_t lengthInBits )
00119 {
00120 #ifdef _DEBUG
00121 RakAssert( lengthInBits >= ( BitSize_t ) numberOfBitsAllocated );
00122 #endif
00123 numberOfBitsAllocated = lengthInBits;
00124 }
00125
00126 BitStream::~BitStream()
00127 {
00128 if ( copyData && numberOfBitsAllocated > (BITSTREAM_STACK_ALLOCATION_SIZE << 3))
00129 rakFree_Ex( data , __FILE__, __LINE__ );
00130 }
00131
00132 void BitStream::Reset( void )
00133 {
00134
00135
00136
00137
00138 if ( numberOfBitsUsed > 0 )
00139 {
00140
00141 }
00142
00143
00144
00145 numberOfBitsUsed = 0;
00146
00147
00148 readOffset = 0;
00149
00150
00151
00152
00153 }
00154
00155
00156 void BitStream::Write( const char* inputByteArray, const unsigned int numberOfBytes )
00157 {
00158 if (numberOfBytes==0)
00159 return;
00160
00161
00162 if ((numberOfBitsUsed & 7) == 0)
00163 {
00164 AddBitsAndReallocate( BYTES_TO_BITS(numberOfBytes) );
00165 memcpy(data+BITS_TO_BYTES(numberOfBitsUsed), inputByteArray, (size_t) numberOfBytes);
00166 numberOfBitsUsed+=BYTES_TO_BITS(numberOfBytes);
00167 }
00168 else
00169 {
00170 WriteBits( ( unsigned char* ) inputByteArray, numberOfBytes * 8, true );
00171 }
00172
00173 }
00174 void BitStream::Write( BitStream *bitStream)
00175 {
00176 Write(bitStream, bitStream->GetNumberOfBitsUsed());
00177 }
00178 void BitStream::Write( BitStream *bitStream, BitSize_t numberOfBits )
00179 {
00180 AddBitsAndReallocate( numberOfBits );
00181 BitSize_t numberOfBitsMod8;
00182
00183 if ((bitStream->GetReadOffset()&7)==0 && (numberOfBitsUsed&7)==0)
00184 {
00185 int readOffsetBytes=bitStream->GetReadOffset()/8;
00186 int numBytes=numberOfBits/8;
00187 memcpy(data + (numberOfBitsUsed >> 3), bitStream->GetData()+readOffsetBytes, numBytes);
00188 numberOfBits-=BYTES_TO_BITS(numBytes);
00189 bitStream->SetReadOffset(BYTES_TO_BITS(numBytes+readOffsetBytes));
00190 numberOfBitsUsed+=BYTES_TO_BITS(numBytes);
00191 }
00192
00193 while (numberOfBits-->0 && bitStream->readOffset + 1 <= bitStream->numberOfBitsUsed)
00194 {
00195 numberOfBitsMod8 = numberOfBitsUsed & 7;
00196 if ( numberOfBitsMod8 == 0 )
00197 {
00198
00199 if (bitStream->data[ bitStream->readOffset >> 3 ] & ( 0x80 >> ( bitStream->readOffset & 7 ) ) )
00200 {
00201
00202 data[ numberOfBitsUsed >> 3 ] = 0x80;
00203 }
00204 else
00205 {
00206
00207 data[ numberOfBitsUsed >> 3 ] = 0;
00208 }
00209
00210 }
00211 else
00212 {
00213
00214 if (bitStream->data[ bitStream->readOffset >> 3 ] & ( 0x80 >> ( bitStream->readOffset & 7 ) ) )
00215 data[ numberOfBitsUsed >> 3 ] |= 0x80 >> ( numberOfBitsMod8 );
00216
00217 }
00218
00219 bitStream->readOffset++;
00220 numberOfBitsUsed++;
00221 }
00222 }
00223 void BitStream::Write( BitStream &bitStream, BitSize_t numberOfBits )
00224 {
00225 Write(&bitStream, numberOfBits);
00226 }
00227 void BitStream::Write( BitStream &bitStream )
00228 {
00229 Write(&bitStream);
00230 }
00231 bool BitStream::Read( BitStream *bitStream, BitSize_t numberOfBits )
00232 {
00233 if (GetNumberOfUnreadBits() < numberOfBits)
00234 return false;
00235 bitStream->Write(this, numberOfBits);
00236 return true;
00237 }
00238 bool BitStream::Read( BitStream *bitStream )
00239 {
00240 bitStream->Write(this);
00241 return true;
00242 }
00243 bool BitStream::Read( BitStream &bitStream, BitSize_t numberOfBits )
00244 {
00245 if (GetNumberOfUnreadBits() < numberOfBits)
00246 return false;
00247 bitStream.Write(this, numberOfBits);
00248 return true;
00249 }
00250 bool BitStream::Read( BitStream &bitStream )
00251 {
00252 bitStream.Write(this);
00253 return true;
00254 }
00255
00256
00257 bool BitStream::Read( char* outByteArray, const unsigned int numberOfBytes )
00258 {
00259
00260 if ((readOffset & 7) == 0)
00261 {
00262 if ( readOffset + ( numberOfBytes << 3 ) > numberOfBitsUsed )
00263 return false;
00264
00265
00266 memcpy( outByteArray, data + ( readOffset >> 3 ), (size_t) numberOfBytes );
00267
00268 readOffset += numberOfBytes << 3;
00269 return true;
00270 }
00271 else
00272 {
00273 return ReadBits( ( unsigned char* ) outByteArray, numberOfBytes * 8 );
00274 }
00275 }
00276
00277
00278 void BitStream::ResetReadPointer( void )
00279 {
00280 readOffset = 0;
00281 }
00282
00283
00284 void BitStream::ResetWritePointer( void )
00285 {
00286 numberOfBitsUsed = 0;
00287 }
00288
00289
00290 void BitStream::Write0( void )
00291 {
00292 AddBitsAndReallocate( 1 );
00293
00294
00295 if ( ( numberOfBitsUsed & 7 ) == 0 )
00296 data[ numberOfBitsUsed >> 3 ] = 0;
00297
00298 numberOfBitsUsed++;
00299 }
00300
00301
00302 void BitStream::Write1( void )
00303 {
00304 AddBitsAndReallocate( 1 );
00305
00306 BitSize_t numberOfBitsMod8 = numberOfBitsUsed & 7;
00307
00308 if ( numberOfBitsMod8 == 0 )
00309 data[ numberOfBitsUsed >> 3 ] = 0x80;
00310 else
00311 data[ numberOfBitsUsed >> 3 ] |= 0x80 >> ( numberOfBitsMod8 );
00312
00313 numberOfBitsUsed++;
00314 }
00315
00316
00317 bool BitStream::ReadBit( void )
00318 {
00319 bool result = ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset & 7 ) ) ) !=0;
00320 readOffset++;
00321 return result;
00322 }
00323
00324
00325
00326
00327 void BitStream::WriteAlignedBytes( const unsigned char* inByteArray, const unsigned int numberOfBytesToWrite )
00328 {
00329 AlignWriteToByteBoundary();
00330 Write((const char*) inByteArray, numberOfBytesToWrite);
00331 }
00332 void BitStream::EndianSwapBytes( int byteOffset, int length )
00333 {
00334 if (DoEndianSwap())
00335 {
00336 ReverseBytesInPlace(data+byteOffset, length);
00337 }
00338 }
00340 void BitStream::WriteAlignedBytesSafe( const char *inByteArray, const unsigned int inputLength, const unsigned int maxBytesToWrite )
00341 {
00342 if (inByteArray==0 || inputLength==0)
00343 {
00344 WriteCompressed((unsigned int)0);
00345 return;
00346 }
00347 WriteCompressed(inputLength);
00348 WriteAlignedBytes((const unsigned char*) inByteArray, inputLength < maxBytesToWrite ? inputLength : maxBytesToWrite);
00349 }
00350
00351
00352
00353
00354 bool BitStream::ReadAlignedBytes( unsigned char* inOutByteArray, const unsigned int numberOfBytesToRead )
00355 {
00356 #ifdef _DEBUG
00357 RakAssert( numberOfBytesToRead > 0 );
00358 #endif
00359
00360 if ( numberOfBytesToRead <= 0 )
00361 return false;
00362
00363
00364 AlignReadToByteBoundary();
00365
00366 if ( readOffset + ( numberOfBytesToRead << 3 ) > numberOfBitsUsed )
00367 return false;
00368
00369
00370 memcpy( inOutByteArray, data + ( readOffset >> 3 ), (size_t) numberOfBytesToRead );
00371
00372 readOffset += numberOfBytesToRead << 3;
00373
00374 return true;
00375 }
00376 bool BitStream::ReadAlignedBytesSafe( char *inOutByteArray, int &inputLength, const int maxBytesToRead )
00377 {
00378 return ReadAlignedBytesSafe(inOutByteArray,(unsigned int&) inputLength,(unsigned int)maxBytesToRead);
00379 }
00380 bool BitStream::ReadAlignedBytesSafe( char *inOutByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead )
00381 {
00382 if (ReadCompressed(inputLength)==false)
00383 return false;
00384 if (inputLength > maxBytesToRead)
00385 inputLength=maxBytesToRead;
00386 if (inputLength==0)
00387 return true;
00388 return ReadAlignedBytes((unsigned char*) inOutByteArray, inputLength);
00389 }
00390 bool BitStream::ReadAlignedBytesSafeAlloc( char **outByteArray, int &inputLength, const unsigned int maxBytesToRead )
00391 {
00392 return ReadAlignedBytesSafeAlloc(outByteArray,(unsigned int&) inputLength, maxBytesToRead);
00393 }
00394 bool BitStream::ReadAlignedBytesSafeAlloc( char ** outByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead )
00395 {
00396 rakFree_Ex(*outByteArray, __FILE__, __LINE__ );
00397 *outByteArray=0;
00398 if (ReadCompressed(inputLength)==false)
00399 return false;
00400 if (inputLength > maxBytesToRead)
00401 inputLength=maxBytesToRead;
00402 if (inputLength==0)
00403 return true;
00404 *outByteArray = (char*) rakMalloc_Ex( (size_t) inputLength, __FILE__, __LINE__ );
00405 return ReadAlignedBytes((unsigned char*) *outByteArray, inputLength);
00406 }
00407
00408
00409 void BitStream::WriteBits( const unsigned char* inByteArray, BitSize_t numberOfBitsToWrite, const bool rightAlignedBits )
00410 {
00411
00412
00413
00414 AddBitsAndReallocate( numberOfBitsToWrite );
00415
00416 const BitSize_t numberOfBitsUsedMod8 = numberOfBitsUsed & 7;
00417
00418
00419 if (numberOfBitsUsedMod8==0 && (numberOfBitsToWrite&7)==0)
00420 {
00421 memcpy( data + ( numberOfBitsUsed >> 3 ), inByteArray, numberOfBitsToWrite>>3);
00422 numberOfBitsUsed+=numberOfBitsToWrite;
00423 return;
00424 }
00425
00426 unsigned char dataByte;
00427 const unsigned char* inputPtr=inByteArray;
00428
00429
00430 while ( numberOfBitsToWrite > 0 )
00431
00432 {
00433 dataByte = *( inputPtr++ );
00434
00435 if ( numberOfBitsToWrite < 8 && rightAlignedBits )
00436 dataByte <<= 8 - numberOfBitsToWrite;
00437
00438
00439 if ( numberOfBitsUsedMod8 == 0 )
00440 * ( data + ( numberOfBitsUsed >> 3 ) ) = dataByte;
00441 else
00442 {
00443
00444 *( data + ( numberOfBitsUsed >> 3 ) ) |= dataByte >> ( numberOfBitsUsedMod8 );
00445
00446 if ( 8 - ( numberOfBitsUsedMod8 ) < 8 && 8 - ( numberOfBitsUsedMod8 ) < numberOfBitsToWrite )
00447 {
00448 *( data + ( numberOfBitsUsed >> 3 ) + 1 ) = (unsigned char) ( dataByte << ( 8 - ( numberOfBitsUsedMod8 ) ) );
00449 }
00450 }
00451
00452 if ( numberOfBitsToWrite >= 8 )
00453 {
00454 numberOfBitsUsed += 8;
00455 numberOfBitsToWrite -= 8;
00456 }
00457 else
00458 {
00459 numberOfBitsUsed += numberOfBitsToWrite;
00460 numberOfBitsToWrite=0;
00461 }
00462 }
00463
00464 }
00465
00466
00467 void BitStream::SetData( unsigned char *inByteArray )
00468 {
00469 data=inByteArray;
00470 copyData=false;
00471 }
00472
00473
00474 void BitStream::WriteCompressed( const unsigned char* inByteArray,
00475 const unsigned int size, const bool unsignedData )
00476 {
00477 BitSize_t currentByte = ( size >> 3 ) - 1;
00478
00479 unsigned char byteMatch;
00480
00481 if ( unsignedData )
00482 {
00483 byteMatch = 0;
00484 }
00485
00486 else
00487 {
00488 byteMatch = 0xFF;
00489 }
00490
00491
00492
00493 while ( currentByte > 0 )
00494 {
00495 if ( inByteArray[ currentByte ] == byteMatch )
00496 {
00497 bool b = true;
00498 Write( b );
00499 }
00500 else
00501 {
00502
00503 bool b = false;
00504 Write( b );
00505
00506 WriteBits( inByteArray, ( currentByte + 1 ) << 3, true );
00507
00508
00509
00510 return ;
00511 }
00512
00513 currentByte--;
00514 }
00515
00516
00517 if ( ( unsignedData && ( ( *( inByteArray + currentByte ) ) & 0xF0 ) == 0x00 ) ||
00518 ( unsignedData == false && ( ( *( inByteArray + currentByte ) ) & 0xF0 ) == 0xF0 ) )
00519 {
00520 bool b = true;
00521 Write( b );
00522 WriteBits( inByteArray + currentByte, 4, true );
00523 }
00524
00525 else
00526 {
00527 bool b = false;
00528 Write( b );
00529 WriteBits( inByteArray + currentByte, 8, true );
00530 }
00531 }
00532
00533
00534
00535
00536 bool BitStream::ReadBits( unsigned char *inOutByteArray, BitSize_t numberOfBitsToRead, const bool alignBitsToRight )
00537 {
00538 #ifdef _DEBUG
00539
00540 #endif
00541 if (numberOfBitsToRead<=0)
00542 return false;
00543
00544 if ( readOffset + numberOfBitsToRead > numberOfBitsUsed )
00545 return false;
00546
00547
00548 const BitSize_t readOffsetMod8 = readOffset & 7;
00549
00550
00551 if (readOffsetMod8==0 && (numberOfBitsToRead&7)==0)
00552 {
00553 memcpy( inOutByteArray, data + ( readOffset >> 3 ), numberOfBitsToRead>>3);
00554 readOffset+=numberOfBitsToRead;
00555 return true;
00556 }
00557
00558
00559
00560 BitSize_t offset = 0;
00561
00562 memset( inOutByteArray, 0, (size_t) BITS_TO_BYTES( numberOfBitsToRead ) );
00563
00564 while ( numberOfBitsToRead > 0 )
00565 {
00566 *( inOutByteArray + offset ) |= *( data + ( readOffset >> 3 ) ) << ( readOffsetMod8 );
00567
00568 if ( readOffsetMod8 > 0 && numberOfBitsToRead > 8 - ( readOffsetMod8 ) )
00569 *( inOutByteArray + offset ) |= *( data + ( readOffset >> 3 ) + 1 ) >> ( 8 - ( readOffsetMod8 ) );
00570
00571 if (numberOfBitsToRead>=8)
00572 {
00573 numberOfBitsToRead -= 8;
00574 readOffset += 8;
00575 offset++;
00576 }
00577 else
00578 {
00579 int neg = (int) numberOfBitsToRead - 8;
00580
00581 if ( neg < 0 )
00582 {
00583
00584 if ( alignBitsToRight )
00585 * ( inOutByteArray + offset ) >>= -neg;
00586
00587 readOffset += 8 + neg;
00588 }
00589 else
00590 readOffset += 8;
00591
00592 offset++;
00593
00594 numberOfBitsToRead=0;
00595 }
00596 }
00597
00598 return true;
00599 }
00600
00601
00602 bool BitStream::ReadCompressed( unsigned char* inOutByteArray,
00603 const unsigned int size, const bool unsignedData )
00604 {
00605 unsigned int currentByte = ( size >> 3 ) - 1;
00606
00607
00608 unsigned char byteMatch, halfByteMatch;
00609
00610 if ( unsignedData )
00611 {
00612 byteMatch = 0;
00613 halfByteMatch = 0;
00614 }
00615
00616 else
00617 {
00618 byteMatch = 0xFF;
00619 halfByteMatch = 0xF0;
00620 }
00621
00622
00623
00624 while ( currentByte > 0 )
00625 {
00626
00627
00628 bool b;
00629
00630 if ( Read( b ) == false )
00631 return false;
00632
00633 if ( b )
00634 {
00635 inOutByteArray[ currentByte ] = byteMatch;
00636 currentByte--;
00637 }
00638 else
00639 {
00640
00641
00642 if ( ReadBits( inOutByteArray, ( currentByte + 1 ) << 3 ) == false )
00643 return false;
00644
00645 return true;
00646 }
00647 }
00648
00649
00650
00651
00652 if ( readOffset + 1 > numberOfBitsUsed )
00653 return false;
00654
00655 bool b;
00656
00657 if ( Read( b ) == false )
00658 return false;
00659
00660 if ( b )
00661 {
00662
00663 if ( ReadBits( inOutByteArray + currentByte, 4 ) == false )
00664 return false;
00665
00666 inOutByteArray[ currentByte ] |= halfByteMatch;
00667 }
00668 else
00669 {
00670 if ( ReadBits( inOutByteArray + currentByte, 8 ) == false )
00671 return false;
00672 }
00673
00674 return true;
00675 }
00676
00677
00678 void BitStream::AddBitsAndReallocate( const BitSize_t numberOfBitsToWrite )
00679 {
00680 BitSize_t newNumberOfBitsAllocated = numberOfBitsToWrite + numberOfBitsUsed;
00681
00682 if ( numberOfBitsToWrite + numberOfBitsUsed > 0 && ( ( numberOfBitsAllocated - 1 ) >> 3 ) < ( ( newNumberOfBitsAllocated - 1 ) >> 3 ) )
00683 {
00684 #ifdef _DEBUG
00685
00686
00687
00688 RakAssert( copyData == true );
00689 #endif
00690
00691
00693 newNumberOfBitsAllocated = ( numberOfBitsToWrite + numberOfBitsUsed ) * 2;
00694 if (newNumberOfBitsAllocated - ( numberOfBitsToWrite + numberOfBitsUsed ) > 1048576 )
00695 newNumberOfBitsAllocated = numberOfBitsToWrite + numberOfBitsUsed + 1048576;
00696
00697
00698
00699 BitSize_t amountToAllocate = BITS_TO_BYTES( newNumberOfBitsAllocated );
00700 if (data==(unsigned char*)stackData)
00701 {
00702 if (amountToAllocate > BITSTREAM_STACK_ALLOCATION_SIZE)
00703 {
00704 data = ( unsigned char* ) rakMalloc_Ex( (size_t) amountToAllocate, __FILE__, __LINE__ );
00705
00706
00707 memcpy ((void *)data, (void *)stackData, (size_t) BITS_TO_BYTES( numberOfBitsAllocated ));
00708 }
00709 }
00710 else
00711 {
00712 data = ( unsigned char* ) rakRealloc_Ex( data, (size_t) amountToAllocate, __FILE__, __LINE__ );
00713 }
00714
00715 #ifdef _DEBUG
00716 RakAssert( data );
00717 #endif
00718
00719 }
00720
00721 if ( newNumberOfBitsAllocated > numberOfBitsAllocated )
00722 numberOfBitsAllocated = newNumberOfBitsAllocated;
00723 }
00724 BitSize_t BitStream::GetNumberOfBitsAllocated(void) const
00725 {
00726 return numberOfBitsAllocated;
00727 }
00728 void BitStream::PadWithZeroToByteLength( unsigned int bytes )
00729 {
00730 if (GetNumberOfBytesUsed() < bytes)
00731 {
00732 AlignWriteToByteBoundary();
00733 unsigned int numToWrite = bytes - GetNumberOfBytesUsed();
00734 AddBitsAndReallocate( BYTES_TO_BITS(numToWrite) );
00735 memset(data+BITS_TO_BYTES(numberOfBitsUsed), 0, (size_t) numToWrite);
00736 numberOfBitsUsed+=BYTES_TO_BITS(numToWrite);
00737 }
00738 }
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765 int BitStream::NumberOfLeadingZeroes( int8_t x ) {return NumberOfLeadingZeroes((uint8_t)x);}
00766 int BitStream::NumberOfLeadingZeroes( uint8_t x )
00767 {
00768 uint8_t y;
00769 int n;
00770
00771 n = 8;
00772 y = x >> 4; if (y != 0) {n = n - 4; x = y;}
00773 y = x >> 2; if (y != 0) {n = n - 2; x = y;}
00774 y = x >> 1; if (y != 0) return n - 2;
00775 return (int)(n - x);
00776 }
00777 int BitStream::NumberOfLeadingZeroes( int16_t x ) {return NumberOfLeadingZeroes((uint16_t)x);}
00778 int BitStream::NumberOfLeadingZeroes( uint16_t x )
00779 {
00780 uint16_t y;
00781 int n;
00782
00783 n = 16;
00784 y = x >> 8; if (y != 0) {n = n - 8; x = y;}
00785 y = x >> 4; if (y != 0) {n = n - 4; x = y;}
00786 y = x >> 2; if (y != 0) {n = n - 2; x = y;}
00787 y = x >> 1; if (y != 0) return n - 2;
00788 return (int)(n - x);
00789 }
00790 int BitStream::NumberOfLeadingZeroes( int32_t x ) {return NumberOfLeadingZeroes((uint32_t)x);}
00791 int BitStream::NumberOfLeadingZeroes( uint32_t x )
00792 {
00793 uint32_t y;
00794 int n;
00795
00796 n = 32;
00797 y = x >>16; if (y != 0) {n = n -16; x = y;}
00798 y = x >> 8; if (y != 0) {n = n - 8; x = y;}
00799 y = x >> 4; if (y != 0) {n = n - 4; x = y;}
00800 y = x >> 2; if (y != 0) {n = n - 2; x = y;}
00801 y = x >> 1; if (y != 0) return n - 2;
00802 return (int)(n - x);
00803 }
00804 int BitStream::NumberOfLeadingZeroes( int64_t x ) {return NumberOfLeadingZeroes((uint64_t)x);}
00805 int BitStream::NumberOfLeadingZeroes( uint64_t x )
00806 {
00807 uint64_t y;
00808 int n;
00809
00810 n = 64;
00811 y = x >>32; if (y != 0) {n = n -32; x = y;}
00812 y = x >>16; if (y != 0) {n = n -16; x = y;}
00813 y = x >> 8; if (y != 0) {n = n - 8; x = y;}
00814 y = x >> 4; if (y != 0) {n = n - 4; x = y;}
00815 y = x >> 2; if (y != 0) {n = n - 2; x = y;}
00816 y = x >> 1; if (y != 0) return n - 2;
00817 return (int)(n - x);
00818 }
00819
00820
00821 void BitStream::AssertStreamEmpty( void )
00822 {
00823 RakAssert( readOffset == numberOfBitsUsed );
00824 }
00825 void BitStream::PrintBits( char *out ) const
00826 {
00827 if ( numberOfBitsUsed <= 0 )
00828 {
00829 strcpy(out, "No bits\n" );
00830 return;
00831 }
00832
00833 unsigned int strIndex=0;
00834 for ( BitSize_t counter = 0; counter < BITS_TO_BYTES( numberOfBitsUsed ); counter++ )
00835 {
00836 BitSize_t stop;
00837
00838 if ( counter == ( numberOfBitsUsed - 1 ) >> 3 )
00839 stop = 8 - ( ( ( numberOfBitsUsed - 1 ) & 7 ) + 1 );
00840 else
00841 stop = 0;
00842
00843 for ( BitSize_t counter2 = 7; counter2 >= stop; counter2-- )
00844 {
00845 if ( ( data[ counter ] >> counter2 ) & 1 )
00846 out[strIndex++]='1';
00847 else
00848 out[strIndex++]='0';
00849
00850 if (counter2==0)
00851 break;
00852 }
00853
00854 out[strIndex++]=' ';
00855 }
00856
00857 out[strIndex++]='\n';
00858
00859 out[strIndex++]=0;
00860 }
00861 void BitStream::PrintBits( void ) const
00862 {
00863 char out[2048];
00864 PrintBits(out);
00865 RAKNET_DEBUG_PRINTF(out);
00866 }
00867 void BitStream::PrintHex( char *out ) const
00868 {
00869 BitSize_t i;
00870 for ( i=0; i < GetNumberOfBytesUsed(); i++)
00871 {
00872 sprintf(out+i*3, "%02x ", data[i]);
00873 }
00874 }
00875 void BitStream::PrintHex( void ) const
00876 {
00877 char out[2048];
00878 PrintHex(out);
00879 RAKNET_DEBUG_PRINTF(out);
00880 }
00881
00882
00883
00884 BitSize_t BitStream::CopyData( unsigned char** _data ) const
00885 {
00886 #ifdef _DEBUG
00887 RakAssert( numberOfBitsUsed > 0 );
00888 #endif
00889
00890 *_data = (unsigned char*) rakMalloc_Ex( (size_t) BITS_TO_BYTES( numberOfBitsUsed ), __FILE__, __LINE__ );
00891 memcpy( *_data, data, sizeof(unsigned char) * (size_t) ( BITS_TO_BYTES( numberOfBitsUsed ) ) );
00892 return numberOfBitsUsed;
00893 }
00894
00895
00896 void BitStream::IgnoreBits( const BitSize_t numberOfBits )
00897 {
00898 readOffset += numberOfBits;
00899 }
00900
00901 void BitStream::IgnoreBytes( const unsigned int numberOfBytes )
00902 {
00903 IgnoreBits(BYTES_TO_BITS(numberOfBytes));
00904 }
00905
00906
00907
00908 void BitStream::SetWriteOffset( const BitSize_t offset )
00909 {
00910 numberOfBitsUsed = offset;
00911 }
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957 void BitStream::AssertCopyData( void )
00958 {
00959 if ( copyData == false )
00960 {
00961 copyData = true;
00962
00963 if ( numberOfBitsAllocated > 0 )
00964 {
00965 unsigned char * newdata = ( unsigned char* ) rakMalloc_Ex( (size_t) BITS_TO_BYTES( numberOfBitsAllocated ), __FILE__, __LINE__ );
00966 #ifdef _DEBUG
00967
00968 RakAssert( data );
00969 #endif
00970
00971 memcpy( newdata, data, (size_t) BITS_TO_BYTES( numberOfBitsAllocated ) );
00972 data = newdata;
00973 }
00974
00975 else
00976 data = 0;
00977 }
00978 }
00979 bool BitStream::IsNetworkOrderInternal(void)
00980 {
00981 #if defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3)
00982
00983 #else
00984 static const bool isNetworkOrder=(htonl(12345) == 12345);
00985 return isNetworkOrder;
00986 #endif
00987 }
00988 void BitStream::ReverseBytes(unsigned char *inByteArray, unsigned char *inOutByteArray, const unsigned int length)
00989 {
00990 for (BitSize_t i=0; i < length; i++)
00991 inOutByteArray[i]=inByteArray[length-i-1];
00992 }
00993 void BitStream::ReverseBytesInPlace(unsigned char *inOutData,const unsigned int length)
00994 {
00995 unsigned char temp;
00996 BitSize_t i;
00997 for (i=0; i < (length>>1); i++)
00998 {
00999 temp = inOutData[i];
01000 inOutData[i]=inOutData[length-i-1];
01001 inOutData[length-i-1]=temp;
01002 }
01003 }
01004
01005 bool BitStream::Read(char *varString)
01006 {
01007 return RakString::Deserialize(varString,this);
01008 }
01009 bool BitStream::Read(unsigned char *varString)
01010 {
01011 return RakString::Deserialize((char*) varString,this);
01012 }
01013 void BitStream::WriteAlignedVar8(const char *inByteArray)
01014 {
01015 RakAssert((numberOfBitsUsed&7)==0);
01016 AddBitsAndReallocate(1*8);
01017 data[( numberOfBitsUsed >> 3 ) + 0] = inByteArray[0];
01018 numberOfBitsUsed+=1*8;
01019 }
01020 bool BitStream::ReadAlignedVar8(char *inOutByteArray)
01021 {
01022 RakAssert((readOffset&7)==0);
01023 if ( readOffset + 1*8 > numberOfBitsUsed )
01024 return false;
01025
01026 inOutByteArray[0] = data[( readOffset >> 3 ) + 0];
01027 readOffset+=1*8;
01028 return true;
01029 }
01030 void BitStream::WriteAlignedVar16(const char *inByteArray)
01031 {
01032 RakAssert((numberOfBitsUsed&7)==0);
01033 AddBitsAndReallocate(2*8);
01034 #ifndef __BITSTREAM_NATIVE_END
01035 if (DoEndianSwap())
01036 {
01037 data[( numberOfBitsUsed >> 3 ) + 0] = inByteArray[1];
01038 data[( numberOfBitsUsed >> 3 ) + 1] = inByteArray[0];
01039 }
01040 else
01041 #endif
01042 {
01043 data[( numberOfBitsUsed >> 3 ) + 0] = inByteArray[0];
01044 data[( numberOfBitsUsed >> 3 ) + 1] = inByteArray[1];
01045 }
01046
01047 numberOfBitsUsed+=2*8;
01048 }
01049 bool BitStream::ReadAlignedVar16(char *inOutByteArray)
01050 {
01051 RakAssert((readOffset&7)==0);
01052 if ( readOffset + 2*8 > numberOfBitsUsed )
01053 return false;
01054 #ifndef __BITSTREAM_NATIVE_END
01055 if (DoEndianSwap())
01056 {
01057 inOutByteArray[0] = data[( readOffset >> 3 ) + 1];
01058 inOutByteArray[1] = data[( readOffset >> 3 ) + 0];
01059 }
01060 else
01061 #endif
01062 {
01063 inOutByteArray[0] = data[( readOffset >> 3 ) + 0];
01064 inOutByteArray[1] = data[( readOffset >> 3 ) + 1];
01065 }
01066
01067 readOffset+=2*8;
01068 return true;
01069 }
01070 void BitStream::WriteAlignedVar32(const char *inByteArray)
01071 {
01072 RakAssert((numberOfBitsUsed&7)==0);
01073 AddBitsAndReallocate(4*8);
01074 #ifndef __BITSTREAM_NATIVE_END
01075 if (DoEndianSwap())
01076 {
01077 data[( numberOfBitsUsed >> 3 ) + 0] = inByteArray[3];
01078 data[( numberOfBitsUsed >> 3 ) + 1] = inByteArray[2];
01079 data[( numberOfBitsUsed >> 3 ) + 2] = inByteArray[1];
01080 data[( numberOfBitsUsed >> 3 ) + 3] = inByteArray[0];
01081 }
01082 else
01083 #endif
01084 {
01085 data[( numberOfBitsUsed >> 3 ) + 0] = inByteArray[0];
01086 data[( numberOfBitsUsed >> 3 ) + 1] = inByteArray[1];
01087 data[( numberOfBitsUsed >> 3 ) + 2] = inByteArray[2];
01088 data[( numberOfBitsUsed >> 3 ) + 3] = inByteArray[3];
01089 }
01090
01091 numberOfBitsUsed+=4*8;
01092 }
01093 bool BitStream::ReadAlignedVar32(char *inOutByteArray)
01094 {
01095 RakAssert((readOffset&7)==0);
01096 if ( readOffset + 4*8 > numberOfBitsUsed )
01097 return false;
01098 #ifndef __BITSTREAM_NATIVE_END
01099 if (DoEndianSwap())
01100 {
01101 inOutByteArray[0] = data[( readOffset >> 3 ) + 3];
01102 inOutByteArray[1] = data[( readOffset >> 3 ) + 2];
01103 inOutByteArray[2] = data[( readOffset >> 3 ) + 1];
01104 inOutByteArray[3] = data[( readOffset >> 3 ) + 0];
01105 }
01106 else
01107 #endif
01108 {
01109 inOutByteArray[0] = data[( readOffset >> 3 ) + 0];
01110 inOutByteArray[1] = data[( readOffset >> 3 ) + 1];
01111 inOutByteArray[2] = data[( readOffset >> 3 ) + 2];
01112 inOutByteArray[3] = data[( readOffset >> 3 ) + 3];
01113 }
01114
01115 readOffset+=4*8;
01116 return true;
01117 }
01118 bool BitStream::ReadFloat16( float &outFloat, float floatMin, float floatMax )
01119 {
01120 unsigned short percentile;
01121 if (Read(percentile))
01122 {
01123 RakAssert(floatMax>floatMin);
01124 outFloat = floatMin + ((float) percentile / 65535.0f) * (floatMax-floatMin);
01125 if (outFloat<floatMin)
01126 outFloat=floatMin;
01127 else if (outFloat>floatMax)
01128 outFloat=floatMax;
01129 return true;
01130 }
01131 return false;
01132 }
01133 bool BitStream::SerializeFloat16(bool writeToBitstream, float &inOutFloat, float floatMin, float floatMax)
01134 {
01135 if (writeToBitstream)
01136 WriteFloat16(inOutFloat, floatMin, floatMax);
01137 else
01138 return ReadFloat16(inOutFloat, floatMin, floatMax);
01139 return true;
01140 }
01141 void BitStream::WriteFloat16( float inOutFloat, float floatMin, float floatMax )
01142 {
01143 RakAssert(floatMax>floatMin);
01144 if (inOutFloat>floatMax+.001)
01145 {
01146 RakAssert(inOutFloat<=floatMax+.001);
01147 }
01148 if (inOutFloat<floatMin-.001)
01149 {
01150 RakAssert(inOutFloat>=floatMin-.001);
01151 }
01152 float percentile=65535.0f * (inOutFloat-floatMin)/(floatMax-floatMin);
01153 if (percentile<0.0)
01154 percentile=0.0;
01155 if (percentile>65535.0f)
01156 percentile=65535.0f;
01157 Write((unsigned short)percentile);
01158 }
01159
01160 #ifdef _MSC_VER
01161 #pragma warning( pop )
01162 #endif
01163
01164 #endif // #if _MSC_VER < 1299