1 /// \file
2 ///
3 /// This file is part of RakNet Copyright 2003 Jenkins Software LLC
4 ///
5 /// Raknet is available under the terms of the GPLv3 license, see /usr/local/share/licenses/raknet-3.9.2_10,1/GPLv3.
6 
7 
8 #if defined(_MSC_VER) && _MSC_VER < 1299 // VC6 doesn't support template specialization
9 
10 #include "BitStream.h"
11 #include <stdlib.h>
12 #include <memory.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <cmath>
16 #include <float.h>
17 
18 
19 #if   defined(_WIN32)
20 #include <winsock2.h> // htonl
21 #elif defined(_CONSOLE_2)
22 #include "PS3Includes.h"
23 #else
24 #include <arpa/inet.h>
25 #endif
26 
27 // MSWin uses _copysign, others use copysign...
28 #ifndef _WIN32
29 #define _copysign copysign
30 #endif
31 
32 
33 
34 using namespace RakNet;
35 
36 #ifdef _MSC_VER
37 #pragma warning( push )
38 #endif
39 
BitStream()40 BitStream::BitStream()
41 {
42 	numberOfBitsUsed = 0;
43 	//numberOfBitsAllocated = 32 * 8;
44 	numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE * 8;
45 	readOffset = 0;
46 	//data = ( unsigned char* ) rakMalloc_Ex( 32, __FILE__, __LINE__ );
47 	data = ( unsigned char* ) stackData;
48 
49 #ifdef _DEBUG
50 	//	RakAssert( data );
51 #endif
52 	//memset(data, 0, 32);
53 	copyData = true;
54 }
55 
BitStream(const unsigned int initialBytesToAllocate)56 BitStream::BitStream( const unsigned int initialBytesToAllocate )
57 {
58 	numberOfBitsUsed = 0;
59 	readOffset = 0;
60 	if (initialBytesToAllocate <= BITSTREAM_STACK_ALLOCATION_SIZE)
61 	{
62 		data = ( unsigned char* ) stackData;
63 		numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE * 8;
64 	}
65 	else
66 	{
67 		data = ( unsigned char* ) rakMalloc_Ex( (size_t) initialBytesToAllocate, __FILE__, __LINE__ );
68 		numberOfBitsAllocated = initialBytesToAllocate << 3;
69 	}
70 #ifdef _DEBUG
71 	RakAssert( data );
72 #endif
73 	// memset(data, 0, initialBytesToAllocate);
74 	copyData = true;
75 }
76 
BitStream(unsigned char * _data,const unsigned int lengthInBytes,bool _copyData)77 BitStream::BitStream( unsigned char* _data, const unsigned int lengthInBytes, bool _copyData )
78 {
79 	numberOfBitsUsed = lengthInBytes << 3;
80 	readOffset = 0;
81 	copyData = _copyData;
82 	numberOfBitsAllocated = lengthInBytes << 3;
83 
84 	if ( copyData )
85 	{
86 		if ( lengthInBytes > 0 )
87 		{
88 			if (lengthInBytes < BITSTREAM_STACK_ALLOCATION_SIZE)
89 			{
90 				data = ( unsigned char* ) stackData;
91 				numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE << 3;
92 			}
93 			else
94 			{
95 				data = ( unsigned char* ) rakMalloc_Ex( (size_t) lengthInBytes, __FILE__, __LINE__ );
96 			}
97 #ifdef _DEBUG
98 			RakAssert( data );
99 #endif
100 			memcpy( data, _data, (size_t) lengthInBytes );
101 		}
102 		else
103 			data = 0;
104 	}
105 	else
106 		data = ( unsigned char* ) _data;
107 }
108 
109 // Use this if you pass a pointer copy to the constructor (_copyData==false) and want to overallocate to prevent reallocation
SetNumberOfBitsAllocated(const BitSize_t lengthInBits)110 void BitStream::SetNumberOfBitsAllocated( const BitSize_t lengthInBits )
111 {
112 #ifdef _DEBUG
113 	RakAssert( lengthInBits >= ( BitSize_t ) numberOfBitsAllocated );
114 #endif
115 	numberOfBitsAllocated = lengthInBits;
116 }
117 
~BitStream()118 BitStream::~BitStream()
119 {
120 	if ( copyData && numberOfBitsAllocated > (BITSTREAM_STACK_ALLOCATION_SIZE << 3))
121 		rakFree_Ex( data , __FILE__, __LINE__ );  // Use realloc and free so we are more efficient than delete and new for resizing
122 }
123 
Reset(void)124 void BitStream::Reset( void )
125 {
126 	// Note:  Do NOT reallocate memory because BitStream is used
127 	// in places to serialize/deserialize a buffer. Reallocation
128 	// is a dangerous operation (may result in leaks).
129 
130 	if ( numberOfBitsUsed > 0 )
131 	{
132 		//  memset(data, 0, BITS_TO_BYTES(numberOfBitsUsed));
133 	}
134 
135 	// Don't free memory here for speed efficiency
136 	//free(data);  // Use realloc and free so we are more efficient than delete and new for resizing
137 	numberOfBitsUsed = 0;
138 
139 	//numberOfBitsAllocated=8;
140 	readOffset = 0;
141 
142 	//data=(unsigned char*)rakMalloc_Ex(1, __FILE__, __LINE__);
143 	// if (numberOfBitsAllocated>0)
144 	//  memset(data, 0, BITS_TO_BYTES(numberOfBitsAllocated));
145 }
146 
147 // Write an array or casted stream
Write(const char * input,const unsigned int numberOfBytes)148 void BitStream::Write( const char* input, const unsigned int numberOfBytes )
149 {
150 	if (numberOfBytes==0)
151 		return;
152 
153 	// Optimization:
154 	if ((numberOfBitsUsed & 7) == 0)
155 	{
156 		AddBitsAndReallocate( BYTES_TO_BITS(numberOfBytes) );
157 		memcpy(data+BITS_TO_BYTES(numberOfBitsUsed), input, (size_t) numberOfBytes);
158 		numberOfBitsUsed+=BYTES_TO_BITS(numberOfBytes);
159 	}
160 	else
161 	{
162 		WriteBits( ( unsigned char* ) input, numberOfBytes * 8, true );
163 	}
164 
165 }
Write(BitStream * bitStream)166 void BitStream::Write( BitStream *bitStream)
167 {
168 	Write(bitStream, bitStream->GetNumberOfBitsUsed());
169 }
Write(BitStream * bitStream,BitSize_t numberOfBits)170 void BitStream::Write( BitStream *bitStream, BitSize_t numberOfBits )
171 {
172 	AddBitsAndReallocate( numberOfBits );
173 	BitSize_t numberOfBitsMod8;
174 
175 	if ((bitStream->GetReadOffset()&7)==0 && (numberOfBitsUsed&7)==0)
176 	{
177 		int readOffsetBytes=bitStream->GetReadOffset()/8;
178 		int numBytes=numberOfBits/8;
179 		memcpy(data + (numberOfBitsUsed >> 3), bitStream->GetData()+readOffsetBytes, numBytes);
180 		numberOfBits-=BYTES_TO_BITS(numBytes);
181 		bitStream->SetReadOffset(BYTES_TO_BITS(numBytes+readOffsetBytes));
182 		numberOfBitsUsed+=BYTES_TO_BITS(numBytes);
183 	}
184 
185 	while (numberOfBits-->0 && bitStream->readOffset + 1 <= bitStream->numberOfBitsUsed)
186 	{
187 		numberOfBitsMod8 = numberOfBitsUsed & 7;
188 		if ( numberOfBitsMod8 == 0 )
189 		{
190 			// New byte
191 			if (bitStream->data[ bitStream->readOffset >> 3 ] & ( 0x80 >> ( bitStream->readOffset & 7 ) ) )
192 			{
193 				// Write 1
194 				data[ numberOfBitsUsed >> 3 ] = 0x80;
195 			}
196 			else
197 			{
198 				// Write 0
199 				data[ numberOfBitsUsed >> 3 ] = 0;
200 			}
201 
202 		}
203 		else
204 		{
205 			// Existing byte
206 			if (bitStream->data[ bitStream->readOffset >> 3 ] & ( 0x80 >> ( bitStream->readOffset & 7 ) ) )
207 				data[ numberOfBitsUsed >> 3 ] |= 0x80 >> ( numberOfBitsMod8 ); // Set the bit to 1
208 			// else 0, do nothing
209 		}
210 
211 		bitStream->readOffset++;
212 		numberOfBitsUsed++;
213 	}
214 }
Write(BitStream & bitStream,BitSize_t numberOfBits)215 void BitStream::Write( BitStream &bitStream, BitSize_t numberOfBits )
216 {
217 	Write(&bitStream, numberOfBits);
218 }
Write(BitStream & bitStream)219 void BitStream::Write( BitStream &bitStream )
220 {
221 	Write(&bitStream);
222 }
Read(BitStream * bitStream,BitSize_t numberOfBits)223 bool BitStream::Read( BitStream *bitStream, BitSize_t numberOfBits )
224 {
225 	if (GetNumberOfUnreadBits() < numberOfBits)
226 		return false;
227 	bitStream->Write(this, numberOfBits);
228 	return true;
229 }
Read(BitStream * bitStream)230 bool BitStream::Read( BitStream *bitStream )
231 {
232 	bitStream->Write(this);
233 	return true;
234 }
Read(BitStream & bitStream,BitSize_t numberOfBits)235 bool BitStream::Read( BitStream &bitStream, BitSize_t numberOfBits )
236 {
237 	if (GetNumberOfUnreadBits() < numberOfBits)
238 		return false;
239 	bitStream.Write(this, numberOfBits);
240 	return true;
241 }
Read(BitStream & bitStream)242 bool BitStream::Read( BitStream &bitStream )
243 {
244 	bitStream.Write(this);
245 	return true;
246 }
247 
248 // Read an array or casted stream
Read(char * output,const unsigned int numberOfBytes)249 bool BitStream::Read( char* output, const unsigned int numberOfBytes )
250 {
251 	// Optimization:
252 	if ((readOffset & 7) == 0)
253 	{
254 		if ( readOffset + ( numberOfBytes << 3 ) > numberOfBitsUsed )
255 			return false;
256 
257 		// Write the data
258 		memcpy( output, data + ( readOffset >> 3 ), (size_t) numberOfBytes );
259 
260 		readOffset += numberOfBytes << 3;
261 		return true;
262 	}
263 	else
264 	{
265 		return ReadBits( ( unsigned char* ) output, numberOfBytes * 8 );
266 	}
267 }
268 
269 // Sets the read pointer back to the beginning of your data.
ResetReadPointer(void)270 void BitStream::ResetReadPointer( void )
271 {
272 	readOffset = 0;
273 }
274 
275 // Sets the write pointer back to the beginning of your data.
ResetWritePointer(void)276 void BitStream::ResetWritePointer( void )
277 {
278 	numberOfBitsUsed = 0;
279 }
280 
281 // Write a 0
Write0(void)282 void BitStream::Write0( void )
283 {
284 	AddBitsAndReallocate( 1 );
285 
286 	// New bytes need to be zeroed
287 	if ( ( numberOfBitsUsed & 7 ) == 0 )
288 		data[ numberOfBitsUsed >> 3 ] = 0;
289 
290 	numberOfBitsUsed++;
291 }
292 
293 // Write a 1
Write1(void)294 void BitStream::Write1( void )
295 {
296 	AddBitsAndReallocate( 1 );
297 
298 	BitSize_t numberOfBitsMod8 = numberOfBitsUsed & 7;
299 
300 	if ( numberOfBitsMod8 == 0 )
301 		data[ numberOfBitsUsed >> 3 ] = 0x80;
302 	else
303 		data[ numberOfBitsUsed >> 3 ] |= 0x80 >> ( numberOfBitsMod8 ); // Set the bit to 1
304 
305 	numberOfBitsUsed++;
306 }
307 
308 // Returns true if the next data read is a 1, false if it is a 0
ReadBit(void)309 bool BitStream::ReadBit( void )
310 {
311 	bool result = ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset & 7 ) ) ) !=0;
312 	readOffset++;
313 	return result;
314 }
315 
316 // Align the bitstream to the byte boundary and then write the specified number of bits.
317 // This is faster than WriteBits but wastes the bits to do the alignment and requires you to call
318 // SetReadToByteAlignment at the corresponding read position
WriteAlignedBytes(const unsigned char * input,const unsigned int numberOfBytesToWrite)319 void BitStream::WriteAlignedBytes( const unsigned char* input, const unsigned int numberOfBytesToWrite )
320 {
321 	AlignWriteToByteBoundary();
322 	Write((const char*) input, numberOfBytesToWrite);
323 }
EndianSwapBytes(int byteOffset,int length)324 void BitStream::EndianSwapBytes( int byteOffset, int length )
325 {
326 	if (DoEndianSwap())
327 	{
328 		ReverseBytesInPlace(data+byteOffset, length);
329 	}
330 }
331 /// Aligns the bitstream, writes inputLength, and writes input. Won't write beyond maxBytesToWrite
WriteAlignedBytesSafe(const char * input,const unsigned int inputLength,const unsigned int maxBytesToWrite)332 void BitStream::WriteAlignedBytesSafe( const char *input, const unsigned int inputLength, const unsigned int maxBytesToWrite )
333 {
334 	if (input==0 || inputLength==0)
335 	{
336 		WriteCompressed((unsigned int)0);
337 		return;
338 	}
339 	WriteCompressed(inputLength);
340 	WriteAlignedBytes((const unsigned char*) input, inputLength < maxBytesToWrite ? inputLength : maxBytesToWrite);
341 }
342 
343 // Read bits, starting at the next aligned bits. Note that the modulus 8 starting offset of the
344 // sequence must be the same as was used with WriteBits. This will be a problem with packet coalescence
345 // unless you byte align the coalesced packets.
ReadAlignedBytes(unsigned char * output,const unsigned int numberOfBytesToRead)346 bool BitStream::ReadAlignedBytes( unsigned char* output, const unsigned int numberOfBytesToRead )
347 {
348 #ifdef _DEBUG
349 	RakAssert( numberOfBytesToRead > 0 );
350 #endif
351 
352 	if ( numberOfBytesToRead <= 0 )
353 		return false;
354 
355 	// Byte align
356 	AlignReadToByteBoundary();
357 
358 	if ( readOffset + ( numberOfBytesToRead << 3 ) > numberOfBitsUsed )
359 		return false;
360 
361 	// Write the data
362 	memcpy( output, data + ( readOffset >> 3 ), (size_t) numberOfBytesToRead );
363 
364 	readOffset += numberOfBytesToRead << 3;
365 
366 	return true;
367 }
ReadAlignedBytesSafe(char * input,int & inputLength,const int maxBytesToRead)368 bool BitStream::ReadAlignedBytesSafe( char *input, int &inputLength, const int maxBytesToRead )
369 {
370 	return ReadAlignedBytesSafe(input,(unsigned int&) inputLength,(unsigned int)maxBytesToRead);
371 }
ReadAlignedBytesSafe(char * input,unsigned int & inputLength,const unsigned int maxBytesToRead)372 bool BitStream::ReadAlignedBytesSafe( char *input, unsigned int &inputLength, const unsigned int maxBytesToRead )
373 {
374 	if (ReadCompressed(inputLength)==false)
375 		return false;
376 	if (inputLength > maxBytesToRead)
377 		inputLength=maxBytesToRead;
378 	if (inputLength==0)
379 		return true;
380 	return ReadAlignedBytes((unsigned char*) input, inputLength);
381 }
ReadAlignedBytesSafeAlloc(char ** input,int & inputLength,const unsigned int maxBytesToRead)382 bool BitStream::ReadAlignedBytesSafeAlloc( char **input, int &inputLength, const unsigned int maxBytesToRead )
383 {
384 	return ReadAlignedBytesSafeAlloc(input,(unsigned int&) inputLength, maxBytesToRead);
385 }
ReadAlignedBytesSafeAlloc(char ** input,unsigned int & inputLength,const unsigned int maxBytesToRead)386 bool BitStream::ReadAlignedBytesSafeAlloc( char **input, unsigned int &inputLength, const unsigned int maxBytesToRead )
387 {
388 	rakFree_Ex(*input, __FILE__, __LINE__ );
389 	*input=0;
390 	if (ReadCompressed(inputLength)==false)
391 		return false;
392 	if (inputLength > maxBytesToRead)
393 		inputLength=maxBytesToRead;
394 	if (inputLength==0)
395 		return true;
396 	*input = (char*) rakMalloc_Ex( (size_t) inputLength, __FILE__, __LINE__ );
397 	return ReadAlignedBytes((unsigned char*) *input, inputLength);
398 }
399 
400 // Write numberToWrite bits from the input source
WriteBits(const unsigned char * input,BitSize_t numberOfBitsToWrite,const bool rightAlignedBits)401 void BitStream::WriteBits( const unsigned char* input, BitSize_t numberOfBitsToWrite, const bool rightAlignedBits )
402 {
403 	//	if (numberOfBitsToWrite<=0)
404 	//		return;
405 
406 	AddBitsAndReallocate( numberOfBitsToWrite );
407 
408 	const BitSize_t numberOfBitsUsedMod8 = numberOfBitsUsed & 7;
409 
410 	// If currently aligned and numberOfBits is a multiple of 8, just memcpy for speed
411 	if (numberOfBitsUsedMod8==0 && (numberOfBitsToWrite&7)==0)
412 	{
413 		memcpy( data + ( numberOfBitsUsed >> 3 ), input, numberOfBitsToWrite>>3);
414 		numberOfBitsUsed+=numberOfBitsToWrite;
415 		return;
416 	}
417 
418 	unsigned char dataByte;
419 	const unsigned char* inputPtr=input;
420 
421 	// Faster to put the while at the top surprisingly enough
422 	while ( numberOfBitsToWrite > 0 )
423 		//do
424 	{
425 		dataByte = *( inputPtr++ );
426 
427 		if ( numberOfBitsToWrite < 8 && rightAlignedBits )   // rightAlignedBits means in the case of a partial byte, the bits are aligned from the right (bit 0) rather than the left (as in the normal internal representation)
428 			dataByte <<= 8 - numberOfBitsToWrite;  // shift left to get the bits on the left, as in our internal representation
429 
430 		// Writing to a new byte each time
431 		if ( numberOfBitsUsedMod8 == 0 )
432 			* ( data + ( numberOfBitsUsed >> 3 ) ) = dataByte;
433 		else
434 		{
435 			// Copy over the new data.
436 			*( data + ( numberOfBitsUsed >> 3 ) ) |= dataByte >> ( numberOfBitsUsedMod8 ); // First half
437 
438 			if ( 8 - ( numberOfBitsUsedMod8 ) < 8 && 8 - ( numberOfBitsUsedMod8 ) < numberOfBitsToWrite )   // If we didn't write it all out in the first half (8 - (numberOfBitsUsed%8) is the number we wrote in the first half)
439 			{
440 				*( data + ( numberOfBitsUsed >> 3 ) + 1 ) = (unsigned char) ( dataByte << ( 8 - ( numberOfBitsUsedMod8 ) ) ); // Second half (overlaps byte boundary)
441 			}
442 		}
443 
444 		if ( numberOfBitsToWrite >= 8 )
445 		{
446 			numberOfBitsUsed += 8;
447 			numberOfBitsToWrite -= 8;
448 		}
449 		else
450 		{
451 			numberOfBitsUsed += numberOfBitsToWrite;
452 			numberOfBitsToWrite=0;
453 		}
454 	}
455 	// } while(numberOfBitsToWrite>0);
456 }
457 
458 // Set the stream to some initial data.  For internal use
SetData(unsigned char * input)459 void BitStream::SetData( unsigned char *input )
460 {
461 	data=input;
462 	copyData=false;
463 }
464 
465 // Assume the input source points to a native type, compress and write it
WriteCompressed(const unsigned char * input,const unsigned int size,const bool unsignedData)466 void BitStream::WriteCompressed( const unsigned char* input,
467 								const unsigned int size, const bool unsignedData )
468 {
469 	BitSize_t currentByte = ( size >> 3 ) - 1; // PCs
470 
471 	unsigned char byteMatch;
472 
473 	if ( unsignedData )
474 	{
475 		byteMatch = 0;
476 	}
477 
478 	else
479 	{
480 		byteMatch = 0xFF;
481 	}
482 
483 	// Write upper bytes with a single 1
484 	// From high byte to low byte, if high byte is a byteMatch then write a 1 bit. Otherwise write a 0 bit and then write the remaining bytes
485 	while ( currentByte > 0 )
486 	{
487 		if ( input[ currentByte ] == byteMatch )   // If high byte is byteMatch (0 of 0xff) then it would have the same value shifted
488 		{
489 			bool b = true;
490 			Write( b );
491 		}
492 		else
493 		{
494 			// Write the remainder of the data after writing 0
495 			bool b = false;
496 			Write( b );
497 
498 			WriteBits( input, ( currentByte + 1 ) << 3, true );
499 			//  currentByte--;
500 
501 
502 			return ;
503 		}
504 
505 		currentByte--;
506 	}
507 
508 	// If the upper half of the last byte is a 0 (positive) or 16 (negative) then write a 1 and the remaining 4 bits.  Otherwise write a 0 and the 8 bites.
509 	if ( ( unsignedData && ( ( *( input + currentByte ) ) & 0xF0 ) == 0x00 ) ||
510 		( unsignedData == false && ( ( *( input + currentByte ) ) & 0xF0 ) == 0xF0 ) )
511 	{
512 		bool b = true;
513 		Write( b );
514 		WriteBits( input + currentByte, 4, true );
515 	}
516 
517 	else
518 	{
519 		bool b = false;
520 		Write( b );
521 		WriteBits( input + currentByte, 8, true );
522 	}
523 }
524 
525 // Read numberOfBitsToRead bits to the output source
526 // alignBitsToRight should be set to true to convert internal bitstream data to userdata
527 // It should be false if you used WriteBits with rightAlignedBits false
ReadBits(unsigned char * output,BitSize_t numberOfBitsToRead,const bool alignBitsToRight)528 bool BitStream::ReadBits( unsigned char *output, BitSize_t numberOfBitsToRead, const bool alignBitsToRight )
529 {
530 #ifdef _DEBUG
531 	//	RakAssert( numberOfBitsToRead > 0 );
532 #endif
533 	if (numberOfBitsToRead<=0)
534 		return false;
535 
536 	if ( readOffset + numberOfBitsToRead > numberOfBitsUsed )
537 		return false;
538 
539 
540 	const BitSize_t readOffsetMod8 = readOffset & 7;
541 
542 	// If currently aligned and numberOfBits is a multiple of 8, just memcpy for speed
543 	if (readOffsetMod8==0 && (numberOfBitsToRead&7)==0)
544 	{
545 		memcpy( output, data + ( readOffset >> 3 ), numberOfBitsToRead>>3);
546 		readOffset+=numberOfBitsToRead;
547 		return true;
548 	}
549 
550 
551 
552 	BitSize_t offset = 0;
553 
554 	memset( output, 0, (size_t) BITS_TO_BYTES( numberOfBitsToRead ) );
555 
556 	while ( numberOfBitsToRead > 0 )
557 	{
558 		*( output + offset ) |= *( data + ( readOffset >> 3 ) ) << ( readOffsetMod8 ); // First half
559 
560 		if ( readOffsetMod8 > 0 && numberOfBitsToRead > 8 - ( readOffsetMod8 ) )   // If we have a second half, we didn't read enough bytes in the first half
561 			*( output + offset ) |= *( data + ( readOffset >> 3 ) + 1 ) >> ( 8 - ( readOffsetMod8 ) ); // Second half (overlaps byte boundary)
562 
563 		if (numberOfBitsToRead>=8)
564 		{
565 			numberOfBitsToRead -= 8;
566 			readOffset += 8;
567 			offset++;
568 		}
569 		else
570 		{
571 			int neg = (int) numberOfBitsToRead - 8;
572 
573 			if ( neg < 0 )   // Reading a partial byte for the last byte, shift right so the data is aligned on the right
574 			{
575 
576 				if ( alignBitsToRight )
577 					* ( output + offset ) >>= -neg;
578 
579 				readOffset += 8 + neg;
580 			}
581 			else
582 				readOffset += 8;
583 
584 			offset++;
585 
586 			numberOfBitsToRead=0;
587 		}
588 	}
589 
590 	return true;
591 }
592 
593 // Assume the input source points to a compressed native type. Decompress and read it
ReadCompressed(unsigned char * output,const unsigned int size,const bool unsignedData)594 bool BitStream::ReadCompressed( unsigned char* output,
595 							   const unsigned int size, const bool unsignedData )
596 {
597 	unsigned int currentByte = ( size >> 3 ) - 1;
598 
599 
600 	unsigned char byteMatch, halfByteMatch;
601 
602 	if ( unsignedData )
603 	{
604 		byteMatch = 0;
605 		halfByteMatch = 0;
606 	}
607 
608 	else
609 	{
610 		byteMatch = 0xFF;
611 		halfByteMatch = 0xF0;
612 	}
613 
614 	// Upper bytes are specified with a single 1 if they match byteMatch
615 	// From high byte to low byte, if high byte is a byteMatch then write a 1 bit. Otherwise write a 0 bit and then write the remaining bytes
616 	while ( currentByte > 0 )
617 	{
618 		// If we read a 1 then the data is byteMatch.
619 
620 		bool b;
621 
622 		if ( Read( b ) == false )
623 			return false;
624 
625 		if ( b )   // Check that bit
626 		{
627 			output[ currentByte ] = byteMatch;
628 			currentByte--;
629 		}
630 		else
631 		{
632 			// Read the rest of the bytes
633 
634 			if ( ReadBits( output, ( currentByte + 1 ) << 3 ) == false )
635 				return false;
636 
637 			return true;
638 		}
639 	}
640 
641 	// All but the first bytes are byteMatch.  If the upper half of the last byte is a 0 (positive) or 16 (negative) then what we read will be a 1 and the remaining 4 bits.
642 	// Otherwise we read a 0 and the 8 bytes
643 	//RakAssert(readOffset+1 <=numberOfBitsUsed); // If this assert is hit the stream wasn't long enough to read from
644 	if ( readOffset + 1 > numberOfBitsUsed )
645 		return false;
646 
647 	bool b;
648 
649 	if ( Read( b ) == false )
650 		return false;
651 
652 	if ( b )   // Check that bit
653 	{
654 
655 		if ( ReadBits( output + currentByte, 4 ) == false )
656 			return false;
657 
658 		output[ currentByte ] |= halfByteMatch; // We have to set the high 4 bits since these are set to 0 by ReadBits
659 	}
660 	else
661 	{
662 		if ( ReadBits( output + currentByte, 8 ) == false )
663 			return false;
664 	}
665 
666 	return true;
667 }
668 
669 // Reallocates (if necessary) in preparation of writing numberOfBitsToWrite
AddBitsAndReallocate(const BitSize_t numberOfBitsToWrite)670 void BitStream::AddBitsAndReallocate( const BitSize_t numberOfBitsToWrite )
671 {
672 	BitSize_t newNumberOfBitsAllocated = numberOfBitsToWrite + numberOfBitsUsed;
673 
674 	if ( numberOfBitsToWrite + numberOfBitsUsed > 0 && ( ( numberOfBitsAllocated - 1 ) >> 3 ) < ( ( newNumberOfBitsAllocated - 1 ) >> 3 ) )   // If we need to allocate 1 or more new bytes
675 	{
676 #ifdef _DEBUG
677 		// If this assert hits then we need to specify true for the third parameter in the constructor
678 		// It needs to reallocate to hold all the data and can't do it unless we allocated to begin with
679 		// Often hits if you call Write or Serialize on a read-only bitstream
680 		RakAssert( copyData == true );
681 #endif
682 
683 		// Less memory efficient but saves on news and deletes
684 		/// Cap to 1 meg buffer to save on huge allocations
685 		newNumberOfBitsAllocated = ( numberOfBitsToWrite + numberOfBitsUsed ) * 2;
686 		if (newNumberOfBitsAllocated - ( numberOfBitsToWrite + numberOfBitsUsed ) > 1048576 )
687 			newNumberOfBitsAllocated = numberOfBitsToWrite + numberOfBitsUsed + 1048576;
688 
689 		//		BitSize_t newByteOffset = BITS_TO_BYTES( numberOfBitsAllocated );
690 		// Use realloc and free so we are more efficient than delete and new for resizing
691 		BitSize_t amountToAllocate = BITS_TO_BYTES( newNumberOfBitsAllocated );
692 		if (data==(unsigned char*)stackData)
693 		{
694 			if (amountToAllocate > BITSTREAM_STACK_ALLOCATION_SIZE)
695 			{
696 				data = ( unsigned char* ) rakMalloc_Ex( (size_t) amountToAllocate, __FILE__, __LINE__ );
697 
698 				// need to copy the stack data over to our new memory area too
699 				memcpy ((void *)data, (void *)stackData, (size_t) BITS_TO_BYTES( numberOfBitsAllocated ));
700 			}
701 		}
702 		else
703 		{
704 			data = ( unsigned char* ) rakRealloc_Ex( data, (size_t) amountToAllocate, __FILE__, __LINE__ );
705 		}
706 
707 #ifdef _DEBUG
708 		RakAssert( data ); // Make sure realloc succeeded
709 #endif
710 		//  memset(data+newByteOffset, 0,  ((newNumberOfBitsAllocated-1)>>3) - ((numberOfBitsAllocated-1)>>3)); // Set the new data block to 0
711 	}
712 
713 	if ( newNumberOfBitsAllocated > numberOfBitsAllocated )
714 		numberOfBitsAllocated = newNumberOfBitsAllocated;
715 }
GetNumberOfBitsAllocated(void) const716 BitSize_t BitStream::GetNumberOfBitsAllocated(void) const
717 {
718 	return numberOfBitsAllocated;
719 }
PadWithZeroToByteLength(unsigned int bytes)720 void BitStream::PadWithZeroToByteLength( unsigned int bytes )
721 {
722 	if (GetNumberOfBytesUsed() < bytes)
723 	{
724 		AlignWriteToByteBoundary();
725 		unsigned int numToWrite = bytes - GetNumberOfBytesUsed();
726 		AddBitsAndReallocate( BYTES_TO_BITS(numToWrite) );
727 		memset(data+BITS_TO_BYTES(numberOfBitsUsed), 0, (size_t) numToWrite);
728 		numberOfBitsUsed+=BYTES_TO_BITS(numToWrite);
729 	}
730 }
731 
732 // Should hit if reads didn't match writes
AssertStreamEmpty(void)733 void BitStream::AssertStreamEmpty( void )
734 {
735 	RakAssert( readOffset == numberOfBitsUsed );
736 }
PrintBits(char * out) const737 void BitStream::PrintBits( char *out ) const
738 {
739 	if ( numberOfBitsUsed <= 0 )
740 	{
741 		strcpy(out, "No bits\n" );
742 		return;
743 	}
744 
745 	unsigned int strIndex=0;
746 	for ( BitSize_t counter = 0; counter < BITS_TO_BYTES( numberOfBitsUsed ); counter++ )
747 	{
748 		BitSize_t stop;
749 
750 		if ( counter == ( numberOfBitsUsed - 1 ) >> 3 )
751 			stop = 8 - ( ( ( numberOfBitsUsed - 1 ) & 7 ) + 1 );
752 		else
753 			stop = 0;
754 
755 		for ( BitSize_t counter2 = 7; counter2 >= stop; counter2-- )
756 		{
757 			if ( ( data[ counter ] >> counter2 ) & 1 )
758 				out[strIndex++]='1';
759 			else
760 				out[strIndex++]='0';
761 
762 			if (counter2==0)
763 				break;
764 		}
765 
766 		out[strIndex++]=' ';
767 	}
768 
769 	out[strIndex++]='\n';
770 
771 	out[strIndex++]=0;
772 }
PrintBits(void) const773 void BitStream::PrintBits( void ) const
774 {
775 	char out[2048];
776 	PrintBits(out);
777 	RAKNET_DEBUG_PRINTF(out);
778 }
PrintHex(char * out) const779 void BitStream::PrintHex( char *out ) const
780 {
781 	BitSize_t i;
782 	for ( i=0; i < GetNumberOfBytesUsed(); i++)
783 	{
784 		sprintf(out+i*3, "%02x ", data[i]);
785 	}
786 }
PrintHex(void) const787 void BitStream::PrintHex( void ) const
788 {
789 	char out[2048];
790 	PrintHex(out);
791 	RAKNET_DEBUG_PRINTF(out);
792 }
793 
794 // Exposes the data for you to look at, like PrintBits does.
795 // Data will point to the stream.  Returns the length in bits of the stream.
CopyData(unsigned char ** _data) const796 BitSize_t BitStream::CopyData( unsigned char** _data ) const
797 {
798 #ifdef _DEBUG
799 	RakAssert( numberOfBitsUsed > 0 );
800 #endif
801 
802 	*_data = (unsigned char*) rakMalloc_Ex( (size_t) BITS_TO_BYTES( numberOfBitsUsed ), __FILE__, __LINE__ );
803 	memcpy( *_data, data, sizeof(unsigned char) * (size_t) ( BITS_TO_BYTES( numberOfBitsUsed ) ) );
804 	return numberOfBitsUsed;
805 }
806 
807 // Ignore data we don't intend to read
IgnoreBits(const BitSize_t numberOfBits)808 void BitStream::IgnoreBits( const BitSize_t numberOfBits )
809 {
810 	readOffset += numberOfBits;
811 }
812 
IgnoreBytes(const unsigned int numberOfBytes)813 void BitStream::IgnoreBytes( const unsigned int numberOfBytes )
814 {
815 	IgnoreBits(BYTES_TO_BITS(numberOfBytes));
816 }
817 
818 // Move the write pointer to a position on the array.  Dangerous if you don't know what you are doing!
819 // Doesn't work with non-aligned data!
SetWriteOffset(const BitSize_t offset)820 void BitStream::SetWriteOffset( const BitSize_t offset )
821 {
822 	numberOfBitsUsed = offset;
823 }
824 
825 /*
826 BitSize_t BitStream::GetWriteOffset( void ) const
827 {
828 return numberOfBitsUsed;
829 }
830 
831 // Returns the length in bits of the stream
832 BitSize_t BitStream::GetNumberOfBitsUsed( void ) const
833 {
834 return GetWriteOffset();
835 }
836 
837 // Returns the length in bytes of the stream
838 BitSize_t BitStream::GetNumberOfBytesUsed( void ) const
839 {
840 return BITS_TO_BYTES( numberOfBitsUsed );
841 }
842 
843 // Returns the number of bits into the stream that we have read
844 BitSize_t BitStream::GetReadOffset( void ) const
845 {
846 return readOffset;
847 }
848 
849 
850 // Sets the read bit index
851 void BitStream::SetReadOffset( const BitSize_t newReadOffset )
852 {
853 readOffset=newReadOffset;
854 }
855 
856 // Returns the number of bits left in the stream that haven't been read
857 BitSize_t BitStream::GetNumberOfUnreadBits( void ) const
858 {
859 return numberOfBitsUsed - readOffset;
860 }
861 // Exposes the internal data
862 unsigned char* BitStream::GetData( void ) const
863 {
864 return data;
865 }
866 
867 */
868 // If we used the constructor version with copy data off, this makes sure it is set to on and the data pointed to is copied.
AssertCopyData(void)869 void BitStream::AssertCopyData( void )
870 {
871 	if ( copyData == false )
872 	{
873 		copyData = true;
874 
875 		if ( numberOfBitsAllocated > 0 )
876 		{
877 			unsigned char * newdata = ( unsigned char* ) rakMalloc_Ex( (size_t) BITS_TO_BYTES( numberOfBitsAllocated ), __FILE__, __LINE__ );
878 #ifdef _DEBUG
879 
880 			RakAssert( data );
881 #endif
882 
883 			memcpy( newdata, data, (size_t) BITS_TO_BYTES( numberOfBitsAllocated ) );
884 			data = newdata;
885 		}
886 
887 		else
888 			data = 0;
889 	}
890 }
IsNetworkOrderInternal(void)891 bool BitStream::IsNetworkOrderInternal(void)
892 {
893 
894 
895 
896 	static const bool isNetworkOrder=(htonl(12345) == 12345);
897 	return isNetworkOrder;
898 
899 }
ReverseBytes(unsigned char * input,unsigned char * output,const unsigned int length)900 void BitStream::ReverseBytes(unsigned char *input, unsigned char *output, const unsigned int length)
901 {
902 	for (BitSize_t i=0; i < length; i++)
903 		output[i]=input[length-i-1];
904 }
ReverseBytesInPlace(unsigned char * data,const unsigned int length)905 void BitStream::ReverseBytesInPlace(unsigned char *data,const unsigned int length)
906 {
907 	unsigned char temp;
908 	BitSize_t i;
909 	for (i=0; i < (length>>1); i++)
910 	{
911 		temp = data[i];
912 		data[i]=data[length-i-1];
913 		data[length-i-1]=temp;
914 	}
915 }
916 
WriteAlignedVar8(const char * input)917 void BitStream::WriteAlignedVar8(const char *input)
918 {
919 	RakAssert((numberOfBitsUsed&7)==0);
920 	AddBitsAndReallocate(1*8);
921 	data[( numberOfBitsUsed >> 3 ) + 0] = input[0];
922 	numberOfBitsUsed+=1*8;
923 }
ReadAlignedVar8(char * output)924 bool BitStream::ReadAlignedVar8(char *output)
925 {
926 	RakAssert((readOffset&7)==0);
927 	if ( readOffset + 1*8 > numberOfBitsUsed )
928 		return false;
929 
930 	output[0] = data[( readOffset >> 3 ) + 0];
931 	readOffset+=1*8;
932 	return true;
933 }
WriteAlignedVar16(const char * input)934 void BitStream::WriteAlignedVar16(const char *input)
935 {
936 	RakAssert((numberOfBitsUsed&7)==0);
937 	AddBitsAndReallocate(2*8);
938 #ifndef __BITSTREAM_NATIVE_END
939 	if (DoEndianSwap())
940 	{
941 		data[( numberOfBitsUsed >> 3 ) + 0] = input[1];
942 		data[( numberOfBitsUsed >> 3 ) + 1] = input[0];
943 	}
944 	else
945 #endif
946 	{
947 		data[( numberOfBitsUsed >> 3 ) + 0] = input[0];
948 		data[( numberOfBitsUsed >> 3 ) + 1] = input[1];
949 	}
950 
951 	numberOfBitsUsed+=2*8;
952 }
ReadAlignedVar16(char * output)953 bool BitStream::ReadAlignedVar16(char *output)
954 {
955 	RakAssert((readOffset&7)==0);
956 	if ( readOffset + 2*8 > numberOfBitsUsed )
957 		return false;
958 #ifndef __BITSTREAM_NATIVE_END
959 	if (DoEndianSwap())
960 	{
961 		output[0] = data[( readOffset >> 3 ) + 1];
962 		output[1] = data[( readOffset >> 3 ) + 0];
963 	}
964 	else
965 #endif
966 	{
967 		output[0] = data[( readOffset >> 3 ) + 0];
968 		output[1] = data[( readOffset >> 3 ) + 1];
969 	}
970 
971 	readOffset+=2*8;
972 	return true;
973 }
WriteAlignedVar32(const char * input)974 void BitStream::WriteAlignedVar32(const char *input)
975 {
976 	RakAssert((numberOfBitsUsed&7)==0);
977 	AddBitsAndReallocate(4*8);
978 #ifndef __BITSTREAM_NATIVE_END
979 	if (DoEndianSwap())
980 	{
981 		data[( numberOfBitsUsed >> 3 ) + 0] = input[3];
982 		data[( numberOfBitsUsed >> 3 ) + 1] = input[2];
983 		data[( numberOfBitsUsed >> 3 ) + 2] = input[1];
984 		data[( numberOfBitsUsed >> 3 ) + 3] = input[0];
985 	}
986 	else
987 #endif
988 	{
989 		data[( numberOfBitsUsed >> 3 ) + 0] = input[0];
990 		data[( numberOfBitsUsed >> 3 ) + 1] = input[1];
991 		data[( numberOfBitsUsed >> 3 ) + 2] = input[2];
992 		data[( numberOfBitsUsed >> 3 ) + 3] = input[3];
993 	}
994 
995 	numberOfBitsUsed+=4*8;
996 }
ReadAlignedVar32(char * output)997 bool BitStream::ReadAlignedVar32(char *output)
998 {
999 	RakAssert((readOffset&7)==0);
1000 	if ( readOffset + 4*8 > numberOfBitsUsed )
1001 		return false;
1002 #ifndef __BITSTREAM_NATIVE_END
1003 	if (DoEndianSwap())
1004 	{
1005 		output[0] = data[( readOffset >> 3 ) + 3];
1006 		output[1] = data[( readOffset >> 3 ) + 2];
1007 		output[2] = data[( readOffset >> 3 ) + 1];
1008 		output[3] = data[( readOffset >> 3 ) + 0];
1009 	}
1010 	else
1011 #endif
1012 	{
1013 		output[0] = data[( readOffset >> 3 ) + 0];
1014 		output[1] = data[( readOffset >> 3 ) + 1];
1015 		output[2] = data[( readOffset >> 3 ) + 2];
1016 		output[3] = data[( readOffset >> 3 ) + 3];
1017 	}
1018 
1019 	readOffset+=4*8;
1020 	return true;
1021 }
ReadFloat16(float & f,float floatMin,float floatMax)1022 bool BitStream::ReadFloat16( float &f, float floatMin, float floatMax )
1023 {
1024 	unsigned short percentile;
1025 	if (Read(percentile))
1026 	{
1027 		RakAssert(floatMax>floatMin);
1028 		f = floatMin + ((float) percentile / 65535.0f) * (floatMax-floatMin);
1029 		if (f<floatMin)
1030 			f=floatMin;
1031 		else if (f>floatMax)
1032 			f=floatMax;
1033 		return true;
1034 	}
1035 	return false;
1036 }
SerializeFloat16(bool writeToBitstream,float & f,float floatMin,float floatMax)1037 bool BitStream::SerializeFloat16(bool writeToBitstream, float &f, float floatMin, float floatMax)
1038 {
1039 	if (writeToBitstream)
1040 		WriteFloat16(f, floatMin, floatMax);
1041 	else
1042 		return ReadFloat16(f, floatMin, floatMax);
1043 	return true;
1044 }
WriteFloat16(float f,float floatMin,float floatMax)1045 void BitStream::WriteFloat16( float f, float floatMin, float floatMax )
1046 {
1047 	RakAssert(floatMax>floatMin);
1048 	if (f>floatMax+.001)
1049 	{
1050 		RakAssert(f<=floatMax+.001);
1051 	}
1052 	if (f<floatMin-.001)
1053 	{
1054 		RakAssert(f>=floatMin-.001);
1055 	}
1056 	float percentile=65535.0f * (f-floatMin)/(floatMax-floatMin);
1057 	if (percentile<0.0)
1058 		percentile=0.0;
1059 	if (percentile>65535.0f)
1060 		percentile=65535.0f;
1061 	Write((unsigned short)percentile);
1062 }
1063 
Write(const uint24_t & var)1064 void BitStream::Write(const uint24_t &var)
1065 {
1066 	AlignWriteToByteBoundary();
1067 	AddBitsAndReallocate(3*8);
1068 
1069 	if (IsBigEndian()==false)
1070 	{
1071 		data[( numberOfBitsUsed >> 3 ) + 0] = ((char *)&var.val)[0];
1072 		data[( numberOfBitsUsed >> 3 ) + 1] = ((char *)&var.val)[1];
1073 		data[( numberOfBitsUsed >> 3 ) + 2] = ((char *)&var.val)[2];
1074 	}
1075 	else
1076 	{
1077 		data[( numberOfBitsUsed >> 3 ) + 0] = ((char *)&var.val)[3];
1078 		data[( numberOfBitsUsed >> 3 ) + 1] = ((char *)&var.val)[2];
1079 		data[( numberOfBitsUsed >> 3 ) + 2] = ((char *)&var.val)[1];
1080 	}
1081 
1082 	numberOfBitsUsed+=3*8;
1083 }
1084 
Read(uint24_t & var)1085 bool BitStream::Read(uint24_t &var)
1086 {
1087 	AlignReadToByteBoundary();
1088 	if ( readOffset + 3*8 > numberOfBitsUsed )
1089 		return false;
1090 
1091 	if (IsBigEndian()==false)
1092 	{
1093 		((char *)&var.val)[0]=data[ (readOffset >> 3) + 0];
1094 		((char *)&var.val)[1]=data[ (readOffset >> 3) + 1];
1095 		((char *)&var.val)[2]=data[ (readOffset >> 3) + 2];
1096 		((char *)&var.val)[3]=0;
1097 	}
1098 	else
1099 	{
1100 
1101 		((char *)&var.val)[3]=data[ (readOffset >> 3) + 0];
1102 		((char *)&var.val)[2]=data[ (readOffset >> 3) + 1];
1103 		((char *)&var.val)[1]=data[ (readOffset >> 3) + 2];
1104 		((char *)&var.val)[0]=0;
1105 	}
1106 
1107 	readOffset+=3*8;
1108 	return true;
1109 }
1110 
1111 #ifdef _MSC_VER
1112 #pragma warning( pop )
1113 #endif
1114 
1115 #endif
1116