C++ Bitstream类
从raknet上剥下来的
比较适用于前后端通讯,可以对BitStream进行二次封装,方便使用.
BitStream.h:
1 #ifndef __BITSTREAM_H 2 #define __BITSTREAM_H 3 4 #ifdef _WIN32 5 #if defined (_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64 6 typedef signed __int64 int64_t; 7 typedef unsigned __int64 uint64_t; 8 #define HAS_INT64 9 #endif 10 #else 11 #include <stdint.h> 12 #define HAS_INT64 13 14 #endif 15 16 #include <string> 17 #include "share.h" 18 19 // Arbitrary size, just picking something likely to be larger than most packets 20 #define BITSTREAM_STACK_ALLOCATION_SIZE 1024*2 21 22 /** \note If you want the default network byte stream to be 23 in Network Byte Order (Big Endian) then #define __BITSTREAM_BIG_END 24 otherwise the default is 'Little Endian'. If your CPU has the same 25 Byte Order as your network stream, you can cut out some overheads 26 using #define __BITSTREAM_NATIVE_END --- if this is defined, 27 the __BITSTREAM_BIG_END flag becomes ineffective. 28 */ 29 30 namespace dhpnet 31 { 32 /** 33 * This macro transforms a bit in byte 34 * @param x Transform a bit to a byte 35 */ 36 #define BITS_TO_BYTES(x) (((x)+7)>>3) 37 38 #define BYTES_TO_BITS(x) (x<<3) 39 40 /** 41 * @brief Packets encoding and decoding facilities 42 * 43 * Helper class to encode and decode packets. 44 * 45 */ 46 47 class BitStream 48 { 49 50 public: 51 /** 52 * Default Constructor 53 */ 54 BitStream(); 55 /** 56 * Preallocate some memory for the construction of the packet 57 * @param initialBytesToAllocate the amount of byte to pre-allocate. 58 */ 59 BitStream( int initialBytesToAllocate ); 60 61 /** 62 * Initialize the BitStream object using data from the network. 63 * Set _copyData to true if you want to make an internal copy of 64 * the data you are passing. You can then Write and do all other 65 * operations Set it to false if you want to just use a pointer to 66 * the data you are passing, in order to save memory and speed. 67 * You should only then do read operations. 68 * @param _data An array of bytes. 69 * @param lengthInBytes Size of the @em _data. 70 * @param _copyData Does a copy of the input data. 71 */ 72 BitStream( unsigned char* _data, unsigned int lengthInBytes, bool _copyData ); 73 // 74 BitStream( unsigned char* _data, unsigned int lengthInBytes, unsigned int datasize); 75 /** 76 * Destructor 77 */ 78 ~BitStream(); 79 /** 80 * Reset the bitstream for reuse 81 */ 82 void Reset( void ); 83 void SetBuffer(char* _data, unsigned int lengthInBytes, unsigned int datasize); 84 void ClearBuffer(); 85 // 86 87 /** 88 * Write the native types to the end of the buffer 89 * without any compression mecanism. 90 * @param input The data 91 */ 92 void WriteBool( const bool input ); 93 /** 94 * Write the native types to the end of the buffer 95 * without any compression mecanism. 96 * @param input The data 97 */ 98 void WriteUInt8( const uint8 input ); 99 // 100 101 /** 102 * Write the native types to the end of the buffer 103 * without any compression mecanism. 104 * @param input The data 105 */ 106 void WriteInt8( const int8 input ); 107 /** 108 * Write the native types to the end of the buffer 109 * without any compression mecanism. 110 * @param input The data 111 */ 112 void WriteUInt16( const uint16 input ); 113 /** 114 * Write the native types to the end of the buffer 115 * without any compression mecanism. 116 * @param input The data 117 */ 118 void WriteInt16( const int16 input ); 119 /** 120 * Write the native types to the end of the buffer 121 * without any compression mecanism. 122 * @param input The data 123 */ 124 void WriteUInt32( const uint32 input ); 125 /** 126 * Write the native types to the end of the buffer 127 * without any compression mecanism. 128 * @param input The data 129 */ 130 void WriteInt32( const int32 input ); 131 132 #ifdef HAS_INT64 133 /** 134 * Write the native types to the end of the buffer 135 * without any compression mecanism. 136 * @param input The data 137 */ 138 void WriteUInt64( const uint64 input ); 139 /** 140 * Write the native types to the end of the buffer 141 * without any compression mecanism. 142 * @param input The data 143 */ 144 void WriteInt64( const int64 input ); 145 #endif 146 147 /** 148 * Write the native types to the end of the buffer 149 * without any compression mecanism. 150 * @param input The data 151 */ 152 void WriteFloat( const float input ); 153 /** 154 * Write the native types to the end of the buffer 155 * without any compression mechanism. 156 * @param input The data 157 */ 158 void WriteDouble( const double input ); 159 /** 160 * Write an array or casted stream. It is supposed to 161 * be raw data. It is also not possible to deal with endian problem 162 * @param input a byte buffer 163 * @param numberOfBytes the size of the byte buffer 164 */ 165 void WriteBytes( const char* input, const int numberOfBytes ); 166 /** 167 * write multi bytes string 168 * @param input 169 */ 170 void WriteStr(char input[]); 171 /** 172 * write standard string 173 * @param input 174 */ 175 void WriteStr( const std::string& input ); 176 /** 177 * Copy from another bitstream 178 * @bitStream the bitstream to copy from 179 */ 180 void WriteBS( const BitStream *bitStream ); 181 182 /** 183 * Write the native types with simple compression. 184 * Best used with negatives and positives close to 0 185 * @param input The data. 186 */ 187 void WriteCompUInt8( const uint8 input ); 188 /** 189 * Write the native types with simple compression. 190 * Best used with negatives and positives close to 0 191 * @param input The data. 192 */ 193 void WriteCompInt8( const int8 input ); 194 /** 195 * Write the native types with simple compression. 196 * Best used with negatives and positives close to 0 197 * @param input The data. 198 */ 199 void WriteCompUInt16( const uint16 input ); 200 /** 201 * Write the native types with simple compression. 202 * Best used with negatives and positives close to 0 203 * @param input The data. 204 */ 205 void WriteCompInt16( const int16 input ); 206 /** 207 * Write the native types with simple compression. 208 * Best used with negatives and positives close to 0 209 * @param input The data. 210 */ 211 void WriteCompUInt32( const uint32 input ); 212 /** 213 * Write the native types with simple compression. 214 * Best used with negatives and positives close to 0 215 * @param input The data. 216 */ 217 void WriteCompInt32( const int32 input ); 218 219 #ifdef HAS_INT64 220 /** 221 * Write the native types with simple compression. 222 * Best used with negatives and positives close to 0 223 * @param input The data. 224 */ 225 void WriteCompUInt64( const uint64 input ); 226 /** 227 * Write the native types with simple compression. 228 * Best used with negatives and positives close to 0 229 * @param input The data. 230 */ 231 void WriteCompInt64( const int64 input ); 232 #endif 233 /** 234 * Write the native types with simple compression. 235 * Best used with negatives and positives close to 0 236 * @param input The data. 237 */ 238 void WriteCompFloat( const float input ); 239 240 /** 241 * Write the native types with simple compression. 242 * Best used with negatives and positives close to 0 243 * @param input The data. 244 */ 245 void WriteCompDouble( const double input ); 246 247 /** 248 * Write a normalized 3D vector, using (at most) 4 bytes + 3 bits instead of 12 bytes. Will further compress y or z axis aligned vectors. 249 * Accurate to 1/32767.5. 250 * @param x x 251 * @param y y 252 * @param z z 253 */ 254 void WriteNormVector( float x, float y, float z ); 255 256 /** 257 * Write a vector, using 10 bytes instead of 12. 258 * Loses accuracy to about 3/10ths and only saves 2 bytes, so only use if accuracy is not important. 259 * @param x x 260 * @param y y 261 * @param z z 262 */ 263 void WriteVector( float x, float y, float z ); 264 265 /** 266 * Write a normalized quaternion in 6 bytes + 4 bits instead of 16 bytes. Slightly lossy. 267 * @param w w 268 * @param x x 269 * @param y y 270 * @param z z 271 */ 272 void WriteNormQuat( float w, float x, float y, float z); 273 274 /** 275 * Write an orthogonal matrix by creating a quaternion, and writing 3 components of the quaternion in 2 bytes each 276 * for 6 bytes instead of 36 277 */ 278 void WriteOrthMatrix( 279 float m00, float m01, float m02, 280 float m10, float m11, float m12, 281 float m20, float m21, float m22 ); 282 /** 283 * Read the native types from the front of the buffer 284 * @param output The readed value. 285 * @return true on success false otherwise. The result of a reading 286 * can only be wrong in the case we reach the end of the BitStream 287 * with some missing bits. 288 */ 289 bool ReadBool(); 290 /** 291 * Read the native types from the front of the buffer 292 * @param output The readed value. 293 * @return true on success false otherwise. The result of a reading 294 * can only be wrong in the case we reach the end of the BitStream 295 * with some missing bits. 296 */ 297 uint8 ReadUInt8(); 298 /** 299 * Read the native types from the front of the buffer 300 * @param output The readed value. 301 * @return true on success false otherwise. The result of a reading 302 * can only be wrong in the case we reach the end of the BitStream 303 * with some missing bits. 304 */ 305 int8 ReadInt8(); 306 /** 307 * Read the native types from the front of the buffer 308 * @param output The readed value. 309 * @return true on success false otherwise. The result of a reading 310 * can only be wrong in the case we reach the end of the BitStream 311 * with some missing bits. 312 */ 313 uint16 ReadUInt16(); 314 /** 315 * Read the native types from the front of the buffer 316 * @param output The readed value. 317 * @return true on success false otherwise. The result of a reading 318 * can only be wrong in the case we reach the end of the BitStream 319 * with some missing bits. 320 */ 321 int16 ReadInt16(); 322 /** 323 * Read the native types from the front of the buffer 324 * @param output The readed value. 325 * @return true on success false otherwise. The result of a reading 326 * can only be wrong in the case we reach the end of the BitStream 327 * with some missing bits. 328 */ 329 uint32 ReadUInt32(); 330 /** 331 * Read the native types from the front of the buffer 332 * @param output The readed value. 333 * @return true on success false otherwise. The result of a reading 334 * can only be wrong in the case we reach the end of the BitStream 335 * with some missing bits. 336 */ 337 int32 ReadInt32(); 338 339 340 #ifdef HAS_INT64 341 /** 342 * Read the native types from the front of the buffer 343 * @param output The readed value. 344 * @return true on success false otherwise. The result of a reading 345 * can only be wrong in the case we reach the end of the BitStream 346 * with some missing bits. 347 */ 348 uint64 ReadUInt64(); 349 /** 350 * Read the native types from the front of the buffer 351 * @param output The readed value. 352 * @return true on success false otherwise. The result of a reading 353 * can only be wrong in the case we reach the end of the BitStream 354 * with some missing bits. 355 */ 356 int64 ReadInt64(); 357 #endif 358 /** 359 * Read the native types from the front of the buffer 360 * @param output The readed value. 361 * @return true on success false otherwise. The result of a reading 362 * can only be wrong in the case we reach the end of the BitStream 363 * with some missing bits. 364 */ 365 float ReadFloat(); 366 /** 367 * Read the native types from the front of the buffer 368 * @param output The readed value. 369 * @return true on success false otherwise. The result of a reading 370 * can only be wrong in the case we reach the end of the BitStream 371 * with some missing bits. 372 */ 373 double ReadDouble(); 374 /** 375 * Read an array or casted stream of byte. The array 376 * is raw data. There is no automatic conversion on 377 * big endian arch 378 * @param output The result byte array. It should be larger than @em numberOfBytes. 379 * @param numberOfBytes The number of byte to read 380 * @return true on success false if there is some missing bytes. 381 */ 382 bool ReadBytes( char* output, const int numberOfBytes ); 383 /** 384 * Read multi bytes string 385 * @return 386 */ 387 bool ReadStr(char output[], int size); 388 /** 389 * Read standard string 390 * @return 391 */ 392 std::string ReadStr(); 393 /** 394 * Read the types you wrote with WriteCompressed 395 * @param output The read value 396 * @return true on success, false on not enough data to read 397 */ 398 uint8 ReadCompUInt8(); 399 /** 400 * Read the types you wrote with WriteCompressed 401 * @param output The read value 402 * @return true on success, false on not enough data to read 403 */ 404 int8 ReadCompInt8(); 405 /** 406 * Read the types you wrote with WriteCompressed 407 * @param output The read value 408 * @return true on success, false on not enough data to read 409 */ 410 uint16 ReadCompUInt16(); 411 /** 412 * Read the types you wrote with WriteCompressed 413 * @param output The read value 414 * @return true on success, false on not enough data to read 415 */ 416 int16 ReadCompInt16(); 417 /** 418 * Read the types you wrote with WriteCompressed 419 * @param output The read value 420 * @return true on success, false on not enough data to read 421 */ 422 uint32 ReadCompUInt32(); 423 /** 424 * Read the types you wrote with WriteCompressed 425 * @param output The read value 426 * @return true on success, false on not enough data to read 427 */ 428 int32 ReadCompInt32(); 429 430 #ifdef HAS_INT64 431 /** 432 * Read the types you wrote with WriteCompressed 433 * @param output The read value 434 * @return true on success, false on not enough data to read 435 */ 436 uint64 ReadCompUInt64(); 437 /** 438 * Read the types you wrote with WriteCompressed 439 * @param output The read value 440 * @return true on success, false on not enough data to read 441 */ 442 int64 ReadCompInt64(); 443 #endif 444 /** 445 * Read the types you wrote with WriteCompressed 446 * @param output The read value 447 * @return true on success, false on not enough data to read 448 */ 449 float ReadCompFloat(); 450 451 /** 452 * Read the types you wrote with WriteCompressed 453 * @param output The read value 454 * @return true on success, false on not enough data to read 455 */ 456 double ReadCompDouble(); 457 458 /** 459 * Read a normalized 3D vector, using (at most) 4 bytes + 3 bits instead of 12 bytes. Will further compress y or z axis aligned vectors. 460 * Accurate to 1/32767.5. 461 * @param x x 462 * @param y y 463 * @param z z 464 */ 465 bool ReadNormVector( float &x, float &y, float &z ); 466 467 /** 468 * Read 3 floats, using 10 bytes, where those floats comprise a vector 469 * Loses accuracy to about 3/10ths and only saves 2 bytes, so only use if accuracy is not important. 470 * @param x x 471 * @param y y 472 * @param z z 473 */ 474 bool ReadVector( float &x, float &y, float &z ); 475 /** 476 * Read a normalized quaternion in 6 bytes + 4 bits instead of 16 bytes. Slightly lossy. 477 * @param w w 478 * @param x x 479 * @param y y 480 * @param z z 481 */ 482 bool ReadNormQuat( float &w, float &x, float &y, float &z); 483 /** 484 * Read an orthogonal matrix from a quaternion, reading 3 components of the quaternion in 2 bytes each and extrapolatig the 4th. 485 * for 6 bytes instead of 36 486 */ 487 bool ReadOrthMatrix( 488 float &m00, float &m01, float &m02, 489 float &m10, float &m11, float &m12, 490 float &m20, float &m21, float &m22 ); 491 492 /** 493 * Sets the read pointer back to the beginning of your data. 494 */ 495 void ResetReadPointer( void ); 496 /** 497 * Sets the write pointer back to the beginning of your data. 498 */ 499 void ResetWritePointer( void ); 500 /** 501 * This is good to call when you are done with the stream to make 502 * sure you didn't leave any data left over void 503 */ 504 void AssertStreamEmpty( void ); 505 /** 506 * print to the standard output the state of the stream bit by bit 507 */ 508 void PrintBits( void ) const; 509 510 /** 511 * Ignore data we don't intend to read 512 * @param numberOfBits The number of bits to ignore 513 */ 514 void IgnoreBits( const int numberOfBits ); 515 516 /** 517 * Move the write pointer to a position on the array. 518 * @param offset the offset from the start of the array. 519 * @attention 520 * Dangerous if you don't know what you are doing! 521 * 522 */ 523 void SetWriteOffset( const int offset ); 524 /** 525 * Returns the length in bits of the stream 526 */ 527 int GetWriteOffset( void ) const; 528 /** 529 * Returns the length in bytes of the stream 530 */ 531 int GetNumberOfBytesUsed( void ) const; 532 533 int GetNumberOfBytesRead(void)const; 534 535 /** 536 * Move the read pointer to a position on the array. 537 * @param offset 538 */ 539 void SetReadOffset( const int offset ); 540 541 void SetByteReadOffSet(const int offset); 542 /** 543 * Returns the number of bits into the stream that we have read 544 */ 545 int GetReadOffset( void ) const; 546 547 /** 548 * Returns the number of bits left in the stream that haven't been read 549 */ 550 int GetNumberOfUnreadBits( void ) const; 551 /** 552 * Makes a copy of the internal data for you Data will point to 553 * the stream. Returns the length in bits of the stream. Partial 554 * bytes are left aligned 555 * @param _data the resulting byte copy of the internal state. 556 */ 557 int CopyData( unsigned char** _data ) const; 558 /** 559 * Set the stream to some initial data. For internal use 560 * Partial bytes are left aligned 561 * @param input The data 562 * @param numberOfBits the number of bits set in the data buffer 563 */ 564 void SetData( const unsigned char* input, const int numberOfBits ); 565 /** 566 * Exposes the internal data. 567 * Partial bytes are left aligned. 568 * @return A pointer to the internal state 569 */ 570 unsigned char* GetData( void ) const; 571 /** 572 * Write numberToWrite bits from the input source Right aligned 573 * data means in the case of a partial byte, the bits are aligned 574 * from the right (bit 0) rather than the left (as in the normal 575 * internal representation) You would set this to true when 576 * writing user data, and false when copying bitstream data, such 577 * as writing one bitstream to another 578 * @param input The data 579 * @param numberOfBitsToWrite The number of bits to write 580 * @param rightAlignedBits if true data will be right aligned 581 */ 582 void WriteBits( const unsigned char* input, 583 int numberOfBitsToWrite, const bool rightAlignedBits = true ); 584 /** 585 * Align the bitstream to the byte boundary and then write the 586 * specified number of bits. This is faster than WriteBits but 587 * wastes the bits to do the alignment and requires you to call 588 * ReadAlignedBits at the corresponding read position. 589 * @param input The data 590 * @param numberOfBytesToWrite The size of data. 591 */ 592 void WriteAlignedBytes( const unsigned char* input, 593 const int numberOfBytesToWrite ); 594 /** 595 * Read bits, starting at the next aligned bits. Note that the 596 * modulus 8 starting offset of the sequence must be the same as 597 * was used with WriteBits. This will be a problem with packet 598 * coalescence unless you byte align the coalesced packets. 599 * @param output The byte array larger than @em numberOfBytesToRead 600 * @param numberOfBytesToRead The number of byte to read from the internal state 601 * @return true if there is enough byte. 602 */ 603 bool ReadAlignedBytes( unsigned char* output, 604 const int numberOfBytesToRead ); 605 /** 606 * Align the next write and/or read to a byte boundary. This can 607 * be used to 'waste' bits to byte align for efficiency reasons It 608 * can also be used to force coalesced bitstreams to start on byte 609 * boundaries so so WriteAlignedBits and ReadAlignedBits both 610 * calculate the same offset when aligning. 611 */ 612 void AlignWriteToByteBoundary( void ); 613 /** 614 * Align the next write and/or read to a byte boundary. This can 615 * be used to 'waste' bits to byte align for efficiency reasons It 616 * can also be used to force coalesced bitstreams to start on byte 617 * boundaries so so WriteAlignedBits and ReadAlignedBits both 618 * calculate the same offset when aligning. 619 */ 620 void AlignReadToByteBoundary( void ); 621 622 /** 623 * Read numberOfBitsToRead bits to the output source 624 * alignBitsToRight should be set to true to convert internal 625 * bitstream data to userdata It should be false if you used 626 * WriteBits with rightAlignedBits false 627 * @param output The resulting bits array 628 * @param numberOfBitsToRead The number of bits to read 629 * @param alignsBitsToRight if true bits will be right aligned. 630 * @return true if there is enough bits to read 631 */ 632 bool ReadBits( unsigned char* output, int numberOfBitsToRead, 633 const bool alignBitsToRight = true ); 634 635 /** 636 * --- Low level functions --- 637 * These are for when you want to deal 638 * with bits and don't care about type checking 639 * Write a 0 640 */ 641 void Write0( void ); 642 /** 643 * --- Low level functions --- 644 * These are for when you want to deal 645 * with bits and don't care about type checking 646 * Write a 1 647 */ 648 void Write1( void ); 649 /** 650 * --- Low level functions --- 651 * These are for when you want to deal 652 * with bits and don't care about type checking 653 * Reads 1 bit and returns true if that bit is 1 and false if it is 0 654 */ 655 bool ReadBit( void ); 656 /** 657 * If we used the constructor version with copy data off, this 658 * makes sure it is set to on and the data pointed to is copied. 659 */ 660 void AssertCopyData( void ); 661 /** 662 * Use this if you pass a pointer copy to the constructor 663 * (_copyData==false) and want to overallocate to prevent 664 * reallocation 665 */ 666 void SetNumberOfBitsAllocated( const unsigned int lengthInBits ); 667 668 private: 669 /** 670 * Assume the input source points to a native type, compress and write it. 671 */ 672 void WriteCompressed( const unsigned char* input, 673 const int size, const bool unsignedData ); 674 675 /** 676 * Assume the input source points to a compressed native type. 677 * Decompress and read it. 678 */ 679 bool ReadCompressed( unsigned char* output, 680 const int size, const bool unsignedData ); 681 682 /** 683 * Reallocates (if necessary) in preparation of writing 684 * numberOfBitsToWrite 685 */ 686 void AddBitsAndReallocate( const int numberOfBitsToWrite ); 687 688 /** 689 * Number of bits currently used 690 */ 691 int numberOfBitsUsed; 692 /** 693 * Number of bits currently allocated 694 */ 695 int numberOfBitsAllocated; 696 /** 697 * Current readOffset 698 */ 699 int readOffset; 700 /** 701 * array of byte storing the data. Points to stackData or if is bigger than that then is allocated 702 */ 703 unsigned char *data; 704 /** 705 * true if the internal buffer is copy of the data passed to the 706 * constructor 707 */ 708 bool copyData; 709 710 unsigned char stackData[BITSTREAM_STACK_ALLOCATION_SIZE]; 711 712 }; 713 } 714 715 #endif
BitSteam.cpp:
1 // This should be on by default for speed. Turn it off if you actually need endian swapping 2 #define __BITSTREAM_BIG_END 3 4 #include "BitStream.h" 5 #include <math.h> 6 #include <assert.h> 7 #include <string.h> 8 #ifdef _WIN32 9 #include <stdlib.h> 10 #include <memory.h> 11 #include <stdio.h> 12 #include <float.h> 13 #else 14 #define _copysign copysign 15 #endif 16 17 18 19 #if defined ( __APPLE__ ) || defined ( __APPLE_CC__ ) 20 #include <malloc/malloc.h> 21 #else 22 #include <malloc.h> 23 #include <string> 24 #endif 25 26 #ifdef __BITSTREAM_BIG_END 27 // Set up the read/write routines to produce Big-End network streams. 28 #define B16_1 0 29 #define B16_0 1 30 31 #define B32_3 0 32 #define B32_2 1 33 #define B32_1 2 34 #define B32_0 3 35 36 #define B64_7 0 37 #define B64_6 1 38 #define B64_5 2 39 #define B64_4 3 40 #define B64_3 4 41 #define B64_2 5 42 #define B64_1 6 43 #define B64_0 7 44 45 #else 46 // Default to producing Little-End network streams. 47 #define B16_1 1 48 #define B16_0 0 49 50 #define B32_3 3 51 #define B32_2 2 52 #define B32_1 1 53 #define B32_0 0 54 55 #define B64_7 7 56 #define B64_6 6 57 #define B64_5 5 58 #define B64_4 4 59 #define B64_3 3 60 #define B64_2 2 61 #define B64_1 1 62 #define B64_0 0 63 #endif 64 65 using namespace dhpnet; 66 67 BitStream::BitStream() 68 { 69 numberOfBitsUsed = 0; 70 //numberOfBitsAllocated = 32 * 8; 71 numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE * 8; 72 readOffset = 0; 73 //data = ( unsigned char* ) malloc( 32 ); 74 data = ( unsigned char* ) stackData; 75 76 #ifdef _DEBUG 77 // assert( data ); 78 #endif 79 //memset(data, 0, 32); 80 copyData = true; 81 } 82 83 BitStream::BitStream( int initialBytesToAllocate ) 84 { 85 numberOfBitsUsed = 0; 86 readOffset = 0; 87 if (initialBytesToAllocate <= BITSTREAM_STACK_ALLOCATION_SIZE) 88 { 89 data = ( unsigned char* ) stackData; 90 numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE * 8; 91 } 92 else 93 { 94 data = ( unsigned char* ) malloc( initialBytesToAllocate ); 95 numberOfBitsAllocated = initialBytesToAllocate << 3; 96 } 97 #ifdef _DEBUG 98 assert( data ); 99 #endif 100 // memset(data, 0, initialBytesToAllocate); 101 copyData = true; 102 } 103 104 BitStream::BitStream(unsigned char* _data, unsigned int lengthInBytes, bool _copyData) 105 { 106 numberOfBitsUsed = lengthInBytes << 3; 107 readOffset = 0; 108 copyData = _copyData; 109 numberOfBitsAllocated = lengthInBytes << 3; 110 111 if ( copyData ) 112 { 113 if ( lengthInBytes > 0 ) 114 { 115 if (lengthInBytes < BITSTREAM_STACK_ALLOCATION_SIZE) 116 { 117 data = ( unsigned char* ) stackData; 118 numberOfBitsAllocated = BITSTREAM_STACK_ALLOCATION_SIZE << 3; 119 } 120 else 121 { 122 data = ( unsigned char* ) malloc( lengthInBytes ); 123 } 124 #ifdef _DEBUG 125 assert( data ); 126 #endif 127 memcpy( data, _data, lengthInBytes ); 128 } 129 else 130 data = 0; 131 } 132 else 133 { 134 data = ( unsigned char* ) _data; 135 numberOfBitsUsed = 0; 136 } 137 } 138 BitStream::BitStream(unsigned char* _data, unsigned int lengthInBytes, unsigned int datasize) 139 { 140 numberOfBitsUsed = datasize << 3; 141 readOffset = 0; 142 numberOfBitsAllocated = lengthInBytes << 3; 143 data = ( unsigned char* ) _data; 144 copyData = false; 145 } 146 void BitStream::SetBuffer(char* _data, unsigned int lengthInBytes, unsigned int datasize) 147 { 148 numberOfBitsUsed = datasize << 3; 149 readOffset = 0; 150 numberOfBitsAllocated = lengthInBytes << 3; 151 data = ( unsigned char* ) _data; 152 copyData = false; 153 } 154 void BitStream::ClearBuffer() 155 { 156 numberOfBitsUsed = 0; 157 readOffset = 0; 158 numberOfBitsAllocated = 0; 159 data = NULL; 160 } 161 // Use this if you pass a pointer copy to the constructor (_copyData==false) and want to overallocate to prevent reallocation 162 void BitStream::SetNumberOfBitsAllocated( const unsigned int lengthInBits ) 163 { 164 #ifdef _DEBUG 165 assert( lengthInBits >= ( unsigned int ) numberOfBitsAllocated ); 166 #endif 167 numberOfBitsAllocated = lengthInBits; 168 } 169 170 BitStream::~BitStream() 171 { 172 if ( copyData && numberOfBitsAllocated > BITSTREAM_STACK_ALLOCATION_SIZE << 3) 173 free( data ); // Use realloc and free so we are more efficient than delete and new for resizing 174 } 175 176 void BitStream::Reset( void ) 177 { 178 // Note: Do NOT reallocate memory because BitStream is used 179 // in places to serialize/deserialize a buffer. Reallocation 180 // is a dangerous operation (may result in leaks). 181 182 if ( numberOfBitsUsed > 0 ) 183 { 184 // memset(data, 0, BITS_TO_BYTES(numberOfBitsUsed)); 185 } 186 187 // Don't free memory here for speed efficiency 188 //free(data); // Use realloc and free so we are more efficient than delete and new for resizing 189 numberOfBitsUsed = 0; 190 191 //numberOfBitsAllocated=8; 192 readOffset = 0; 193 194 //data=(unsigned char*)malloc(1); 195 // if (numberOfBitsAllocated>0) 196 // memset(data, 0, BITS_TO_BYTES(numberOfBitsAllocated)); 197 } 198 199 // Write the native types to the end of the buffer 200 void BitStream::WriteBool( const bool input ) 201 { 202 #ifdef TYPE_CHECKING 203 unsigned char ID = 0; 204 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 205 #endif 206 207 if ( input ) 208 WriteInt8(1); 209 else 210 WriteInt8(0); 211 } 212 213 void BitStream::WriteUInt8( const uint8 input ) 214 { 215 #ifdef TYPE_CHECKING 216 unsigned char ID = 1; 217 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 218 #endif 219 220 WriteBits( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 221 } 222 223 void BitStream::WriteInt8( const int8 input ) 224 { 225 #ifdef TYPE_CHECKING 226 unsigned char ID = 2; 227 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 228 #endif 229 230 WriteBits( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 231 } 232 233 void BitStream::WriteUInt16( const uint16 input ) 234 { 235 #ifdef TYPE_CHECKING 236 unsigned char ID = 3; 237 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 238 #endif 239 240 #ifdef __BITSTREAM_NATIVE_END 241 WriteBits( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 242 #else 243 unsigned char uint16w[2]; 244 uint16w[B16_1] = (input >> 8)&(0xff); 245 uint16w[B16_0] = input&(0xff); 246 247 WriteBits( uint16w, sizeof( input ) * 8, true ); 248 #endif 249 } 250 251 void BitStream::WriteInt16( const int16 input ) 252 { 253 #ifdef TYPE_CHECKING 254 unsigned char ID = 4; 255 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 256 #endif 257 258 #ifdef __BITSTREAM_NATIVE_END 259 WriteBits( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 260 #else 261 unsigned char int16w[2]; 262 int16w[B16_1] = (input >> 8)&(0xff); 263 int16w[B16_0] = input&(0xff); 264 265 WriteBits( int16w, sizeof( input ) * 8, true ); 266 #endif 267 } 268 269 void BitStream::WriteUInt32( const uint32 input ) 270 { 271 #ifdef TYPE_CHECKING 272 unsigned char ID = 5; 273 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 274 #endif 275 276 #ifdef __BITSTREAM_NATIVE_END 277 WriteBits( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 278 #else 279 unsigned char uint32w[4]; 280 uint32w[B32_3] = (input >> 24)&(0x000000ff); 281 uint32w[B32_2] = (input >> 16)&(0x000000ff); 282 uint32w[B32_1] = (input >> 8)&(0x000000ff); 283 uint32w[B32_0] = (input)&(0x000000ff); 284 285 WriteBits( uint32w, sizeof( input ) * 8, true ); 286 #endif 287 } 288 289 void BitStream::WriteInt32( const int32 input ) 290 { 291 #ifdef TYPE_CHECKING 292 unsigned char ID = 6; 293 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 294 #endif 295 296 #ifdef __BITSTREAM_NATIVE_END 297 WriteBits( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 298 #else 299 unsigned char int32w[4]; 300 int32w[B32_3] = (input >> 24)&(0x000000ff); 301 int32w[B32_2] = (input >> 16)&(0x000000ff); 302 int32w[B32_1] = (input >> 8)&(0x000000ff); 303 int32w[B32_0] = (input)&(0x000000ff); 304 305 WriteBits( int32w, sizeof( input ) * 8, true ); 306 #endif 307 } 308 309 #ifdef HAS_INT64 310 void BitStream::WriteUInt64( const uint64 input ) 311 { 312 #ifdef TYPE_CHECKING 313 unsigned char ID = 7; 314 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 315 #endif 316 317 #ifdef __BITSTREAM_NATIVE_END 318 WriteBits( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 319 #else 320 unsigned char uint64w[8]; 321 uint64w[B64_7] = (input >> 56) & 0xff; 322 uint64w[B64_6] = (input >> 48) & 0xff; 323 uint64w[B64_5] = (input >> 40) & 0xff; 324 uint64w[B64_4] = (input >> 32) & 0xff; 325 uint64w[B64_3] = (input >> 24) & 0xff; 326 uint64w[B64_2] = (input >> 16) & 0xff; 327 uint64w[B64_1] = (input >> 8) & 0xff; 328 uint64w[B64_0] = input & 0xff; 329 330 WriteBits( uint64w, sizeof( input ) * 8, true ); 331 #endif 332 } 333 334 void BitStream::WriteInt64( const int64 input ) 335 { 336 #ifdef TYPE_CHECKING 337 unsigned char ID = 8; 338 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 339 #endif 340 341 #ifdef __BITSTREAM_NATIVE_END 342 WriteBits( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 343 #else 344 unsigned char int64w[8]; 345 int64w[B64_7] = (input >> 56) & 0xff; 346 int64w[B64_6] = (input >> 48) & 0xff; 347 int64w[B64_5] = (input >> 40) & 0xff; 348 int64w[B64_4] = (input >> 32) & 0xff; 349 int64w[B64_3] = (input >> 24) & 0xff; 350 int64w[B64_2] = (input >> 16) & 0xff; 351 int64w[B64_1] = (input >> 8) & 0xff; 352 int64w[B64_0] = input & 0xff; 353 354 WriteBits( int64w, sizeof( input ) * 8, true ); 355 #endif 356 } 357 358 #endif 359 360 void BitStream::WriteFloat( const float input ) 361 { 362 #ifdef TYPE_CHECKING 363 unsigned char ID = 9; 364 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 365 #endif 366 367 #ifndef __BITSTREAM_NATIVE_END 368 unsigned int intval = *((unsigned int *)(&input)); 369 WriteUInt32(intval); 370 #else 371 WriteBits( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 372 #endif 373 } 374 375 void BitStream::WriteDouble( const double input ) 376 { 377 #ifdef TYPE_CHECKING 378 unsigned char ID = 10; 379 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 380 #endif 381 382 #if defined ( __BITSTREAM_NATIVE_END ) || ( ! defined (HAS_INT64) ) 383 WriteBits( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 384 #else 385 uint64_t intval = *((uint64_t *)(&input)); 386 WriteUInt64(intval); 387 #endif 388 } 389 // Write an array or casted stream 390 void BitStream::WriteBytes( const char* input, const int numberOfBytes ) 391 { 392 #ifdef TYPE_CHECKING 393 unsigned char ID = 11; 394 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 395 WriteBits( ( unsigned char* ) & numberOfBytes, sizeof( int ) * 8, true ); 396 #endif 397 398 WriteBits( ( unsigned char* ) input, numberOfBytes * 8, true ); 399 } 400 401 void BitStream::WriteStr(char input[]) 402 { 403 unsigned short len = strlen(input); 404 WriteUInt16(len); 405 if(len > 0){ 406 WriteBytes(input,len); 407 } 408 } 409 410 void BitStream::WriteStr(const std::string& input) 411 { 412 unsigned short len = input.size(); 413 WriteUInt16(len); 414 if(len > 0){ 415 WriteBytes(input.data(),len); 416 } 417 } 418 419 void BitStream::WriteBS( const BitStream *bitStream ) 420 { 421 WriteBits(bitStream->GetData(), bitStream->GetWriteOffset(), false); 422 } 423 424 // Write the native types with simple compression. 425 // Best used with negatives and positives close to 0 426 void BitStream::WriteCompUInt8( const uint8 input ) 427 { 428 #ifdef TYPE_CHECKING 429 unsigned char ID = 12; 430 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 431 #endif 432 433 WriteCompressed( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 434 } 435 436 void BitStream::WriteCompInt8( const int8 input ) 437 { 438 #ifdef TYPE_CHECKING 439 unsigned char ID = 13; 440 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 441 #endif 442 443 WriteCompressed( ( unsigned char* ) & input, sizeof( input ) * 8, false ); 444 } 445 446 void BitStream::WriteCompUInt16( const uint16 input ) 447 { 448 #ifdef TYPE_CHECKING 449 unsigned char ID = 14; 450 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 451 #endif 452 453 #ifdef __BITSTREAM_NATIVE_END 454 WriteCompressed( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 455 #else 456 unsigned char uint16wc[2]; 457 uint16wc[B16_1] = (input >> 8)&(0xff); 458 uint16wc[B16_0] = input&(0xff); 459 460 WriteCompressed( uint16wc, sizeof( input ) * 8, true ); 461 #endif 462 } 463 464 void BitStream::WriteCompInt16( const int16 input ) 465 { 466 #ifdef TYPE_CHECKING 467 unsigned char ID = 15; 468 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 469 #endif 470 471 #ifdef __BITSTREAM_NATIVE_END 472 WriteCompressed( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 473 #else 474 unsigned char int16wc[2]; 475 int16wc[B16_1] = (input >> 8)&(0xff); 476 int16wc[B16_0] = input&(0xff); 477 478 WriteCompressed( int16wc, sizeof( input ) * 8, false ); 479 #endif 480 } 481 482 void BitStream::WriteCompUInt32( const uint32 input ) 483 { 484 #ifdef TYPE_CHECKING 485 unsigned char ID = 16; 486 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 487 #endif 488 489 #ifdef __BITSTREAM_NATIVE_END 490 WriteCompressed( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 491 #else 492 unsigned char uint32wc[4]; 493 uint32wc[B32_3] = (input >> 24)&(0x000000ff); 494 uint32wc[B32_2] = (input >> 16)&(0x000000ff); 495 uint32wc[B32_1] = (input >> 8)&(0x000000ff); 496 uint32wc[B32_0] = (input)&(0x000000ff); 497 498 WriteCompressed( uint32wc, sizeof( input ) * 8, true ); 499 #endif 500 } 501 502 void BitStream::WriteCompInt32( const int32 input ) 503 { 504 #ifdef TYPE_CHECKING 505 unsigned char ID = 17; 506 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 507 #endif 508 509 #ifdef __BITSTREAM_NATIVE_END 510 WriteCompressed( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 511 #else 512 unsigned char int32wc[4]; 513 int32wc[B32_3] = (input >> 24)&(0x000000ff); 514 int32wc[B32_2] = (input >> 16)&(0x000000ff); 515 int32wc[B32_1] = (input >> 8)&(0x000000ff); 516 int32wc[B32_0] = (input)&(0x000000ff); 517 518 WriteCompressed( int32wc, sizeof( input ) * 8, false ); 519 #endif 520 } 521 522 #ifdef HAS_INT64 523 void BitStream::WriteCompUInt64( const uint64 input ) 524 { 525 #ifdef TYPE_CHECKING 526 unsigned char ID = 18; 527 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 528 #endif 529 530 #ifdef __BITSTREAM_NATIVE_END 531 WriteCompressed( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 532 #else 533 unsigned char uint64wc[8]; 534 uint64wc[B64_7] = (input >> 56) & 0xff; 535 uint64wc[B64_6] = (input >> 48) & 0xff; 536 uint64wc[B64_5] = (input >> 40) & 0xff; 537 uint64wc[B64_4] = (input >> 32) & 0xff; 538 uint64wc[B64_3] = (input >> 24) & 0xff; 539 uint64wc[B64_2] = (input >> 16) & 0xff; 540 uint64wc[B64_1] = (input >> 8) & 0xff; 541 uint64wc[B64_0] = input & 0xff; 542 543 WriteCompressed( uint64wc, sizeof( input ) * 8, true ); 544 #endif 545 } 546 547 void BitStream::WriteCompInt64( const int64 input ) 548 { 549 #ifdef TYPE_CHECKING 550 unsigned char ID = 19; 551 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 552 #endif 553 554 #ifdef __BITSTREAM_NATIVE_END 555 WriteCompressed( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 556 #else 557 unsigned char int64wc[8]; 558 int64wc[B64_7] = (input >> 56) & 0xff; 559 int64wc[B64_6] = (input >> 48) & 0xff; 560 int64wc[B64_5] = (input >> 40) & 0xff; 561 int64wc[B64_4] = (input >> 32) & 0xff; 562 int64wc[B64_3] = (input >> 24) & 0xff; 563 int64wc[B64_2] = (input >> 16) & 0xff; 564 int64wc[B64_1] = (input >> 8) & 0xff; 565 int64wc[B64_0] = input & 0xff; 566 567 WriteCompressed( int64wc, sizeof( input ) * 8, false ); 568 #endif 569 } 570 #endif 571 572 573 void BitStream::WriteCompFloat( const float input ) 574 { 575 #ifdef TYPE_CHECKING 576 unsigned char ID = 20; 577 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 578 #endif 579 580 // Not yet implemented (no compression) 581 #if defined ( __BITSTREAM_NATIVE_END ) 582 WriteBits( ( unsigned char* ) &input, sizeof( input ) * 8, true ); 583 #else 584 WriteFloat( input ); 585 #endif 586 } 587 588 void BitStream::WriteCompDouble( const double input ) 589 { 590 #ifdef TYPE_CHECKING 591 unsigned char ID = 21; 592 WriteBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8, true ); 593 #endif 594 595 // Not yet implemented (no compression) 596 #if defined ( __BITSTREAM_NATIVE_END ) 597 WriteBits( ( unsigned char* ) & input, sizeof( input ) * 8, true ); 598 #else 599 WriteDouble( input ); 600 #endif 601 } 602 603 void BitStream::WriteNormVector( float x, float y, float z ) 604 { 605 #ifdef _DEBUG 606 assert(x <= 1.01f && y <= 1.01f && z <= 1.01f && x >= -1.01f && y >= -1.01f && z >= -1.01f); 607 #endif 608 if (x>1.0f) 609 x=1.0f; 610 if (y>1.0f) 611 y=1.0f; 612 if (z>1.0f) 613 z=1.0f; 614 if (x<-1.0f) 615 x=-1.0f; 616 if (y<-1.0f) 617 y=-1.0f; 618 if (z<-1.0f) 619 z=-1.0f; 620 621 WriteBool((bool) (x < 0.0f)); 622 623 if (y==0.0f) 624 WriteBool(true); 625 else 626 { 627 WriteBool(false); 628 WriteUInt16((unsigned short)((y+1.0f)*32767.5f)); 629 } 630 if (z==0.0f) 631 WriteBool(true); 632 else 633 { 634 WriteBool(false); 635 WriteUInt16((unsigned short)((z+1.0f)*32767.5f)); 636 } 637 } 638 void BitStream::WriteVector( float x, float y, float z ) 639 { 640 float magnitude = sqrtf(x * x + y * y + z * z); 641 WriteFloat(magnitude); 642 if (magnitude > 0.0f) 643 { 644 WriteUInt16((unsigned short)((x/magnitude+1.0f)*32767.5f)); 645 WriteUInt16((unsigned short)((y/magnitude+1.0f)*32767.5f)); 646 WriteUInt16((unsigned short)((z/magnitude+1.0f)*32767.5f)); 647 } 648 } 649 void BitStream::WriteNormQuat( float w, float x, float y, float z) 650 { 651 WriteBool((bool)(w<0.0f)); 652 WriteBool((bool)(x<0.0f)); 653 WriteBool((bool)(y<0.0f)); 654 WriteBool((bool)(z<0.0f)); 655 WriteUInt16((unsigned short)(fabs(x)*65535.0)); 656 WriteUInt16((unsigned short)(fabs(y)*65535.0)); 657 WriteUInt16((unsigned short)(fabs(z)*65535.0)); 658 // Leave out w and calcuate it on the target 659 } 660 void BitStream::WriteOrthMatrix( 661 float m00, float m01, float m02, 662 float m10, float m11, float m12, 663 float m20, float m21, float m22 ) 664 { 665 double qw; 666 double qx; 667 double qy; 668 double qz; 669 670 // Convert matrix to quat 671 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ 672 qw = sqrt( 1 + m00 + m11 + m22 ) / 2; 673 qx = sqrt( 1 + m00 - m11 - m22 ) / 2; 674 qy = sqrt( 1 - m00 + m11 - m22 ) / 2; 675 qz = sqrt( 1 - m00 - m11 + m22 ) / 2; 676 if (qw < 0.0) qw=0.0; 677 if (qx < 0.0) qx=0.0; 678 if (qy < 0.0) qy=0.0; 679 if (qz < 0.0) qz=0.0; 680 qx = _copysign( qx, m21 - m12 ); 681 qy = _copysign( qy, m02 - m20 ); 682 qz = _copysign( qz, m20 - m02 ); 683 684 WriteNormQuat((float)qw,(float)qx,(float)qy,(float)qz); 685 } 686 687 // Read the native types from the front of the buffer 688 // Write the native types to the end of the buffer 689 bool BitStream::ReadBool() 690 { 691 #ifdef TYPE_CHECKING 692 unsigned char ID; 693 694 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 695 return false; 696 697 #ifdef _DEBUG 698 699 assert( ID == 0 ); 700 701 #endif 702 return true; 703 #endif 704 705 //assert(readOffset+1 <=numberOfBitsUsed); // If this assert is hit the stream wasn't long enough to read from 706 if ( readOffset + 1 > numberOfBitsUsed ) 707 return false; 708 709 //if (ReadBit()) // Check that bit 710 if ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset++ % 8 ) ) ) // Is it faster to just write it out here? 711 return true; 712 713 return false; 714 } 715 716 uint8 BitStream::ReadUInt8() 717 { 718 #ifdef TYPE_CHECKING 719 unsigned char ID; 720 721 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 722 return 0; 723 724 assert( ID == 1 ); 725 return ID; 726 #endif 727 uint8 uint8r; 728 if(ReadBits( ( unsigned char* ) & uint8r, sizeof( uint8r ) * 8 )){ 729 return uint8r; 730 } 731 return 0; 732 } 733 734 int8 BitStream::ReadInt8() 735 { 736 #ifdef TYPE_CHECKING 737 unsigned char ID; 738 739 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 740 return 0; 741 742 assert( ID == 2 ); 743 return ID; 744 #endif 745 int8 int8r; 746 if(ReadBits( ( unsigned char* ) & int8r, sizeof( int8r ) * 8 )) { 747 return int8r; 748 } 749 return 0; 750 } 751 752 uint16 BitStream::ReadUInt16() 753 { 754 #ifdef TYPE_CHECKING 755 unsigned char ID; 756 757 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 758 return 0; 759 760 assert( ID == 3 ); 761 return ID; 762 #endif 763 unsigned char uint16r[2]; 764 #ifdef __BITSTREAM_NATIVE_END 765 if(ReadBits( uint16r, sizeof( uint16_t ) * 8 )){ 766 return *(uint16_t*)uint16r; 767 } 768 return 0; 769 #else 770 if (ReadBits( uint16r, sizeof( uint16 ) * 8 ) != true) return 0; 771 return (((uint16) uint16r[B16_1])<<8)|((uint16)uint16r[B16_0]); 772 #endif 773 } 774 775 int16 BitStream::ReadInt16() 776 { 777 #ifdef TYPE_CHECKING 778 unsigned char ID; 779 780 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 781 return 0; 782 783 assert( ID == 4 ); 784 return ID; 785 #endif 786 unsigned char int16r[2]; 787 #ifdef __BITSTREAM_NATIVE_END 788 if(ReadBits( int16r, sizeof( int16_t ) * 8 )){ 789 return *(int16_t*)int16r; 790 } 791 return 0; 792 #else 793 if (ReadBits( int16r, sizeof( int16 ) * 8 ) != true) return 0; 794 return (((int16) int16r[B16_1])<<8)|((int16)int16r[B16_0]); 795 #endif 796 } 797 798 uint32 BitStream::ReadUInt32() 799 { 800 #ifdef TYPE_CHECKING 801 unsigned char ID; 802 803 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 804 return 0; 805 806 assert( ID == 5 ); 807 return ID; 808 #endif 809 unsigned char uint32r[4]; 810 #ifdef __BITSTREAM_NATIVE_END 811 if(ReadBits( uint32r, sizeof( uint32_t ) * 8 )){ 812 return *(uint32_t*)uint32r; 813 } 814 return 0; 815 #else 816 if(ReadBits( uint32r, sizeof( uint32 ) * 8 ) != true) 817 return 0; 818 return (((uint32) uint32r[B32_3])<<24)| 819 (((uint32) uint32r[B32_2])<<16)| 820 (((uint32) uint32r[B32_1])<<8)| 821 ((uint32) uint32r[B32_0]); 822 #endif 823 } 824 825 int32 BitStream::ReadInt32() 826 { 827 #ifdef TYPE_CHECKING 828 unsigned char ID; 829 830 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 831 return 0; 832 833 assert( ID == 6 ); 834 return ID; 835 #endif 836 unsigned char int32r[4]; 837 #ifdef __BITSTREAM_NATIVE_END 838 if(ReadBits( int32r, sizeof( int32_t ) * 8 )){ 839 return *(int32_t*)int32r; 840 } 841 return 0; 842 #else 843 if(ReadBits( int32r, sizeof( int32 ) * 8 ) != true) 844 return 0; 845 return (((int32) int32r[B32_3])<<24)| 846 (((int32) int32r[B32_2])<<16)| 847 (((int32) int32r[B32_1])<<8)| 848 ((int32) int32r[B32_0]); 849 #endif 850 } 851 852 #ifdef HAS_INT64 853 uint64 BitStream::ReadUInt64() 854 { 855 #ifdef TYPE_CHECKING 856 unsigned char ID; 857 858 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 859 return 0; 860 861 assert( ID == 7 ); 862 return ID; 863 #endif 864 unsigned char uint64r[8]; 865 #ifdef __BITSTREAM_NATIVE_END 866 if(ReadBits( uint64r, sizeof( uint64_t ) * 8 )){ 867 return *(uint64_t*)uint64r; 868 } 869 return 0; 870 #else 871 if(ReadBits( uint64r, sizeof( uint64 ) * 8 ) != true) 872 return 0; 873 return (((uint64) uint64r[B64_7])<<56)|(((uint64) uint64r[B64_6])<<48)| 874 (((uint64) uint64r[B64_5])<<40)|(((uint64) uint64r[B64_4])<<32)| 875 (((uint64) uint64r[B64_3])<<24)|(((uint64) uint64r[B64_2])<<16)| 876 (((uint64) uint64r[B64_1])<<8)|((uint64) uint64r[B64_0]); 877 #endif 878 } 879 880 int64 BitStream::ReadInt64() 881 { 882 #ifdef TYPE_CHECKING 883 unsigned char ID; 884 885 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 886 return 0; 887 888 assert( ID == 8 ); 889 return ID; 890 #endif 891 unsigned char int64r[8]; 892 #ifdef __BITSTREAM_NATIVE_END 893 if(ReadBits(int64r, sizeof( int64_t ) * 8 )){ 894 return *(int64_t*)int64r; 895 } 896 return 0; 897 #else 898 if(ReadBits( int64r, sizeof( int64_t ) * 8 ) != true) 899 return 0; 900 return (((uint64) int64r[B64_7])<<56)|(((uint64) int64r[B64_6])<<48)| 901 (((uint64) int64r[B64_5])<<40)|(((uint64) int64r[B64_4])<<32)| 902 (((uint64) int64r[B64_3])<<24)|(((uint64) int64r[B64_2])<<16)| 903 (((uint64) int64r[B64_1])<<8)|((uint64) int64r[B64_0]); 904 #endif 905 } 906 #endif 907 908 float BitStream::ReadFloat() 909 { 910 #ifdef TYPE_CHECKING 911 unsigned char ID; 912 913 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 914 return 0; 915 916 assert( ID == 9 ); 917 return ID; 918 #endif 919 920 #ifdef __BITSTREAM_NATIVE_END 921 static float floatr; 922 if(ReadBits( ( unsigned char* ) & floatr, sizeof( floatr ) * 8 )){ 923 return floatr; 924 } 925 return 0; 926 #else 927 unsigned int val = ReadUInt32(); 928 return *((float *)(&val)); 929 #endif 930 } 931 932 double BitStream::ReadDouble() 933 { 934 #ifdef TYPE_CHECKING 935 unsigned char ID; 936 937 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 938 return 0; 939 940 assert( ID == 10 ); 941 return ID; 942 #endif 943 944 #if defined ( __BITSTREAM_NATIVE_END ) || ( ! defined ( HAS_INT64 ) ) 945 static double doubler; 946 if(ReadBits( ( unsigned char* ) & doubler, sizeof( doubler ) * 8 )){ 947 return doubler; 948 } 949 return 0; 950 #else 951 uint64_t val = ReadUInt64(); 952 return *((double *)(&val)); 953 #endif 954 } 955 // Read an array or casted stream 956 bool BitStream::ReadBytes( char* output, const int numberOfBytes ) 957 { 958 #ifdef TYPE_CHECKING 959 unsigned char ID; 960 961 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 962 return false; 963 964 assert( ID == 11 ); 965 966 int NOB; 967 968 ReadBits( ( unsigned char* ) & NOB, sizeof( int ) * 8 ); 969 970 assert( NOB == numberOfBytes ); 971 972 #endif 973 974 return ReadBits( ( unsigned char* ) output, numberOfBytes * 8 ); 975 } 976 977 bool BitStream::ReadStr(char output[], int size){ 978 unsigned short len = ReadUInt16(); 979 len = (len+1) > size?size:len; 980 if(len > 0){ 981 if(ReadBytes(output,len)){ 982 output[len] = '\0'; 983 return true; 984 } 985 } 986 return false; 987 } 988 989 std::string BitStream::ReadStr() 990 { 991 std::string strs ; 992 unsigned short len = ReadUInt16(); 993 994 if(len > 0){ 995 char* str = new char[len+1]; 996 if(ReadBytes(str,len)){ 997 str[len] = '\0'; 998 strs = str; 999 delete[] str; 1000 return strs; 1001 } 1002 } 1003 1004 1005 return std::string(); 1006 } 1007 1008 // Read the types you wrote with WriteCompressed 1009 uint8 BitStream::ReadCompUInt8() 1010 { 1011 #ifdef TYPE_CHECKING 1012 unsigned char ID; 1013 1014 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 1015 return 0; 1016 1017 assert( ID == 12 ); 1018 return ID; 1019 #endif 1020 uint8 uint8rc; 1021 if(ReadCompressed( ( unsigned char* ) & uint8rc, sizeof( uint8rc ) * 8, true )){ 1022 return uint8rc; 1023 } 1024 return 0; 1025 } 1026 1027 int8 BitStream::ReadCompInt8() 1028 { 1029 #ifdef TYPE_CHECKING 1030 unsigned char ID; 1031 1032 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 1033 return 0; 1034 1035 assert( ID == 13 ); 1036 return ID; 1037 #endif 1038 int8 int8rc; 1039 if(ReadCompressed( ( unsigned char* ) & int8rc, sizeof( int8rc ) * 8, false )){ 1040 return int8rc; 1041 } 1042 return 0; 1043 } 1044 1045 uint16 BitStream::ReadCompUInt16() 1046 { 1047 #ifdef TYPE_CHECKING 1048 unsigned char ID; 1049 1050 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 1051 return 0; 1052 1053 assert( ID == 14 ); 1054 return ID; 1055 #endif 1056 unsigned char uint16rc[2]; 1057 #ifdef __BITSTREAM_NATIVE_END 1058 if(ReadCompressed( uint16rc, sizeof( uint16_t ) * 8, true )){ 1059 return *(uint16_t*)uint16rc; 1060 } 1061 return 0; 1062 #else 1063 if (ReadCompressed( uint16rc, sizeof( uint16 ) * 8, true ) != true) return 0; 1064 return (((uint16) uint16rc[B16_1])<<8)| 1065 ((uint16) uint16rc[B16_0]); 1066 #endif 1067 } 1068 1069 int16 BitStream::ReadCompInt16() 1070 { 1071 #ifdef TYPE_CHECKING 1072 unsigned char ID; 1073 1074 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 1075 return 0; 1076 1077 assert( ID == 15 ); 1078 return ID; 1079 #endif 1080 unsigned char int16rc[2]; 1081 #ifdef __BITSTREAM_NATIVE_END 1082 if(ReadCompressed( int16rc, sizeof( int16_t ) * 8, true )){ 1083 return *(int16_t*)int16rc; 1084 } 1085 return 0; 1086 #else 1087 if (ReadCompressed( int16rc, sizeof( int16 ) * 8, false ) != true) return 0; 1088 return (((uint16) int16rc[B16_1])<<8)|((uint16)int16rc[B16_0]); 1089 #endif 1090 } 1091 1092 uint32 BitStream::ReadCompUInt32() 1093 { 1094 #ifdef TYPE_CHECKING 1095 unsigned char ID; 1096 1097 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 1098 return 0; 1099 1100 assert( ID == 16 ); 1101 return ID; 1102 1103 #endif 1104 unsigned char uint32rc[4]; 1105 #ifdef __BITSTREAM_NATIVE_END 1106 if(ReadCompressed( uint32rc, sizeof( uint32_t ) * 8, true )){ 1107 return *(uint32_t*)uint32rc; 1108 } 1109 return 0; 1110 #else 1111 if(ReadCompressed( uint32rc, sizeof( uint32 ) * 8, true ) != true) 1112 return 0; 1113 return (((uint32) uint32rc[B32_3])<<24)| 1114 (((uint32) uint32rc[B32_2])<<16)| 1115 (((uint32) uint32rc[B32_1])<<8)| 1116 ((uint32) uint32rc[B32_0]); 1117 #endif 1118 } 1119 1120 int32 BitStream::ReadCompInt32() 1121 { 1122 #ifdef TYPE_CHECKING 1123 unsigned char ID; 1124 1125 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 1126 return 0; 1127 1128 assert( ID == 17 ); 1129 return ID; 1130 #endif 1131 1132 unsigned char int32rc[4]; 1133 #ifdef __BITSTREAM_NATIVE_END 1134 if(ReadCompressed(int32rc, sizeof( int32_t ) * 8, true )){ 1135 return *(int32_t*)int32rc; 1136 } 1137 return 0; 1138 #else 1139 if(ReadCompressed( int32rc, sizeof( int32 ) * 8, false ) != true) 1140 return 0; 1141 return (((uint32) int32rc[B32_3])<<24)| 1142 (((uint32) int32rc[B32_2])<<16)| 1143 (((uint32) int32rc[B32_1])<<8)| 1144 ((uint32) int32rc[B32_0]); 1145 1146 #endif 1147 } 1148 1149 #ifdef HAS_INT64 1150 uint64_t BitStream::ReadCompUInt64() 1151 { 1152 #ifdef TYPE_CHECKING 1153 unsigned char ID; 1154 1155 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 1156 return 0; 1157 1158 assert( ID == 18 ); 1159 return ID; 1160 #endif 1161 1162 unsigned char uint64rc[8]; 1163 #ifdef __BITSTREAM_NATIVE_END 1164 if(ReadCompressed( uint64rc, sizeof( uint64_t ) * 8, true )){ 1165 return *(uint64_t*)uint64rc; 1166 } 1167 return 0; 1168 #else 1169 if(ReadCompressed( uint64rc, sizeof( uint64_t ) * 8, true ) != true) 1170 return 0; 1171 return (((uint64_t) uint64rc[B64_7])<<56)|(((uint64_t) uint64rc[B64_6])<<48)| 1172 (((uint64_t) uint64rc[B64_5])<<40)|(((uint64_t) uint64rc[B64_4])<<32)| 1173 (((uint64_t) uint64rc[B64_3])<<24)|(((uint64_t) uint64rc[B64_2])<<16)| 1174 (((uint64_t) uint64rc[B64_1])<<8)|((uint64_t) uint64rc[B64_0]); 1175 #endif 1176 } 1177 1178 int64_t BitStream::ReadCompInt64() 1179 { 1180 #ifdef TYPE_CHECKING 1181 unsigned char ID; 1182 1183 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 1184 return 0; 1185 1186 assert( ID == 19 ); 1187 return ID; 1188 #endif 1189 unsigned char int64rc[8]; 1190 #ifdef __BITSTREAM_NATIVE_END 1191 if(ReadCompressed( int64rc, sizeof( int64_t ) * 8, true )){ 1192 return *(int64_t*)int64rc; 1193 } 1194 return 0; 1195 #else 1196 if(ReadCompressed( int64rc, sizeof( int64_t ) * 8, false ) != true) 1197 return 0; 1198 return (((uint64_t) int64rc[B64_7])<<56)|(((uint64_t) int64rc[B64_6])<<48)| 1199 (((uint64_t) int64rc[B64_5])<<40)|(((uint64_t) int64rc[B64_4])<<32)| 1200 (((uint64_t) int64rc[B64_3])<<24)|(((uint64_t) int64rc[B64_2])<<16)| 1201 (((uint64_t) int64rc[B64_1])<<8)|((uint64_t) int64rc[B64_0]); 1202 #endif 1203 } 1204 #endif 1205 1206 float BitStream::ReadCompFloat() 1207 { 1208 #ifdef TYPE_CHECKING 1209 unsigned char ID; 1210 1211 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 1212 return 0; 1213 1214 assert( ID == 20 ); 1215 return ID; 1216 #endif 1217 1218 return ReadFloat(); 1219 } 1220 1221 double BitStream::ReadCompDouble() 1222 { 1223 #ifdef TYPE_CHECKING 1224 unsigned char ID; 1225 1226 if ( ReadBits( ( unsigned char* ) & ID, sizeof(unsigned char) * 8 ) == false ) 1227 return 0; 1228 1229 assert( ID == 21 ); 1230 return ID; 1231 #endif 1232 1233 return ReadDouble(); 1234 } 1235 1236 bool BitStream::ReadNormVector( float &x, float &y, float &z ) 1237 { 1238 unsigned short sy, sz; 1239 1240 bool xNeg = ReadBool(); 1241 1242 bool yZero = ReadBool(); 1243 if (yZero) 1244 y=0.0f; 1245 else 1246 { 1247 sy = ReadUInt16(); 1248 y=((float)sy / 32767.5f - 1.0f); 1249 } 1250 1251 bool zZero = ReadBool(); 1252 if (zZero) 1253 z=0.0f; 1254 else 1255 { 1256 sz = ReadUInt16(); 1257 1258 z=((float)sz / 32767.5f - 1.0f); 1259 } 1260 1261 x = sqrtf(1.0f - y*y - z*z); 1262 if (xNeg) 1263 x=-x; 1264 return true; 1265 } 1266 bool BitStream::ReadVector( float &x, float &y, float &z ) 1267 { 1268 unsigned short sx,sy,sz; 1269 1270 float magnitude = ReadFloat(); 1271 1272 if (magnitude!=0.0f) 1273 { 1274 sx = ReadUInt16(); 1275 sy = ReadUInt16(); 1276 sz = ReadUInt16(); 1277 1278 x=((float)sx / 32767.5f - 1.0f) * magnitude; 1279 y=((float)sy / 32767.5f - 1.0f) * magnitude; 1280 z=((float)sz / 32767.5f - 1.0f) * magnitude; 1281 } 1282 else 1283 { 1284 x=0.0f; 1285 y=0.0f; 1286 z=0.0f; 1287 } 1288 return true; 1289 } 1290 bool BitStream::ReadNormQuat( float &w, float &x, float &y, float &z) 1291 { 1292 bool cwNeg = ReadBool(); 1293 bool cxNeg = ReadBool(); 1294 bool cyNeg = ReadBool(); 1295 bool czNeg = ReadBool(); 1296 unsigned short cx = ReadUInt16(); 1297 unsigned short cy = ReadUInt16(); 1298 unsigned short cz = ReadUInt16(); 1299 1300 // Calculate w from x,y,z 1301 x=cx/65535.0f; 1302 y=cy/65535.0f; 1303 z=cz/65535.0f; 1304 if (cxNeg) x=-x; 1305 if (cyNeg) y=-y; 1306 if (czNeg) z=-z; 1307 w = sqrt(1.0f - x*x - y*y - z*z); 1308 if (cwNeg) 1309 w=-w; 1310 return true; 1311 } 1312 bool BitStream::ReadOrthMatrix( 1313 float &m00, float &m01, float &m02, 1314 float &m10, float &m11, float &m12, 1315 float &m20, float &m21, float &m22 ) 1316 { 1317 float qw,qx,qy,qz; 1318 if (!ReadNormQuat(qw,qx,qy,qz)) 1319 return false; 1320 1321 // Quat to orthogonal rotation matrix 1322 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm 1323 double sqw = (double)qw*(double)qw; 1324 double sqx = (double)qx*(double)qx; 1325 double sqy = (double)qy*(double)qy; 1326 double sqz = (double)qz*(double)qz; 1327 m00 = (float)(sqx - sqy - sqz + sqw); // since sqw + sqx + sqy + sqz =1 1328 m11 = (float)(-sqx + sqy - sqz + sqw); 1329 m22 = (float)(-sqx - sqy + sqz + sqw); 1330 1331 double tmp1 = (double)qx*(double)qy; 1332 double tmp2 = (double)qz*(double)qw; 1333 m10 = (float)(2.0 * (tmp1 + tmp2)); 1334 m01 = (float)(2.0 * (tmp1 - tmp2)); 1335 1336 tmp1 = (double)qx*(double)qz; 1337 tmp2 = (double)qy*(double)qw; 1338 m20 =(float)(2.0 * (tmp1 - tmp2)); 1339 m02 = (float)(2.0 * (tmp1 + tmp2)); 1340 tmp1 = (double)qy*(double)qz; 1341 tmp2 = (double)qx*(double)qw; 1342 m21 = (float)(2.0 * (tmp1 + tmp2)); 1343 m12 = (float)(2.0 * (tmp1 - tmp2)); 1344 1345 return true; 1346 } 1347 1348 // Sets the read pointer back to the beginning of your data. 1349 void BitStream::ResetReadPointer( void ) 1350 { 1351 readOffset = 0; 1352 } 1353 1354 // Sets the write pointer back to the beginning of your data. 1355 void BitStream::ResetWritePointer( void ) 1356 { 1357 numberOfBitsUsed = 0; 1358 } 1359 1360 // Write a 0 1361 void BitStream::Write0( void ) 1362 { 1363 AddBitsAndReallocate( 1 ); 1364 1365 // New bytes need to be zeroed 1366 1367 if ( ( numberOfBitsUsed % 8 ) == 0 ) 1368 data[ numberOfBitsUsed >> 3 ] = 0; 1369 1370 numberOfBitsUsed++; 1371 } 1372 1373 // Write a 1 1374 void BitStream::Write1( void ) 1375 { 1376 AddBitsAndReallocate( 1 ); 1377 1378 int numberOfBitsMod8 = numberOfBitsUsed % 8; 1379 1380 if ( numberOfBitsMod8 == 0 ) 1381 data[ numberOfBitsUsed >> 3 ] = 0x80; 1382 else 1383 data[ numberOfBitsUsed >> 3 ] |= 0x80 >> ( numberOfBitsMod8 ); // Set the bit to 1 1384 1385 numberOfBitsUsed++; 1386 } 1387 1388 // Returns true if the next data read is a 1, false if it is a 0 1389 bool BitStream::ReadBit( void ) 1390 { 1391 #pragma warning( disable : 4800 ) 1392 return ( bool ) ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset++ % 8 ) ) ); 1393 #pragma warning( default : 4800 ) 1394 } 1395 1396 // Align the bitstream to the byte boundary and then write the specified number of bits. 1397 // This is faster than WriteBits but wastes the bits to do the alignment and requires you to call 1398 // SetReadToByteAlignment at the corresponding read position 1399 void BitStream::WriteAlignedBytes( const unsigned char* input, 1400 const int numberOfBytesToWrite ) 1401 { 1402 #ifdef _DEBUG 1403 assert( numberOfBytesToWrite > 0 ); 1404 #endif 1405 1406 AlignWriteToByteBoundary(); 1407 // Allocate enough memory to hold everything 1408 AddBitsAndReallocate( numberOfBytesToWrite << 3 ); 1409 1410 // Write the data 1411 memcpy( data + ( numberOfBitsUsed >> 3 ), input, numberOfBytesToWrite ); 1412 1413 numberOfBitsUsed += numberOfBytesToWrite << 3; 1414 } 1415 1416 // Read bits, starting at the next aligned bits. Note that the modulus 8 starting offset of the 1417 // sequence must be the same as was used with WriteBits. This will be a problem with packet coalescence 1418 // unless you byte align the coalesced packets. 1419 bool BitStream::ReadAlignedBytes( unsigned char* output, 1420 const int numberOfBytesToRead ) 1421 { 1422 #ifdef _DEBUG 1423 assert( numberOfBytesToRead > 0 ); 1424 #endif 1425 1426 if ( numberOfBytesToRead <= 0 ) 1427 return false; 1428 1429 // Byte align 1430 AlignReadToByteBoundary(); 1431 1432 if ( readOffset + ( numberOfBytesToRead << 3 ) > numberOfBitsUsed ) 1433 return false; 1434 1435 // Write the data 1436 memcpy( output, data + ( readOffset >> 3 ), numberOfBytesToRead ); 1437 1438 readOffset += numberOfBytesToRead << 3; 1439 1440 return true; 1441 } 1442 1443 // Align the next write and/or read to a byte boundary. This can be used to 'waste' bits to byte align for efficiency reasons 1444 void BitStream::AlignWriteToByteBoundary( void ) 1445 { 1446 if ( numberOfBitsUsed ) 1447 numberOfBitsUsed += 8 - ( ( numberOfBitsUsed - 1 ) % 8 + 1 ); 1448 } 1449 1450 // Align the next write and/or read to a byte boundary. This can be used to 'waste' bits to byte align for efficiency reasons 1451 void BitStream::AlignReadToByteBoundary( void ) 1452 { 1453 if ( readOffset ) 1454 readOffset += 8 - ( ( readOffset - 1 ) % 8 + 1 ); 1455 } 1456 1457 // Write numberToWrite bits from the input source 1458 void BitStream::WriteBits( const unsigned char *input, 1459 int numberOfBitsToWrite, const bool rightAlignedBits ) 1460 { 1461 // if (numberOfBitsToWrite<=0) 1462 // return; 1463 1464 AddBitsAndReallocate( numberOfBitsToWrite ); 1465 int offset = 0; 1466 unsigned char dataByte; 1467 int numberOfBitsUsedMod8; 1468 1469 numberOfBitsUsedMod8 = numberOfBitsUsed % 8; 1470 1471 // Faster to put the while at the top surprisingly enough 1472 while ( numberOfBitsToWrite > 0 ) 1473 //do 1474 { 1475 dataByte = *( input + offset ); 1476 1477 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) 1478 dataByte <<= 8 - numberOfBitsToWrite; // shift left to get the bits on the left, as in our internal representation 1479 1480 // Writing to a new byte each time 1481 if ( numberOfBitsUsedMod8 == 0 ) 1482 * ( data + ( numberOfBitsUsed >> 3 ) ) = dataByte; 1483 else 1484 { 1485 // Copy over the new data. 1486 *( data + ( numberOfBitsUsed >> 3 ) ) |= dataByte >> ( numberOfBitsUsedMod8 ); // First half 1487 1488 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) 1489 { 1490 *( data + ( numberOfBitsUsed >> 3 ) + 1 ) = (unsigned char) ( dataByte << ( 8 - ( numberOfBitsUsedMod8 ) ) ); // Second half (overlaps byte boundary) 1491 } 1492 } 1493 1494 if ( numberOfBitsToWrite >= 8 ) 1495 numberOfBitsUsed += 8; 1496 else 1497 numberOfBitsUsed += numberOfBitsToWrite; 1498 1499 numberOfBitsToWrite -= 8; 1500 1501 offset++; 1502 } 1503 // } while(numberOfBitsToWrite>0); 1504 } 1505 1506 // Set the stream to some initial data. For internal use 1507 void BitStream::SetData( const unsigned char* input, const int numberOfBits ) 1508 { 1509 #ifdef _DEBUG 1510 assert( numberOfBitsUsed == 0 ); // Make sure the stream is clear 1511 #endif 1512 1513 if ( numberOfBits <= 0 ) 1514 return ; 1515 1516 AddBitsAndReallocate( numberOfBits ); 1517 1518 memcpy( data, input, BITS_TO_BYTES( numberOfBits ) ); 1519 1520 numberOfBitsUsed = numberOfBits; 1521 } 1522 1523 // Assume the input source points to a native type, compress and write it 1524 void BitStream::WriteCompressed( const unsigned char* input, 1525 const int size, const bool unsignedData ) 1526 { 1527 int currentByte = ( size >> 3 ) - 1; // PCs 1528 1529 unsigned char byteMatch; 1530 1531 if ( unsignedData ) 1532 { 1533 byteMatch = 0; 1534 } 1535 1536 else 1537 { 1538 byteMatch = 0xFF; 1539 } 1540 1541 // Write upper bytes with a single 1 1542 // 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 1543 while ( currentByte > 0 ) 1544 { 1545 if ( input[ currentByte ] == byteMatch ) // If high byte is byteMatch (0 of 0xff) then it would have the same value shifted 1546 { 1547 bool b = true; 1548 WriteBool( b ); 1549 } 1550 else 1551 { 1552 // Write the remainder of the data after writing 0 1553 bool b = false; 1554 WriteBool( b ); 1555 1556 WriteBits( input, ( currentByte + 1 ) << 3, true ); 1557 // currentByte--; 1558 1559 1560 return ; 1561 } 1562 1563 currentByte--; 1564 } 1565 1566 // 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. 1567 if ( ( unsignedData && ( ( *( input + currentByte ) ) & 0xF0 ) == 0x00 ) || 1568 ( unsignedData == false && ( ( *( input + currentByte ) ) & 0xF0 ) == 0xF0 ) ) 1569 { 1570 bool b = true; 1571 WriteBool( b ); 1572 WriteBits( input + currentByte, 4, true ); 1573 } 1574 1575 else 1576 { 1577 bool b = false; 1578 WriteBool( b ); 1579 WriteBits( input + currentByte, 8, true ); 1580 } 1581 } 1582 1583 // Read numberOfBitsToRead bits to the output source 1584 // alignBitsToRight should be set to true to convert internal bitstream data to userdata 1585 // It should be false if you used WriteBits with rightAlignedBits false 1586 bool BitStream::ReadBits( unsigned char* output, 1587 int numberOfBitsToRead, const bool alignBitsToRight ) 1588 { 1589 #ifdef _DEBUG 1590 assert( numberOfBitsToRead > 0 ); 1591 #endif 1592 // if (numberOfBitsToRead<=0) 1593 // return false; 1594 1595 if ( readOffset + numberOfBitsToRead > numberOfBitsUsed ) 1596 return false; 1597 1598 int readOffsetMod8; 1599 1600 int offset = 0; 1601 1602 memset( output, 0, BITS_TO_BYTES( numberOfBitsToRead ) ); 1603 1604 readOffsetMod8 = readOffset % 8; 1605 1606 // do 1607 // Faster to put the while at the top surprisingly enough 1608 while ( numberOfBitsToRead > 0 ) 1609 { 1610 *( output + offset ) |= *( data + ( readOffset >> 3 ) ) << ( readOffsetMod8 ); // First half 1611 1612 if ( readOffsetMod8 > 0 && numberOfBitsToRead > 8 - ( readOffsetMod8 ) ) // If we have a second half, we didn't read enough bytes in the first half 1613 *( output + offset ) |= *( data + ( readOffset >> 3 ) + 1 ) >> ( 8 - ( readOffsetMod8 ) ); // Second half (overlaps byte boundary) 1614 1615 numberOfBitsToRead -= 8; 1616 1617 if ( numberOfBitsToRead < 0 ) // Reading a partial byte for the last byte, shift right so the data is aligned on the right 1618 { 1619 1620 if ( alignBitsToRight ) 1621 * ( output + offset ) >>= -numberOfBitsToRead; 1622 1623 readOffset += 8 + numberOfBitsToRead; 1624 } 1625 else 1626 readOffset += 8; 1627 1628 offset++; 1629 1630 } 1631 1632 //} while(numberOfBitsToRead>0); 1633 1634 return true; 1635 } 1636 1637 // Assume the input source points to a compressed native type. Decompress and read it 1638 bool BitStream::ReadCompressed( unsigned char* output, 1639 const int size, const bool unsignedData ) 1640 { 1641 int currentByte = ( size >> 3 ) - 1; 1642 1643 1644 unsigned char byteMatch, halfByteMatch; 1645 1646 if ( unsignedData ) 1647 { 1648 byteMatch = 0; 1649 halfByteMatch = 0; 1650 } 1651 1652 else 1653 { 1654 byteMatch = 0xFF; 1655 halfByteMatch = 0xF0; 1656 } 1657 1658 // Upper bytes are specified with a single 1 if they match byteMatch 1659 // 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 1660 while ( currentByte > 0 ) 1661 { 1662 // If we read a 1 then the data is byteMatch. 1663 1664 bool b = ReadBool(); 1665 1666 if ( b ) // Check that bit 1667 { 1668 output[ currentByte ] = byteMatch; 1669 currentByte--; 1670 } 1671 else 1672 { 1673 // Read the rest of the bytes 1674 1675 if ( ReadBits( output, ( currentByte + 1 ) << 3 ) == false ) 1676 return false; 1677 1678 return true; 1679 } 1680 } 1681 1682 // 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. 1683 // Otherwise we read a 0 and the 8 bytes 1684 //assert(readOffset+1 <=numberOfBitsUsed); // If this assert is hit the stream wasn't long enough to read from 1685 if ( readOffset + 1 > numberOfBitsUsed ) 1686 return false; 1687 1688 bool b = ReadBool(); 1689 1690 if ( b ) // Check that bit 1691 { 1692 1693 if ( ReadBits( output + currentByte, 4 ) == false ) 1694 return false; 1695 1696 output[ currentByte ] |= halfByteMatch; // We have to set the high 4 bits since these are set to 0 by ReadBits 1697 } 1698 else 1699 { 1700 if ( ReadBits( output + currentByte, 8 ) == false ) 1701 return false; 1702 } 1703 1704 return true; 1705 } 1706 1707 // Reallocates (if necessary) in preparation of writing numberOfBitsToWrite 1708 void BitStream::AddBitsAndReallocate( const int numberOfBitsToWrite ) 1709 { 1710 if ( numberOfBitsToWrite <= 0 ) 1711 return; 1712 1713 int newNumberOfBitsAllocated = numberOfBitsToWrite + numberOfBitsUsed; 1714 1715 if ( numberOfBitsToWrite + numberOfBitsUsed > 0 && ( ( numberOfBitsAllocated - 1 ) >> 3 ) < ( ( newNumberOfBitsAllocated - 1 ) >> 3 ) ) // If we need to allocate 1 or more new bytes 1716 { 1717 #ifdef _DEBUG 1718 // If this assert hits then we need to specify true for the third parameter in the constructor 1719 // It needs to reallocate to hold all the data and can't do it unless we allocated to begin with 1720 assert( copyData == true ); 1721 #endif 1722 1723 // Less memory efficient but saves on news and deletes 1724 newNumberOfBitsAllocated = ( numberOfBitsToWrite + numberOfBitsUsed ) * 2; 1725 // int newByteOffset = BITS_TO_BYTES( numberOfBitsAllocated ); 1726 // Use realloc and free so we are more efficient than delete and new for resizing 1727 int amountToAllocate = BITS_TO_BYTES( newNumberOfBitsAllocated ); 1728 if (data==(unsigned char*)stackData) 1729 { 1730 if (amountToAllocate > BITSTREAM_STACK_ALLOCATION_SIZE) 1731 { 1732 data = ( unsigned char* ) malloc( amountToAllocate ); 1733 1734 // need to copy the stack data over to our new memory area too 1735 memcpy ((void *)data, (void *)stackData, BITS_TO_BYTES( numberOfBitsAllocated )); 1736 } 1737 } 1738 else 1739 { 1740 data = ( unsigned char* ) realloc( data, amountToAllocate ); 1741 } 1742 1743 #ifdef _DEBUG 1744 assert( data ); // Make sure realloc succeeded 1745 #endif 1746 // memset(data+newByteOffset, 0, ((newNumberOfBitsAllocated-1)>>3) - ((numberOfBitsAllocated-1)>>3)); // Set the new data block to 0 1747 } 1748 1749 if ( newNumberOfBitsAllocated > numberOfBitsAllocated ) 1750 numberOfBitsAllocated = newNumberOfBitsAllocated; 1751 } 1752 1753 // Should hit if reads didn't match writes 1754 void BitStream::AssertStreamEmpty( void ) 1755 { 1756 assert( readOffset == numberOfBitsUsed ); 1757 } 1758 1759 void BitStream::PrintBits( void ) const 1760 { 1761 if ( numberOfBitsUsed <= 0 ) 1762 { 1763 // printf( "No bits\n" ); 1764 return ; 1765 } 1766 1767 for ( int counter = 0; counter < BITS_TO_BYTES( numberOfBitsUsed ); counter++ ) 1768 { 1769 int stop; 1770 1771 if ( counter == ( numberOfBitsUsed - 1 ) >> 3 ) 1772 stop = 8 - ( ( ( numberOfBitsUsed - 1 ) % 8 ) + 1 ); 1773 else 1774 stop = 0; 1775 1776 for ( int counter2 = 7; counter2 >= stop; counter2-- ) 1777 { 1778 if ( ( data[ counter ] >> counter2 ) & 1 ) 1779 putchar( '1' ); 1780 else 1781 putchar( '0' ); 1782 } 1783 1784 putchar( ' ' ); 1785 } 1786 1787 putchar( '\n' ); 1788 } 1789 1790 1791 // Exposes the data for you to look at, like PrintBits does. 1792 // Data will point to the stream. Returns the length in bits of the stream. 1793 int BitStream::CopyData( unsigned char** _data ) const 1794 { 1795 #ifdef _DEBUG 1796 assert( numberOfBitsUsed > 0 ); 1797 #endif 1798 1799 *_data = new unsigned char [ BITS_TO_BYTES( numberOfBitsUsed ) ]; 1800 memcpy( *_data, data, sizeof(unsigned char) * ( BITS_TO_BYTES( numberOfBitsUsed ) ) ); 1801 return numberOfBitsUsed; 1802 } 1803 1804 // Ignore data we don't intend to read 1805 void BitStream::IgnoreBits( const int numberOfBits ) 1806 { 1807 readOffset += numberOfBits; 1808 } 1809 1810 // Move the write pointer to a position on the array. Dangerous if you don't know what you are doing! 1811 void BitStream::SetWriteOffset( const int offset ) 1812 { 1813 numberOfBitsUsed = offset; 1814 } 1815 1816 // Returns the length in bits of the stream 1817 int BitStream::GetWriteOffset( void ) const 1818 { 1819 return numberOfBitsUsed; 1820 } 1821 1822 // Returns the length in bytes of the stream 1823 int BitStream::GetNumberOfBytesUsed( void ) const 1824 { 1825 return BITS_TO_BYTES( numberOfBitsUsed ); 1826 } 1827 int BitStream::GetNumberOfBytesRead(void)const 1828 { 1829 return BITS_TO_BYTES(readOffset); 1830 } 1831 1832 // Move the read pointer to a position on the array. 1833 void BitStream::SetReadOffset( const int offset ) 1834 { 1835 readOffset = offset; 1836 } 1837 void BitStream::SetByteReadOffSet(const int offset) 1838 { 1839 readOffset = BYTES_TO_BITS(offset); 1840 } 1841 // Returns the number of bits into the stream that we have read 1842 int BitStream::GetReadOffset( void ) const 1843 { 1844 return readOffset; 1845 } 1846 1847 // Returns the number of bits left in the stream that haven't been read 1848 int BitStream::GetNumberOfUnreadBits( void ) const 1849 { 1850 return numberOfBitsUsed - readOffset; 1851 } 1852 1853 // Exposes the internal data 1854 unsigned char* BitStream::GetData( void ) const 1855 { 1856 return data; 1857 } 1858 1859 // 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. 1860 void BitStream::AssertCopyData( void ) 1861 { 1862 if ( copyData == false ) 1863 { 1864 copyData = true; 1865 1866 if ( numberOfBitsAllocated > 0 ) 1867 { 1868 unsigned char * newdata = ( unsigned char* ) malloc( BITS_TO_BYTES( numberOfBitsAllocated ) ); 1869 #ifdef _DEBUG 1870 1871 assert( data ); 1872 #endif 1873 1874 memcpy( newdata, data, BITS_TO_BYTES( numberOfBitsAllocated ) ); 1875 data = newdata; 1876 } 1877 1878 else 1879 data = 0; 1880 } 1881 }