从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 /** ote 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] = '