00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #if defined(_MSC_VER) && _MSC_VER < 1299 // VC6 doesn't support template specialization
00011 #include "BitStream_NoTemplate.h"
00012 #else
00013
00014 #ifndef __BITSTREAM_H
00015 #define __BITSTREAM_H
00016
00017 #include "RakMemoryOverride.h"
00018 #include "RakNetDefines.h"
00019 #include "Export.h"
00020 #include "RakNetTypes.h"
00021 #include "RakString.h"
00022 #include "RakAssert.h"
00023 #include <math.h>
00024 #include <float.h>
00025
00026 #ifdef _MSC_VER
00027 #pragma warning( push )
00028 #endif
00029
00030
00031 #ifndef _WIN32
00032 #define _copysign copysign
00033 #endif
00034
00037 namespace RakNet
00038 {
00041 class RAK_DLL_EXPORT BitStream
00042 {
00043
00044 public:
00046 BitStream();
00047
00052 BitStream( const unsigned int initialBytesToAllocate );
00053
00064 BitStream( unsigned char* _data, const unsigned int lengthInBytes, bool _copyData );
00065
00066
00067 ~BitStream();
00068
00070 void Reset( void );
00071
00077 template <class templateType>
00078 bool Serialize(bool writeToBitstream, templateType &inOutTemplateVar);
00079
00087 template <class templateType>
00088 bool SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue, templateType lastValue);
00089
00094 template <class templateType>
00095 bool SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue);
00096
00105 template <class templateType>
00106 bool SerializeCompressed(bool writeToBitstream, templateType &inOutTemplateVar);
00107
00118 template <class templateType>
00119 bool SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue, templateType lastValue);
00120
00123 template <class templateType>
00124 bool SerializeCompressedDelta(bool writeToBitstream, templateType &inOutTemplateVar);
00125
00131 bool Serialize(bool writeToBitstream, char* inOutByteArray, const unsigned int numberOfBytes );
00132
00138 bool SerializeFloat16(bool writeToBitstream, float &inOutFloat, float floatMin, float floatMax);
00139
00145 template <class serializationType, class sourceType >
00146 bool SerializeCasted( bool writeToBitstream, sourceType &value );
00147
00156 template <class templateType, class rangeType>
00157 bool SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange=false );
00159 template <class templateType, class rangeType>
00160 bool SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange=false );
00161
00170 template <class templateType>
00171 bool SerializeNormVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z );
00172
00180 template <class templateType>
00181 bool SerializeVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z );
00182
00190 template <class templateType>
00191 bool SerializeNormQuat(bool writeToBitstream, templateType &w, templateType &x, templateType &y, templateType &z);
00192
00197 template <class templateType>
00198 bool SerializeOrthMatrix(
00199 bool writeToBitstream,
00200 templateType &m00, templateType &m01, templateType &m02,
00201 templateType &m10, templateType &m11, templateType &m12,
00202 templateType &m20, templateType &m21, templateType &m22 );
00203
00215 bool SerializeBits(bool writeToBitstream, unsigned char* inOutByteArray, const BitSize_t numberOfBitsToSerialize, const bool rightAlignedBits = true );
00216
00220
00221 template <class templateType>
00222 void Write(templateType inTemplateVar);
00223 template <class templateType>
00224 void WriteRef(const templateType &inTemplateVar);
00225
00229 template <class templateType>
00230 void WritePtr(templateType *inTemplateVar);
00231
00237 template <class templateType>
00238 void WriteDelta(templateType currentValue, templateType lastValue);
00239
00242 template <class templateType>
00243 void WriteDelta(templateType currentValue);
00244
00251 template <class templateType>
00252 void WriteCompressed(templateType inTemplateVar);
00253
00262 template <class templateType>
00263 void WriteCompressedDelta(templateType currentValue, templateType lastValue);
00264
00266 template <class templateType>
00267 void WriteCompressedDelta(templateType currentValue);
00268
00273 template <class templateType>
00274 bool Read(templateType &outTemplateVar);
00275
00280 template <class templateType>
00281 bool ReadPtr(templateType *outTemplateVar);
00282
00289 template <class templateType>
00290 bool ReadDelta(templateType &outTemplateVar);
00291
00299 template <class templateType>
00300 bool ReadCompressed(templateType &outTemplateVar);
00301
00312 template <class templateType>
00313 bool ReadCompressedDelta(templateType &outTemplateVar);
00314
00319 bool Read( BitStream *bitStream, BitSize_t numberOfBits );
00320 bool Read( BitStream *bitStream );
00321 bool Read( BitStream &bitStream, BitSize_t numberOfBits );
00322 bool Read( BitStream &bitStream );
00323
00327 void Write( const char* inputByteArray, const unsigned int numberOfBytes );
00328
00332 void Write( BitStream *bitStream, BitSize_t numberOfBits );
00333 void Write( BitStream *bitStream );
00334 void Write( BitStream &bitStream, BitSize_t numberOfBits );
00335 void Write( BitStream &bitStream );\
00336
00341 void WriteFloat16( float x, float floatMin, float floatMax );
00342
00347 template <class serializationType, class sourceType >
00348 void WriteCasted( const sourceType &value );
00349
00357 template <class templateType, class rangeType>
00358 void WriteBitsFromIntegerRange( const templateType value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange=false );
00360 template <class templateType, class rangeType>
00361 void WriteBitsFromIntegerRange( const templateType value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange=false );
00362
00369 template <class templateType>
00370 void WriteNormVector( templateType x, templateType y, templateType z );
00371
00378 template <class templateType>
00379 void WriteVector( templateType x, templateType y, templateType z );
00380
00386 template <class templateType>
00387 void WriteNormQuat( templateType w, templateType x, templateType y, templateType z);
00388
00392 template <class templateType>
00393 void WriteOrthMatrix(
00394 templateType m00, templateType m01, templateType m02,
00395 templateType m10, templateType m11, templateType m12,
00396 templateType m20, templateType m21, templateType m22 );
00397
00403 bool Read( char* output, const unsigned int numberOfBytes );
00404
00409 bool ReadFloat16( float &outFloat, float floatMin, float floatMax );
00410
00415 template <class serializationType, class sourceType >
00416 bool ReadCasted( sourceType &value );
00417
00425 template <class templateType, class rangeType>
00426 bool ReadBitsFromIntegerRange( templateType &value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange=false );
00428 template <class templateType, class rangeType>
00429 bool ReadBitsFromIntegerRange( templateType &value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange=false );
00430
00438 template <class templateType>
00439 bool ReadNormVector( templateType &x, templateType &y, templateType &z );
00440
00448 template <class templateType>
00449 bool ReadVector( templateType &x, templateType &y, templateType &z );
00450
00457 template <class templateType>
00458 bool ReadNormQuat( templateType &w, templateType &x, templateType &y, templateType &z);
00459
00464 template <class templateType>
00465 bool ReadOrthMatrix(
00466 templateType &m00, templateType &m01, templateType &m02,
00467 templateType &m10, templateType &m11, templateType &m12,
00468 templateType &m20, templateType &m21, templateType &m22 );
00469
00471 void ResetReadPointer( void );
00472
00474 void ResetWritePointer( void );
00475
00478 void AssertStreamEmpty( void );
00479
00481 void PrintBits( char *out ) const;
00482 void PrintBits( void ) const;
00483 void PrintHex( char *out ) const;
00484 void PrintHex( void ) const;
00485
00488 void IgnoreBits( const BitSize_t numberOfBits );
00489
00492 void IgnoreBytes( const unsigned int numberOfBytes );
00493
00499 void SetWriteOffset( const BitSize_t offset );
00500
00502 inline BitSize_t GetNumberOfBitsUsed( void ) const {return GetWriteOffset();}
00503 inline BitSize_t GetWriteOffset( void ) const {return numberOfBitsUsed;}
00504
00506 inline BitSize_t GetNumberOfBytesUsed( void ) const {return BITS_TO_BYTES( numberOfBitsUsed );}
00507
00509 inline BitSize_t GetReadOffset( void ) const {return readOffset;}
00510
00512 void SetReadOffset( const BitSize_t newReadOffset ) {readOffset=newReadOffset;}
00513
00515 inline BitSize_t GetNumberOfUnreadBits( void ) const {return numberOfBitsUsed - readOffset;}
00516
00521 BitSize_t CopyData( unsigned char** _data ) const;
00522
00525 void SetData( unsigned char *inByteArray );
00526
00530 inline unsigned char* GetData( void ) const {return data;}
00531
00541 void WriteBits( const unsigned char* inByteArray, BitSize_t numberOfBitsToWrite, const bool rightAlignedBits = true );
00542
00550 void WriteAlignedBytes( const unsigned char *inByteArray, const unsigned int numberOfBytesToWrite );
00551
00552
00553 void EndianSwapBytes( int byteOffset, int length );
00554
00559 void WriteAlignedBytesSafe( const char *inByteArray, const unsigned int inputLength, const unsigned int maxBytesToWrite );
00560
00568 bool ReadAlignedBytes( unsigned char *inOutByteArray, const unsigned int numberOfBytesToRead );
00569
00574 bool ReadAlignedBytesSafe( char *inOutByteArray, int &inputLength, const int maxBytesToRead );
00575 bool ReadAlignedBytesSafe( char *inOutByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead );
00576
00580 bool ReadAlignedBytesSafeAlloc( char **outByteArray, int &inputLength, const unsigned int maxBytesToRead );
00581 bool ReadAlignedBytesSafeAlloc( char **outByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead );
00582
00588 inline void AlignWriteToByteBoundary( void ) {numberOfBitsUsed += 8 - ( (( numberOfBitsUsed - 1 ) & 7) + 1 );}
00589
00595 inline void AlignReadToByteBoundary( void ) {readOffset += 8 - ( (( readOffset - 1 ) & 7 ) + 1 );}
00596
00605 bool ReadBits( unsigned char *inOutByteArray, BitSize_t numberOfBitsToRead, const bool alignBitsToRight = true );
00606
00608 void Write0( void );
00609
00611 void Write1( void );
00612
00614 bool ReadBit( void );
00615
00618 void AssertCopyData( void );
00619
00623 void SetNumberOfBitsAllocated( const BitSize_t lengthInBits );
00624
00626 void AddBitsAndReallocate( const BitSize_t numberOfBitsToWrite );
00627
00630 BitSize_t GetNumberOfBitsAllocated(void) const;
00631
00633 bool Read(char *varString);
00634 bool Read(unsigned char *varString);
00635
00637 void PadWithZeroToByteLength( unsigned int bytes );
00638
00641 static int NumberOfLeadingZeroes( uint8_t x );
00642 static int NumberOfLeadingZeroes( uint16_t x );
00643 static int NumberOfLeadingZeroes( uint32_t x );
00644 static int NumberOfLeadingZeroes( uint64_t x );
00645 static int NumberOfLeadingZeroes( int8_t x );
00646 static int NumberOfLeadingZeroes( int16_t x );
00647 static int NumberOfLeadingZeroes( int32_t x );
00648 static int NumberOfLeadingZeroes( int64_t x );
00649
00651 void WriteAlignedVar8(const char *inByteArray);
00653 bool ReadAlignedVar8(char *inOutByteArray);
00655 void WriteAlignedVar16(const char *inByteArray);
00657 bool ReadAlignedVar16(char *inOutByteArray);
00659 void WriteAlignedVar32(const char *inByteArray);
00661 bool ReadAlignedVar32(char *inOutByteArray);
00662
00664
00665 #if defined(_MSC_VER) && _MSC_VER == 1300
00666
00667
00668 template <>
00669 void WriteRef(const bool &var);
00670
00673 template <>
00674 void WriteRef(const SystemAddress &var);
00675
00678 template <>
00679 void WriteRef(const uint24_t &var);
00680
00683 template <>
00684 void WriteRef(const RakNetGuid &var);
00685
00688 template <>
00689 void WriteRef(const NetworkID &var);
00690
00693 template <>
00694 void WriteRef(const char* const &var);
00695 template <>
00696 void WriteRef(const unsigned char* const &var);
00697 template <>
00698 void WriteRef(char* const &var);
00699 template <>
00700 void WriteRef(unsigned char* const &var);
00701 template <>
00702 void WriteRef(const RakString &var);
00703
00709 template <>
00710 void WriteDelta(SystemAddress currentValue, SystemAddress lastValue);
00711
00712 template <>
00713 void WriteDelta(uint24_t currentValue, uint24_t lastValue);
00714
00715 template <>
00716 void WriteDelta(RakNetGUID currentValue, RakNetGUID lastValue);
00717
00723 template <>
00724 void WriteDelta(NetworkID currentValue, NetworkID lastValue);
00725
00730 template <>
00731 void WriteDelta(bool currentValue, bool lastValue);
00732
00733 template <>
00734 void WriteCompressed(SystemAddress var);
00735
00736 template <>
00737 void WriteCompressed(uint24_t var);
00738
00739 template <>
00740 void WriteCompressed(RakNetGUID var);
00741
00742 template <>
00743 void WriteCompressed(NetworkID var);
00744
00745 template <>
00746 void WriteCompressed(bool var);
00747
00749 template <>
00750 void WriteCompressed(float var);
00751
00753 template <>
00754 void WriteCompressed(double var);
00755
00757 template <>
00758 void WriteCompressed(const char* var);
00759 template <>
00760 void WriteCompressed(const unsigned char* var);
00761 template <>
00762 void WriteCompressed(char* var);
00763 template <>
00764 void WriteCompressed(unsigned char* var);
00765 template <>
00766 void WriteCompressed(RakString var);
00767
00772 template <>
00773 void WriteCompressedDelta(bool currentValue, bool lastValue);
00774
00777 template <>
00778 void WriteCompressedDelta(bool currentValue);
00779
00783 template <>
00784 bool Read(bool &var);
00785
00789 template <>
00790 bool Read(SystemAddress &var);
00791
00792 template <>
00793 bool Read(uint24_t &var);
00794
00795 template <>
00796 bool Read(RakNetGUID &var);
00797
00801 template <>
00802 bool Read(NetworkID &var);
00803
00807 template <>
00808 bool Read(char *&var);
00809 template <>
00810 bool Read(unsigned char *&var);
00811 template <>
00812 bool Read(RakString &var);
00813
00817 template <>
00818 bool ReadDelta(bool &var);
00819
00820 template <>
00821 bool ReadCompressed(SystemAddress &var);
00822
00823 template <>
00824 bool ReadCompressed(uint24_t &var);
00825
00826 template <>
00827 bool ReadCompressed(RakNetGUID &var);
00828
00829 template <>
00830 bool ReadCompressed(NetworkID &var);
00831
00832 template <>
00833 bool ReadCompressed(bool &var);
00834
00835 template <>
00836 bool ReadCompressed(float &var);
00837
00840 template <>
00841 bool ReadCompressed(double &var);
00842
00843 template <>
00844 bool ReadCompressed(char* &var);
00845 template <>
00846 bool ReadCompressed(unsigned char *&var);
00847 template <>
00848 bool ReadCompressed(RakString &var);
00849
00853 template <>
00854 bool ReadCompressedDelta(bool &var);
00855 #endif
00856
00857 inline static bool DoEndianSwap(void) {
00858 #ifndef __BITSTREAM_NATIVE_END
00859 return IsNetworkOrder()==false;
00860 #else
00861 return false;
00862 #endif
00863 }
00864 inline static bool IsBigEndian(void)
00865 {
00866 return IsNetworkOrder();
00867 }
00868 inline static bool IsNetworkOrder(void) {static const bool r = IsNetworkOrderInternal(); return r;}
00869
00870 static bool IsNetworkOrderInternal(void);
00871 static void ReverseBytes(unsigned char *inByteArray, unsigned char *inOutByteArray, const unsigned int length);
00872 static void ReverseBytesInPlace(unsigned char *inOutData,const unsigned int length);
00873
00874 private:
00875
00876 BitStream( const BitStream &invalid) {
00877 (void) invalid;
00878 RakAssert(0);
00879 }
00880
00882 void WriteCompressed( const unsigned char* inByteArray, const unsigned int size, const bool unsignedData );
00883
00885 bool ReadCompressed( unsigned char* inOutByteArray, const unsigned int size, const bool unsignedData );
00886
00887
00888 BitSize_t numberOfBitsUsed;
00889
00890 BitSize_t numberOfBitsAllocated;
00891
00892 BitSize_t readOffset;
00893
00894 unsigned char *data;
00895
00897 bool copyData;
00898
00900 unsigned char stackData[BITSTREAM_STACK_ALLOCATION_SIZE];
00901 };
00902
00903 template <class templateType>
00904 inline bool BitStream::Serialize(bool writeToBitstream, templateType &inOutTemplateVar)
00905 {
00906 if (writeToBitstream)
00907 Write(inOutTemplateVar);
00908 else
00909 return Read(inOutTemplateVar);
00910 return true;
00911 }
00912
00913 template <class templateType>
00914 inline bool BitStream::SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue, templateType lastValue)
00915 {
00916 if (writeToBitstream)
00917 WriteDelta(inOutCurrentValue, lastValue);
00918 else
00919 return ReadDelta(inOutCurrentValue);
00920 return true;
00921 }
00922
00923 template <class templateType>
00924 inline bool BitStream::SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue)
00925 {
00926 if (writeToBitstream)
00927 WriteDelta(inOutCurrentValue);
00928 else
00929 return ReadDelta(inOutCurrentValue);
00930 return true;
00931 }
00932
00933 template <class templateType>
00934 inline bool BitStream::SerializeCompressed(bool writeToBitstream, templateType &inOutTemplateVar)
00935 {
00936 if (writeToBitstream)
00937 WriteCompressed(inOutTemplateVar);
00938 else
00939 return ReadCompressed(inOutTemplateVar);
00940 return true;
00941 }
00942
00943 template <class templateType>
00944 inline bool BitStream::SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue, templateType lastValue)
00945 {
00946 if (writeToBitstream)
00947 WriteCompressedDelta(inOutCurrentValue,lastValue);
00948 else
00949 return ReadCompressedDelta(inOutCurrentValue);
00950 return true;
00951 }
00952
00953 template <class templateType>
00954 inline bool BitStream::SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue)
00955 {
00956 if (writeToBitstream)
00957 WriteCompressedDelta(inOutCurrentValue);
00958 else
00959 return ReadCompressedDelta(inOutCurrentValue);
00960 return true;
00961 }
00962
00963 inline bool BitStream::Serialize(bool writeToBitstream, char* inOutByteArray, const unsigned int numberOfBytes )
00964 {
00965 if (writeToBitstream)
00966 Write(inOutByteArray, numberOfBytes);
00967 else
00968 return Read(inOutByteArray, numberOfBytes);
00969 return true;
00970 }
00971
00972 template <class serializationType, class sourceType >
00973 bool BitStream::SerializeCasted( bool writeToBitstream, sourceType &value )
00974 {
00975 if (writeToBitstream) WriteCasted<serializationType>(value);
00976 else return ReadCasted<serializationType>(value);
00977 return true;
00978 }
00979
00980 template <class templateType, class rangeType>
00981 bool BitStream::SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange )
00982 {
00983 static int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum));
00984 return SerializeBitsFromIntegerRange(writeToBitstream,value,minimum,maximum,requiredBits,allowOutsideRange);
00985 }
00986 template <class templateType, class rangeType>
00987 bool BitStream::SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange )
00988 {
00989 if (writeToBitstream) WriteBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
00990 else return ReadBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
00991 return true;
00992 }
00993
00994 template <class templateType>
00995 inline bool BitStream::SerializeNormVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z )
00996 {
00997 if (writeToBitstream)
00998 WriteNormVector(x,y,z);
00999 else
01000 return ReadNormVector(x,y,z);
01001 return true;
01002 }
01003
01004 template <class templateType>
01005 inline bool BitStream::SerializeVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z )
01006 {
01007 if (writeToBitstream)
01008 WriteVector(x,y,z);
01009 else
01010 return ReadVector(x,y,z);
01011 return true;
01012 }
01013
01014 template <class templateType>
01015 inline bool BitStream::SerializeNormQuat(bool writeToBitstream, templateType &w, templateType &x, templateType &y, templateType &z)
01016 {
01017 if (writeToBitstream)
01018 WriteNormQuat(w,x,y,z);
01019 else
01020 return ReadNormQuat(w,x,y,z);
01021 return true;
01022 }
01023
01024 template <class templateType>
01025 inline bool BitStream::SerializeOrthMatrix(
01026 bool writeToBitstream,
01027 templateType &m00, templateType &m01, templateType &m02,
01028 templateType &m10, templateType &m11, templateType &m12,
01029 templateType &m20, templateType &m21, templateType &m22 )
01030 {
01031 if (writeToBitstream)
01032 WriteOrthMatrix(m00,m01,m02,m10,m11,m12,m20,m21,m22);
01033 else
01034 return ReadOrthMatrix(m00,m01,m02,m10,m11,m12,m20,m21,m22);
01035 return true;
01036 }
01037
01038 inline bool BitStream::SerializeBits(bool writeToBitstream, unsigned char* inOutByteArray, const BitSize_t numberOfBitsToSerialize, const bool rightAlignedBits )
01039 {
01040 if (writeToBitstream)
01041 WriteBits(inOutByteArray,numberOfBitsToSerialize,rightAlignedBits);
01042 else
01043 return ReadBits(inOutByteArray,numberOfBitsToSerialize,rightAlignedBits);
01044 return true;
01045 }
01046
01047 template <class templateType>
01048 inline void BitStream::Write(templateType inTemplateVar)
01049 {
01050 WriteRef(inTemplateVar);
01051 }
01052
01053 template <class templateType>
01054 inline void BitStream::WriteRef(const templateType &inTemplateVar)
01055 {
01056 #ifdef _MSC_VER
01057 #pragma warning(disable:4127) // conditional expression is constant
01058 #endif
01059 if (sizeof(inTemplateVar)==1)
01060 WriteBits( ( unsigned char* ) & inTemplateVar, sizeof( templateType ) * 8, true );
01061 else
01062 {
01063 #ifndef __BITSTREAM_NATIVE_END
01064 if (DoEndianSwap())
01065 {
01066 unsigned char output[sizeof(templateType)];
01067 ReverseBytes((unsigned char*)&inTemplateVar, output, sizeof(templateType));
01068 WriteBits( ( unsigned char* ) output, sizeof(templateType) * 8, true );
01069 }
01070 else
01071 #endif
01072 WriteBits( ( unsigned char* ) & inTemplateVar, sizeof(templateType) * 8, true );
01073 }
01074 }
01075
01076 template <class templateType>
01077 inline void BitStream::WritePtr(templateType *inTemplateVar)
01078 {
01079 #ifdef _MSC_VER
01080 #pragma warning(disable:4127) // conditional expression is constant
01081 #endif
01082 if (sizeof(templateType)==1)
01083 WriteBits( ( unsigned char* ) inTemplateVar, sizeof( templateType ) * 8, true );
01084 else
01085 {
01086 #ifndef __BITSTREAM_NATIVE_END
01087 if (DoEndianSwap())
01088 {
01089 unsigned char output[sizeof(templateType)];
01090 ReverseBytes((unsigned char*) inTemplateVar, output, sizeof(templateType));
01091 WriteBits( ( unsigned char* ) output, sizeof(templateType) * 8, true );
01092 }
01093 else
01094 #endif
01095 WriteBits( ( unsigned char* ) inTemplateVar, sizeof(templateType) * 8, true );
01096 }
01097 }
01098
01101 template <>
01102 inline void BitStream::WriteRef(const bool &inTemplateVar)
01103 {
01104 if ( inTemplateVar )
01105 Write1();
01106 else
01107 Write0();
01108 }
01109
01110
01113 template <>
01114 inline void BitStream::WriteRef(const SystemAddress &inTemplateVar)
01115 {
01116
01117 SystemAddress var2=inTemplateVar;
01118 var2.binaryAddress=~inTemplateVar.binaryAddress;
01119
01120 WriteBits((unsigned char*)&var2.binaryAddress, sizeof(var2.binaryAddress)*8, true);
01121 Write(var2.port);
01122 }
01123
01124 template <>
01125 inline void BitStream::WriteRef(const uint24_t &inTemplateVar)
01126 {
01127 AlignWriteToByteBoundary();
01128 AddBitsAndReallocate(3*8);
01129
01130 if (IsBigEndian()==false)
01131 {
01132 data[( numberOfBitsUsed >> 3 ) + 0] = ((char *)&inTemplateVar.val)[0];
01133 data[( numberOfBitsUsed >> 3 ) + 1] = ((char *)&inTemplateVar.val)[1];
01134 data[( numberOfBitsUsed >> 3 ) + 2] = ((char *)&inTemplateVar.val)[2];
01135 }
01136 else
01137 {
01138 data[( numberOfBitsUsed >> 3 ) + 0] = ((char *)&inTemplateVar.val)[3];
01139 data[( numberOfBitsUsed >> 3 ) + 1] = ((char *)&inTemplateVar.val)[2];
01140 data[( numberOfBitsUsed >> 3 ) + 2] = ((char *)&inTemplateVar.val)[1];
01141 }
01142
01143 numberOfBitsUsed+=3*8;
01144 }
01145
01146 template <>
01147 inline void BitStream::WriteRef(const RakNetGUID &inTemplateVar)
01148 {
01149 Write(inTemplateVar.g);
01150 }
01151
01154 template <>
01155 inline void BitStream::WriteRef(const NetworkID &inTemplateVar)
01156 {
01157 #if NETWORK_ID_SUPPORTS_PEER_TO_PEER==1
01158 RakAssert(NetworkID::IsPeerToPeerMode());
01159
01160 {
01161 if (inTemplateVar.guid!=UNASSIGNED_RAKNET_GUID)
01162 {
01163 Write(true);
01164 Write(inTemplateVar.guid);
01165 }
01166 else
01167 Write(false);
01168 if (inTemplateVar.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS)
01169 {
01170 Write(true);
01171 Write(inTemplateVar.systemAddress);
01172 }
01173 else
01174 Write(false);
01175 }
01176 #endif
01177
01178
01179
01180
01181 Write(inTemplateVar.localSystemAddress);
01182 }
01183
01186 template <>
01187 inline void BitStream::WriteRef(const RakString &inTemplateVar)
01188 {
01189 inTemplateVar.Serialize(this);
01190 }
01191 template <>
01192 inline void BitStream::WriteRef(const char * const &inStringVar)
01193 {
01194 RakString::Serialize(inStringVar, this);
01195 }
01196 template <>
01197 inline void BitStream::WriteRef(const unsigned char * const &inTemplateVar)
01198 {
01199 Write((const char*)inTemplateVar);
01200 }
01201 template <>
01202 inline void BitStream::WriteRef(char * const &inTemplateVar)
01203 {
01204 Write((const char*)inTemplateVar);
01205 }
01206 template <>
01207 inline void BitStream::WriteRef(unsigned char * const &inTemplateVar)
01208 {
01209 Write((const char*)inTemplateVar);
01210 }
01211
01217 template <class templateType>
01218 inline void BitStream::WriteDelta(templateType currentValue, templateType lastValue)
01219 {
01220 if (currentValue==lastValue)
01221 {
01222 Write(false);
01223 }
01224 else
01225 {
01226 Write(true);
01227 Write(currentValue);
01228 }
01229 }
01230
01231
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01288 template <>
01289 inline void BitStream::WriteDelta(bool currentValue, bool lastValue)
01290 {
01291 (void) lastValue;
01292
01293 Write(currentValue);
01294 }
01295
01298 template <class templateType>
01299 inline void BitStream::WriteDelta(templateType currentValue)
01300 {
01301 Write(true);
01302 Write(currentValue);
01303 }
01304
01311 template <class templateType>
01312 inline void BitStream::WriteCompressed(templateType inTemplateVar)
01313 {
01314 #ifdef _MSC_VER
01315 #pragma warning(disable:4127) // conditional expression is constant
01316 #endif
01317 if (sizeof(inTemplateVar)==1)
01318 WriteCompressed( ( unsigned char* ) & inTemplateVar, sizeof( templateType ) * 8, true );
01319 else
01320 {
01321 #ifndef __BITSTREAM_NATIVE_END
01322 #ifdef _MSC_VER
01323 #pragma warning(disable:4244) // '=' : conversion from 'unsigned long' to 'unsigned short', possible loss of data
01324 #endif
01325
01326 if (DoEndianSwap())
01327 {
01328 unsigned char output[sizeof(templateType)];
01329 ReverseBytes((unsigned char*)&inTemplateVar, output, sizeof(templateType));
01330 WriteCompressed( ( unsigned char* ) output, sizeof(templateType) * 8, true );
01331 }
01332 else
01333 #endif
01334 WriteCompressed( ( unsigned char* ) & inTemplateVar, sizeof(templateType) * 8, true );
01335 }
01336 }
01337
01338 template <>
01339 inline void BitStream::WriteCompressed(SystemAddress inTemplateVar)
01340 {
01341 Write(inTemplateVar);
01342 }
01343
01344 template <>
01345 inline void BitStream::WriteCompressed(RakNetGUID inTemplateVar)
01346 {
01347 Write(inTemplateVar);
01348 }
01349
01350 template <>
01351 inline void BitStream::WriteCompressed(uint24_t var)
01352 {
01353 Write(var);
01354 }
01355
01356 template <>
01357 inline void BitStream::WriteCompressed(NetworkID inTemplateVar)
01358 {
01359 Write(inTemplateVar);
01360 }
01361
01362 template <>
01363 inline void BitStream::WriteCompressed(bool inTemplateVar)
01364 {
01365 Write(inTemplateVar);
01366 }
01367
01369 template <>
01370 inline void BitStream::WriteCompressed(float inTemplateVar)
01371 {
01372 RakAssert(inTemplateVar > -1.01f && inTemplateVar < 1.01f);
01373 if (inTemplateVar < -1.0f)
01374 inTemplateVar=-1.0f;
01375 if (inTemplateVar > 1.0f)
01376 inTemplateVar=1.0f;
01377 Write((unsigned short)((inTemplateVar+1.0f)*32767.5f));
01378 }
01379
01381 template <>
01382 inline void BitStream::WriteCompressed(double inTemplateVar)
01383 {
01384 RakAssert(inTemplateVar > -1.01 && inTemplateVar < 1.01);
01385 if (inTemplateVar < -1.0f)
01386 inTemplateVar=-1.0f;
01387 if (inTemplateVar > 1.0f)
01388 inTemplateVar=1.0f;
01389 #ifdef _DEBUG
01390 RakAssert(sizeof(unsigned long)==4);
01391 #endif
01392 Write((unsigned long)((inTemplateVar+1.0)*2147483648.0));
01393 }
01394
01396 template <>
01397 inline void BitStream::WriteCompressed(RakString inTemplateVar)
01398 {
01399 inTemplateVar.SerializeCompressed(this,0,false);
01400 }
01401 template <>
01402 inline void BitStream::WriteCompressed(const char * inStringVar)
01403 {
01404 RakString::SerializeCompressed(inStringVar,this,0,false);
01405 }
01406 template <>
01407 inline void BitStream::WriteCompressed(const unsigned char * inTemplateVar)
01408 {
01409 WriteCompressed((const char*) inTemplateVar);
01410 }
01411 template <>
01412 inline void BitStream::WriteCompressed(char * inTemplateVar)
01413 {
01414 WriteCompressed((const char*) inTemplateVar);
01415 }
01416 template <>
01417 inline void BitStream::WriteCompressed(unsigned char * inTemplateVar)
01418 {
01419 WriteCompressed((const char*) inTemplateVar);
01420 }
01421
01430 template <class templateType>
01431 inline void BitStream::WriteCompressedDelta(templateType currentValue, templateType lastValue)
01432 {
01433 if (currentValue==lastValue)
01434 {
01435 Write(false);
01436 }
01437 else
01438 {
01439 Write(true);
01440 WriteCompressed(currentValue);
01441 }
01442 }
01443
01447 template <>
01448 inline void BitStream::WriteCompressedDelta(bool currentValue, bool lastValue)
01449 {
01450 (void) lastValue;
01451
01452 Write(currentValue);
01453 }
01454
01457 template <class templateType>
01458 inline void BitStream::WriteCompressedDelta(templateType currentValue)
01459 {
01460 Write(true);
01461 WriteCompressed(currentValue);
01462 }
01463
01466 template <>
01467 inline void BitStream::WriteCompressedDelta(bool currentValue)
01468 {
01469 Write(currentValue);
01470 }
01471
01474 template <class templateType>
01475 inline bool BitStream::Read(templateType &outTemplateVar)
01476 {
01477 #ifdef _MSC_VER
01478 #pragma warning(disable:4127) // conditional expression is constant
01479 #endif
01480 if (sizeof(outTemplateVar)==1)
01481 return ReadBits( ( unsigned char* ) &outTemplateVar, sizeof(templateType) * 8, true );
01482 else
01483 {
01484 #ifndef __BITSTREAM_NATIVE_END
01485 #ifdef _MSC_VER
01486 #pragma warning(disable:4244) // '=' : conversion from 'unsigned long' to 'unsigned short', possible loss of data
01487 #endif
01488 if (DoEndianSwap())
01489 {
01490 unsigned char output[sizeof(templateType)];
01491 if (ReadBits( ( unsigned char* ) output, sizeof(templateType) * 8, true ))
01492 {
01493 ReverseBytes(output, (unsigned char*)&outTemplateVar, sizeof(templateType));
01494 return true;
01495 }
01496 return false;
01497 }
01498 else
01499 #endif
01500 return ReadBits( ( unsigned char* ) & outTemplateVar, sizeof(templateType) * 8, true );
01501 }
01502 }
01503
01504 template <class templateType>
01505 inline bool BitStream::ReadPtr(templateType *outTemplateVar)
01506 {
01507 #ifdef _MSC_VER
01508 #pragma warning(disable:4127) // conditional expression is constant
01509 #endif
01510 if (sizeof(templateType)==1)
01511 return ReadBits( ( unsigned char* ) outTemplateVar, sizeof(templateType) * 8, true );
01512 else
01513 {
01514 #ifndef __BITSTREAM_NATIVE_END
01515 #ifdef _MSC_VER
01516 #pragma warning(disable:4244) // '=' : conversion from 'unsigned long' to 'unsigned short', possible loss of data
01517 #endif
01518 if (DoEndianSwap())
01519 {
01520 unsigned char output[sizeof(templateType)];
01521 if (ReadBits( ( unsigned char* ) output, sizeof(templateType) * 8, true ))
01522 {
01523 ReverseBytes(output, (unsigned char*)outTemplateVar, sizeof(templateType));
01524 return true;
01525 }
01526 return false;
01527 }
01528 else
01529 #endif
01530 return ReadBits( ( unsigned char* ) outTemplateVar, sizeof(templateType) * 8, true );
01531 }
01532 }
01533
01536 template <>
01537 inline bool BitStream::Read(bool &outTemplateVar)
01538 {
01539 if ( readOffset + 1 > numberOfBitsUsed )
01540 return false;
01541
01542 if ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset & 7 ) ) )
01543 outTemplateVar = true;
01544 else
01545 outTemplateVar = false;
01546
01547
01548 readOffset++;
01549
01550 return true;
01551 }
01552
01555 template <>
01556 inline bool BitStream::Read(SystemAddress &outTemplateVar)
01557 {
01558
01559
01560 ReadBits( ( unsigned char* ) & outTemplateVar.binaryAddress, sizeof(outTemplateVar.binaryAddress) * 8, true );
01561
01562 outTemplateVar.binaryAddress=~outTemplateVar.binaryAddress;
01563 return Read(outTemplateVar.port);
01564 }
01565
01566 template <>
01567 inline bool BitStream::Read(uint24_t &outTemplateVar)
01568 {
01569 AlignReadToByteBoundary();
01570 if ( readOffset + 3*8 > numberOfBitsUsed )
01571 return false;
01572
01573 if (IsBigEndian()==false)
01574 {
01575 ((char *)&outTemplateVar.val)[0]=data[ (readOffset >> 3) + 0];
01576 ((char *)&outTemplateVar.val)[1]=data[ (readOffset >> 3) + 1];
01577 ((char *)&outTemplateVar.val)[2]=data[ (readOffset >> 3) + 2];
01578 ((char *)&outTemplateVar.val)[3]=0;
01579 }
01580 else
01581 {
01582
01583 ((char *)&outTemplateVar.val)[3]=data[ (readOffset >> 3) + 0];
01584 ((char *)&outTemplateVar.val)[2]=data[ (readOffset >> 3) + 1];
01585 ((char *)&outTemplateVar.val)[1]=data[ (readOffset >> 3) + 2];
01586 ((char *)&outTemplateVar.val)[0]=0;
01587 }
01588
01589 readOffset+=3*8;
01590 return true;
01591 }
01592
01593 template <>
01594 inline bool BitStream::Read(RakNetGUID &outTemplateVar)
01595 {
01596 return Read(outTemplateVar.g);
01597 }
01598
01601 template <>
01602 inline bool BitStream::Read(NetworkID &outTemplateVar)
01603 {
01604 #if NETWORK_ID_SUPPORTS_PEER_TO_PEER==1
01605 RakAssert(NetworkID::IsPeerToPeerMode());
01606
01607 {
01608 bool hasGuid, hasSystemAddress;
01609 Read(hasGuid);
01610 if (hasGuid)
01611 Read(outTemplateVar.guid);
01612 else
01613 outTemplateVar.guid=UNASSIGNED_RAKNET_GUID;
01614 Read(hasSystemAddress);
01615 if (hasSystemAddress)
01616 Read(outTemplateVar.systemAddress);
01617 else
01618 outTemplateVar.systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
01619 }
01620 #endif
01621
01622
01623
01624
01625 return Read(outTemplateVar.localSystemAddress);
01626 }
01627
01630 template <>
01631 inline bool BitStream::Read(RakString &outTemplateVar)
01632 {
01633 return outTemplateVar.Deserialize(this);
01634 }
01635 template <>
01636 inline bool BitStream::Read(char *&varString)
01637 {
01638 return RakString::Deserialize(varString,this);
01639 }
01640 template <>
01641 inline bool BitStream::Read(unsigned char *&varString)
01642 {
01643 return RakString::Deserialize((char*) varString,this);
01644 }
01645
01651 template <class templateType>
01652 inline bool BitStream::ReadDelta(templateType &outTemplateVar)
01653 {
01654 bool dataWritten;
01655 bool success;
01656 success=Read(dataWritten);
01657 if (dataWritten)
01658 success=Read(outTemplateVar);
01659 return success;
01660 }
01661
01664 template <>
01665 inline bool BitStream::ReadDelta(bool &outTemplateVar)
01666 {
01667 return Read(outTemplateVar);
01668 }
01669
01676 template <class templateType>
01677 inline bool BitStream::ReadCompressed(templateType &outTemplateVar)
01678 {
01679 #ifdef _MSC_VER
01680 #pragma warning(disable:4127) // conditional expression is constant
01681 #endif
01682 if (sizeof(outTemplateVar)==1)
01683 return ReadCompressed( ( unsigned char* ) &outTemplateVar, sizeof(templateType) * 8, true );
01684 else
01685 {
01686 #ifndef __BITSTREAM_NATIVE_END
01687 if (DoEndianSwap())
01688 {
01689 unsigned char output[sizeof(templateType)];
01690 if (ReadCompressed( ( unsigned char* ) output, sizeof(templateType) * 8, true ))
01691 {
01692 ReverseBytes(output, (unsigned char*)&outTemplateVar, sizeof(templateType));
01693 return true;
01694 }
01695 return false;
01696 }
01697 else
01698 #endif
01699 return ReadCompressed( ( unsigned char* ) & outTemplateVar, sizeof(templateType) * 8, true );
01700 }
01701 }
01702
01703 template <>
01704 inline bool BitStream::ReadCompressed(SystemAddress &outTemplateVar)
01705 {
01706 return Read(outTemplateVar);
01707 }
01708
01709 template <>
01710 inline bool BitStream::ReadCompressed(uint24_t &outTemplateVar)
01711 {
01712 return Read(outTemplateVar);
01713 }
01714
01715 template <>
01716 inline bool BitStream::ReadCompressed(RakNetGUID &outTemplateVar)
01717 {
01718 return Read(outTemplateVar);
01719 }
01720
01721 template <>
01722 inline bool BitStream::ReadCompressed(NetworkID &outTemplateVar)
01723 {
01724 return Read(outTemplateVar);
01725 }
01726
01727 template <>
01728 inline bool BitStream::ReadCompressed(bool &outTemplateVar)
01729 {
01730 return Read(outTemplateVar);
01731 }
01732
01734 template <>
01735 inline bool BitStream::ReadCompressed(float &outTemplateVar)
01736 {
01737 unsigned short compressedFloat;
01738 if (Read(compressedFloat))
01739 {
01740 outTemplateVar = ((float)compressedFloat / 32767.5f - 1.0f);
01741 return true;
01742 }
01743 return false;
01744 }
01745
01747 template <>
01748 inline bool BitStream::ReadCompressed(double &outTemplateVar)
01749 {
01750 unsigned long compressedFloat;
01751 if (Read(compressedFloat))
01752 {
01753 outTemplateVar = ((double)compressedFloat / 2147483648.0 - 1.0);
01754 return true;
01755 }
01756 return false;
01757 }
01758
01760 template <>
01761 inline bool BitStream::ReadCompressed(RakString &outTemplateVar)
01762 {
01763 return outTemplateVar.DeserializeCompressed(this,false);
01764 }
01765 template <>
01766 inline bool BitStream::ReadCompressed(char *&outTemplateVar)
01767 {
01768 return RakString::DeserializeCompressed(outTemplateVar,this,false);
01769 }
01770 template <>
01771 inline bool BitStream::ReadCompressed(unsigned char *&outTemplateVar)
01772 {
01773 return RakString::DeserializeCompressed((char*) outTemplateVar,this,false);
01774 }
01775
01785 template <class templateType>
01786 inline bool BitStream::ReadCompressedDelta(templateType &outTemplateVar)
01787 {
01788 bool dataWritten;
01789 bool success;
01790 success=Read(dataWritten);
01791 if (dataWritten)
01792 success=ReadCompressed(outTemplateVar);
01793 return success;
01794 }
01795
01798 template <>
01799 inline bool BitStream::ReadCompressedDelta(bool &outTemplateVar)
01800 {
01801 return Read(outTemplateVar);
01802 }
01803
01804 template <class destinationType, class sourceType >
01805 void BitStream::WriteCasted( const sourceType &value )
01806 {
01807 destinationType val = (destinationType) value;
01808 Write(val);
01809 }
01810
01811 template <class templateType, class rangeType>
01812 void BitStream::WriteBitsFromIntegerRange( const templateType value, const rangeType minimum,const rangeType maximum, bool allowOutsideRange )
01813 {
01814 static int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum));
01815 WriteBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
01816 }
01817 template <class templateType, class rangeType>
01818 void BitStream::WriteBitsFromIntegerRange( const templateType value, const rangeType minimum,const rangeType maximum, const int requiredBits, bool allowOutsideRange )
01819 {
01820 RakAssert(maximum>=minimum);
01821 RakAssert(allowOutsideRange==true || (value>=minimum && value<=maximum));
01822 if (allowOutsideRange)
01823 {
01824 if (value<minimum || value>maximum)
01825 {
01826 Write(true);
01827 Write(value);
01828 return;
01829 }
01830 Write(false);
01831 }
01832 templateType valueOffMin=value-minimum;
01833 if (IsBigEndian()==true)
01834 {
01835 unsigned char output[sizeof(templateType)];
01836 ReverseBytes((unsigned char*)&valueOffMin, output, sizeof(templateType));
01837 WriteBits(output,requiredBits);
01838 }
01839 else
01840 {
01841 WriteBits((unsigned char*) &valueOffMin,requiredBits);
01842 }
01843 }
01844
01845 template <class templateType>
01846 void BitStream::WriteNormVector( templateType x, templateType y, templateType z )
01847 {
01848 #ifdef _DEBUG
01849 RakAssert(x <= 1.01 && y <= 1.01 && z <= 1.01 && x >= -1.01 && y >= -1.01 && z >= -1.01);
01850 #endif
01851
01852 WriteFloat16((float)x,-1.0f,1.0f);
01853 WriteFloat16((float)y,-1.0f,1.0f);
01854 WriteFloat16((float)z,-1.0f,1.0f);
01855 }
01856
01857 template <class templateType>
01858 void BitStream::WriteVector( templateType x, templateType y, templateType z )
01859 {
01860 templateType magnitude = sqrt(x * x + y * y + z * z);
01861 Write((float)magnitude);
01862 if (magnitude > 0.00001f)
01863 {
01864 WriteCompressed((float)(x/magnitude));
01865 WriteCompressed((float)(y/magnitude));
01866 WriteCompressed((float)(z/magnitude));
01867
01868
01869
01870 }
01871 }
01872
01873 template <class templateType>
01874 void BitStream::WriteNormQuat( templateType w, templateType x, templateType y, templateType z)
01875 {
01876 Write((bool)(w<0.0));
01877 Write((bool)(x<0.0));
01878 Write((bool)(y<0.0));
01879 Write((bool)(z<0.0));
01880 Write((unsigned short)(fabs(x)*65535.0));
01881 Write((unsigned short)(fabs(y)*65535.0));
01882 Write((unsigned short)(fabs(z)*65535.0));
01883
01884 }
01885
01886 template <class templateType>
01887 void BitStream::WriteOrthMatrix(
01888 templateType m00, templateType m01, templateType m02,
01889 templateType m10, templateType m11, templateType m12,
01890 templateType m20, templateType m21, templateType m22 )
01891 {
01892
01893 double qw;
01894 double qx;
01895 double qy;
01896 double qz;
01897
01898
01899
01900 float sum;
01901 sum = 1 + m00 + m11 + m22;
01902 if (sum < 0.0f) sum=0.0f;
01903 qw = sqrt( sum ) / 2;
01904 sum = 1 + m00 - m11 - m22;
01905 if (sum < 0.0f) sum=0.0f;
01906 qx = sqrt( sum ) / 2;
01907 sum = 1 - m00 + m11 - m22;
01908 if (sum < 0.0f) sum=0.0f;
01909 qy = sqrt( sum ) / 2;
01910 sum = 1 - m00 - m11 + m22;
01911 if (sum < 0.0f) sum=0.0f;
01912 qz = sqrt( sum ) / 2;
01913 if (qw < 0.0) qw=0.0;
01914 if (qx < 0.0) qx=0.0;
01915 if (qy < 0.0) qy=0.0;
01916 if (qz < 0.0) qz=0.0;
01917 qx = _copysign( (double) qx, (double) (m21 - m12) );
01918 qy = _copysign( (double) qy, (double) (m02 - m20) );
01919 qz = _copysign( (double) qz, (double) (m10 - m01) );
01920
01921 WriteNormQuat(qw,qx,qy,qz);
01922 }
01923
01924 template <class serializationType, class sourceType >
01925 bool BitStream::ReadCasted( sourceType &value )
01926 {
01927 serializationType val;
01928 bool success = Read(val);
01929 value=(sourceType) val;
01930 return success;
01931 }
01932
01933 template <class templateType, class rangeType>
01934 bool BitStream::ReadBitsFromIntegerRange( templateType &value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange )
01935 {
01936 static int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum));
01937 return ReadBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
01938 }
01939 template <class templateType, class rangeType>
01940 bool BitStream::ReadBitsFromIntegerRange( templateType &value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange )
01941 {
01942 RakAssert(maximum>=minimum);
01943 if (allowOutsideRange)
01944 {
01945 bool isOutsideRange;
01946 Read(isOutsideRange);
01947 if (isOutsideRange)
01948 return Read(value);
01949 }
01950 unsigned char output[sizeof(templateType)];
01951 memset(output,0,sizeof(output));
01952 bool success = ReadBits(output,requiredBits);
01953 if (success)
01954 {
01955 if (IsBigEndian()==true)
01956 ReverseBytesInPlace(output,sizeof(output));
01957 memcpy(&value,output,sizeof(output));
01958
01959 value+=minimum;
01960 }
01961
01962 return success;
01963 }
01964
01965 template <class templateType>
01966 bool BitStream::ReadNormVector( templateType &x, templateType &y, templateType &z )
01967 {
01968 float xIn,yIn,zIn;
01969 ReadFloat16(xIn,-1.0f,1.0f);
01970 ReadFloat16(yIn,-1.0f,1.0f);
01971 ReadFloat16(zIn,-1.0f,1.0f);
01972 x=xIn;
01973 y=yIn;
01974 z=zIn;
01975 return true;
01976 }
01977
01978 template <class templateType>
01979 bool BitStream::ReadVector( templateType &x, templateType &y, templateType &z )
01980 {
01981 float magnitude;
01982
01983 if (!Read(magnitude))
01984 return false;
01985 if (magnitude>0.00001f)
01986 {
01987
01988
01989
01990
01991
01992
01993
01994 float cx,cy,cz;
01995 ReadCompressed(cx);
01996 ReadCompressed(cy);
01997 if (!ReadCompressed(cz))
01998 return false;
01999 x=cx;
02000 y=cy;
02001 z=cz;
02002 x*=magnitude;
02003 y*=magnitude;
02004 z*=magnitude;
02005 }
02006 else
02007 {
02008 x=0.0;
02009 y=0.0;
02010 z=0.0;
02011 }
02012 return true;
02013 }
02014
02015 template <class templateType>
02016 bool BitStream::ReadNormQuat( templateType &w, templateType &x, templateType &y, templateType &z)
02017 {
02018 bool cwNeg, cxNeg, cyNeg, czNeg;
02019 unsigned short cx,cy,cz;
02020 Read(cwNeg);
02021 Read(cxNeg);
02022 Read(cyNeg);
02023 Read(czNeg);
02024 Read(cx);
02025 Read(cy);
02026 if (!Read(cz))
02027 return false;
02028
02029
02030 x=(templateType)(cx/65535.0);
02031 y=(templateType)(cy/65535.0);
02032 z=(templateType)(cz/65535.0);
02033 if (cxNeg) x=-x;
02034 if (cyNeg) y=-y;
02035 if (czNeg) z=-z;
02036 float difference = 1.0f - x*x - y*y - z*z;
02037 if (difference < 0.0f)
02038 difference=0.0f;
02039 w = (templateType)(sqrt(difference));
02040 if (cwNeg)
02041 w=-w;
02042
02043 return true;
02044 }
02045
02046 template <class templateType>
02047 bool BitStream::ReadOrthMatrix(
02048 templateType &m00, templateType &m01, templateType &m02,
02049 templateType &m10, templateType &m11, templateType &m12,
02050 templateType &m20, templateType &m21, templateType &m22 )
02051 {
02052 float qw,qx,qy,qz;
02053 if (!ReadNormQuat(qw,qx,qy,qz))
02054 return false;
02055
02056
02057
02058 double sqw = (double)qw*(double)qw;
02059 double sqx = (double)qx*(double)qx;
02060 double sqy = (double)qy*(double)qy;
02061 double sqz = (double)qz*(double)qz;
02062 m00 = (templateType)(sqx - sqy - sqz + sqw);
02063 m11 = (templateType)(-sqx + sqy - sqz + sqw);
02064 m22 = (templateType)(-sqx - sqy + sqz + sqw);
02065
02066 double tmp1 = (double)qx*(double)qy;
02067 double tmp2 = (double)qz*(double)qw;
02068 m10 = (templateType)(2.0 * (tmp1 + tmp2));
02069 m01 = (templateType)(2.0 * (tmp1 - tmp2));
02070
02071 tmp1 = (double)qx*(double)qz;
02072 tmp2 = (double)qy*(double)qw;
02073 m20 =(templateType)(2.0 * (tmp1 - tmp2));
02074 m02 = (templateType)(2.0 * (tmp1 + tmp2));
02075 tmp1 = (double)qy*(double)qz;
02076 tmp2 = (double)qx*(double)qw;
02077 m21 = (templateType)(2.0 * (tmp1 + tmp2));
02078 m12 = (templateType)(2.0 * (tmp1 - tmp2));
02079
02080 return true;
02081 }
02082
02083 template <class templateType>
02084 BitStream& operator<<(BitStream& out, templateType& c)
02085 {
02086 out.WriteRef(c);
02087 return out;
02088 }
02089 template <class templateType>
02090 BitStream& operator>>(BitStream& in, templateType& c)
02091 {
02092 bool success = in.Read(c);
02093 RakAssert(success);
02094 return in;
02095 }
02096
02097 }
02098
02099 #ifdef _MSC_VER
02100 #pragma warning( pop )
02101 #endif
02102
02103 #endif
02104
02105 #endif // VC6