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