• 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 /** 
    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] = '';
     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] = '';
     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
    " );
    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( '
    ' );
    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 }
  • 相关阅读:
    WinFrom 经典登录窗体(转)
    .Net 反射牛刀小试
    WCF和Entity framework 发现的性能问题(转)
    扩展方法(C# 编程指南)
    如何把Access中数据导入Mysql中 (转)
    MD5 Message Digest
    .Net 集合排序
    test
    如何使自己的程序只运行一次(转)
    WCF传较大数据(转)
  • 原文地址:https://www.cnblogs.com/ishowfun/p/4026819.html
Copyright © 2020-2023  润新知