Shadowrun: Awakened 29 September 2011 - Build 871
BitStream.h
Go to the documentation of this file.
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 "RakWString.h"
00023 #include "RakAssert.h"
00024 #include <math.h>
00025 #include <float.h>
00026 
00027 #ifdef _MSC_VER
00028 #pragma warning( push )
00029 #endif
00030 
00031 // MSWin uses _copysign, others use copysign...
00032 #ifndef _WIN32
00033 #define _copysign copysign
00034 #endif
00035 
00036 namespace RakNet
00037 {
00040     class RAK_DLL_EXPORT BitStream
00041     {
00042 
00043     public:
00044         // GetInstance() and DestroyInstance(instance*)
00045         STATIC_FACTORY_DECLARATIONS(BitStream)
00046 
00047         
00048         BitStream();
00049 
00054         BitStream( const unsigned int initialBytesToAllocate );
00055 
00066         BitStream( unsigned char* _data, const unsigned int lengthInBytes, bool _copyData );
00067 
00068         // Destructor
00069         ~BitStream();
00070 
00072         void Reset( void );
00073 
00079         template <class templateType>
00080             bool Serialize(bool writeToBitstream, templateType &inOutTemplateVar);
00081 
00089         template <class templateType>
00090             bool SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue);
00091 
00096         template <class templateType>
00097             bool SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue);
00098 
00107         template <class templateType>
00108             bool SerializeCompressed(bool writeToBitstream, templateType &inOutTemplateVar);
00109 
00120         template <class templateType>
00121             bool SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue);
00122 
00125         template <class templateType>
00126             bool SerializeCompressedDelta(bool writeToBitstream, templateType &inOutTemplateVar);
00127 
00133         bool Serialize(bool writeToBitstream,  char* inOutByteArray, const unsigned int numberOfBytes );
00134 
00140         bool SerializeFloat16(bool writeToBitstream, float &inOutFloat, float floatMin, float floatMax);
00141 
00147         template <class serializationType, class sourceType >
00148         bool SerializeCasted( bool writeToBitstream, sourceType &value );
00149 
00158         template <class templateType, class rangeType>
00159         bool SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange=false );
00161         template <class templateType, class rangeType>
00162         bool SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange=false );
00163 
00172         template <class templateType> // templateType for this function must be a float or double
00173             bool SerializeNormVector(bool writeToBitstream,  templateType &x, templateType &y, templateType &z );
00174 
00182         template <class templateType> // templateType for this function must be a float or double
00183             bool SerializeVector(bool writeToBitstream,  templateType &x, templateType &y, templateType &z );
00184 
00192         template <class templateType> // templateType for this function must be a float or double
00193             bool SerializeNormQuat(bool writeToBitstream,  templateType &w, templateType &x, templateType &y, templateType &z);
00194 
00199         template <class templateType> // templateType for this function must be a float or double
00200             bool SerializeOrthMatrix(
00201             bool writeToBitstream,
00202             templateType &m00, templateType &m01, templateType &m02,
00203             templateType &m10, templateType &m11, templateType &m12,
00204             templateType &m20, templateType &m21, templateType &m22 );
00205 
00217         bool SerializeBits(bool writeToBitstream, unsigned char* inOutByteArray, const BitSize_t numberOfBitsToSerialize, const bool rightAlignedBits = true );
00218 
00222         template <class templateType>
00223             void Write(const templateType &inTemplateVar);
00224 
00228         template <class templateType>
00229             void WritePtr(templateType *inTemplateVar);
00230 
00236         template <class templateType>
00237             void WriteDelta(const templateType &currentValue, const templateType &lastValue);
00238 
00241         template <class templateType>
00242             void WriteDelta(const templateType &currentValue);
00243 
00250         template <class templateType>
00251             void WriteCompressed(const templateType &inTemplateVar);
00252 
00261         template <class templateType>
00262             void WriteCompressedDelta(const templateType &currentValue, const templateType &lastValue);
00263 
00265         template <class templateType>
00266             void WriteCompressedDelta(const templateType &currentValue);
00267 
00272         template <class templateType>
00273             bool Read(templateType &outTemplateVar);
00274 
00281         template <class templateType>
00282             bool ReadDelta(templateType &outTemplateVar);
00283 
00291         template <class templateType>
00292             bool ReadCompressed(templateType &outTemplateVar);
00293 
00304         template <class templateType>
00305             bool ReadCompressedDelta(templateType &outTemplateVar);
00306 
00311         bool Read( BitStream *bitStream, BitSize_t numberOfBits );
00312         bool Read( BitStream *bitStream );
00313         bool Read( BitStream &bitStream, BitSize_t numberOfBits );
00314         bool Read( BitStream &bitStream );
00315 
00319         void Write( const char* inputByteArray, const unsigned int numberOfBytes );
00320 
00324         void Write( BitStream *bitStream, BitSize_t numberOfBits );
00325         void Write( BitStream *bitStream );
00326         void Write( BitStream &bitStream, BitSize_t numberOfBits );
00327         void Write( BitStream &bitStream );\
00328         
00333         void WriteFloat16( float x, float floatMin, float floatMax );
00334 
00339         template <class serializationType, class sourceType >
00340         void WriteCasted( const sourceType &value );
00341 
00349         template <class templateType, class rangeType>
00350         void WriteBitsFromIntegerRange( const templateType value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange=false );
00352         template <class templateType, class rangeType>
00353         void WriteBitsFromIntegerRange( const templateType value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange=false );
00354 
00361         template <class templateType> // templateType for this function must be a float or double
00362         void WriteNormVector( templateType x, templateType y, templateType z );
00363 
00370         template <class templateType> // templateType for this function must be a float or double
00371         void WriteVector( templateType x, templateType y, templateType z );
00372 
00378         template <class templateType> // templateType for this function must be a float or double
00379         void WriteNormQuat( templateType w, templateType x, templateType y, templateType z);
00380 
00384         template <class templateType> // templateType for this function must be a float or double
00385         void WriteOrthMatrix(
00386             templateType m00, templateType m01, templateType m02,
00387             templateType m10, templateType m11, templateType m12,
00388             templateType m20, templateType m21, templateType m22 );
00389 
00395         bool Read( char* output, const unsigned int numberOfBytes );
00396 
00401         bool ReadFloat16( float &outFloat, float floatMin, float floatMax );
00402 
00407         template <class serializationType, class sourceType >
00408         bool ReadCasted( sourceType &value );
00409 
00417         template <class templateType, class rangeType>
00418         bool ReadBitsFromIntegerRange( templateType &value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange=false );
00420         template <class templateType, class rangeType>
00421         bool ReadBitsFromIntegerRange( templateType &value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange=false );
00422 
00430         template <class templateType> // templateType for this function must be a float or double
00431         bool ReadNormVector( templateType &x, templateType &y, templateType &z );
00432 
00440         template <class templateType> // templateType for this function must be a float or double
00441         bool ReadVector( templateType &x, templateType &y, templateType &z );
00442 
00449         template <class templateType> // templateType for this function must be a float or double
00450         bool ReadNormQuat( templateType &w, templateType &x, templateType &y, templateType &z);
00451 
00456         template <class templateType> // templateType for this function must be a float or double
00457         bool ReadOrthMatrix(
00458             templateType &m00, templateType &m01, templateType &m02,
00459             templateType &m10, templateType &m11, templateType &m12,
00460             templateType &m20, templateType &m21, templateType &m22 );
00461 
00463         void ResetReadPointer( void );
00464 
00466         void ResetWritePointer( void );
00467 
00470         void AssertStreamEmpty( void );
00471 
00473         void PrintBits( char *out ) const;
00474         void PrintBits( void ) const;
00475         void PrintHex( char *out ) const;
00476         void PrintHex( void ) const;
00477 
00480         void IgnoreBits( const BitSize_t numberOfBits );
00481 
00484         void IgnoreBytes( const unsigned int numberOfBytes );
00485 
00491         void SetWriteOffset( const BitSize_t offset );
00492 
00494         inline BitSize_t GetNumberOfBitsUsed( void ) const {return GetWriteOffset();}
00495         inline BitSize_t GetWriteOffset( void ) const {return numberOfBitsUsed;}
00496 
00498         inline BitSize_t GetNumberOfBytesUsed( void ) const {return BITS_TO_BYTES( numberOfBitsUsed );}
00499 
00501         inline BitSize_t GetReadOffset( void ) const {return readOffset;}
00502 
00504         void SetReadOffset( const BitSize_t newReadOffset ) {readOffset=newReadOffset;}
00505 
00507         inline BitSize_t GetNumberOfUnreadBits( void ) const {return numberOfBitsUsed - readOffset;}
00508 
00513         BitSize_t CopyData( unsigned char** _data ) const;
00514 
00517         void SetData( unsigned char *inByteArray );
00518 
00522         inline unsigned char* GetData( void ) const {return data;}
00523 
00533         void WriteBits( const unsigned char* inByteArray, BitSize_t numberOfBitsToWrite, const bool rightAlignedBits = true );
00534 
00542         void WriteAlignedBytes( const unsigned char *inByteArray, const unsigned int numberOfBytesToWrite );
00543 
00544         // Endian swap bytes already in the bitstream
00545         void EndianSwapBytes( int byteOffset, int length );
00546 
00551         void WriteAlignedBytesSafe( const char *inByteArray, const unsigned int inputLength, const unsigned int maxBytesToWrite );
00552 
00560         bool ReadAlignedBytes( unsigned char *inOutByteArray, const unsigned int numberOfBytesToRead );
00561 
00566         bool ReadAlignedBytesSafe( char *inOutByteArray, int &inputLength, const int maxBytesToRead );
00567         bool ReadAlignedBytesSafe( char *inOutByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead );
00568 
00572         bool ReadAlignedBytesSafeAlloc( char **outByteArray, int &inputLength, const unsigned int maxBytesToRead );
00573         bool ReadAlignedBytesSafeAlloc( char **outByteArray, unsigned int &inputLength, const unsigned int maxBytesToRead );
00574 
00580         inline void AlignWriteToByteBoundary( void ) {numberOfBitsUsed += 8 - ( (( numberOfBitsUsed - 1 ) & 7) + 1 );}
00581 
00587         inline void AlignReadToByteBoundary( void ) {readOffset += 8 - ( (( readOffset - 1 ) & 7 ) + 1 );}
00588 
00597         bool ReadBits( unsigned char *inOutByteArray, BitSize_t numberOfBitsToRead, const bool alignBitsToRight = true );
00598 
00600         void Write0( void );
00601 
00603         void Write1( void );
00604 
00606         bool ReadBit( void );
00607 
00610         void AssertCopyData( void );
00611 
00615         void SetNumberOfBitsAllocated( const BitSize_t lengthInBits );
00616 
00618         void AddBitsAndReallocate( const BitSize_t numberOfBitsToWrite );
00619 
00622         BitSize_t GetNumberOfBitsAllocated(void) const;
00623 
00625         bool Read(char *varString);
00626         bool Read(unsigned char *varString);
00627 
00629         void PadWithZeroToByteLength( unsigned int bytes );
00630 
00633         static int NumberOfLeadingZeroes( uint8_t x );
00634         static int NumberOfLeadingZeroes( uint16_t x );
00635         static int NumberOfLeadingZeroes( uint32_t x );
00636         static int NumberOfLeadingZeroes( uint64_t x );
00637         static int NumberOfLeadingZeroes( int8_t x );
00638         static int NumberOfLeadingZeroes( int16_t x );
00639         static int NumberOfLeadingZeroes( int32_t x );
00640         static int NumberOfLeadingZeroes( int64_t x );
00641 
00643         void WriteAlignedVar8(const char *inByteArray);
00645         bool ReadAlignedVar8(char *inOutByteArray);
00647         void WriteAlignedVar16(const char *inByteArray);
00649         bool ReadAlignedVar16(char *inOutByteArray);
00651         void WriteAlignedVar32(const char *inByteArray);
00653         bool ReadAlignedVar32(char *inOutByteArray);
00654 
00655         inline void Write(const char * const inStringVar)
00656         {
00657             RakString::Serialize(inStringVar, this);
00658         }
00659         inline void Write(const wchar_t * const inStringVar)
00660         {
00661             RakWString::Serialize(inStringVar, this);
00662         }
00663         inline void Write(const unsigned char * const inTemplateVar)
00664         {
00665             Write((const char*)inTemplateVar);
00666         }
00667         inline void Write(char * const inTemplateVar)
00668         {
00669             Write((const char*)inTemplateVar);
00670         }
00671         inline void Write(unsigned char * const inTemplateVar)
00672         {
00673             Write((const char*)inTemplateVar);
00674         }
00675         inline void WriteCompressed(const char * const inStringVar)
00676         {
00677             RakString::SerializeCompressed(inStringVar,this,0,false);
00678         }
00679         inline void WriteCompressed(const wchar_t * const inStringVar)
00680         {
00681             RakWString::Serialize(inStringVar,this);
00682         }
00683         inline void WriteCompressed(const unsigned char * const inTemplateVar)
00684         {
00685             WriteCompressed((const char*) inTemplateVar);
00686         }
00687         inline void WriteCompressed(char * const inTemplateVar)
00688         {
00689             WriteCompressed((const char*) inTemplateVar);
00690         }
00691         inline void WriteCompressed(unsigned char * const inTemplateVar)
00692         {
00693             WriteCompressed((const char*) inTemplateVar);
00694         }
00695 
00697         // Used for VC7
00698 #if defined(_MSC_VER) && _MSC_VER == 1300
00699 
00700 
00701         template <>
00702             void Write(const bool &var);
00703 
00706         template <>
00707             void Write(const SystemAddress &var);
00708 
00711         template <>
00712         void Write(const uint24_t &var);
00713 
00716         template <>
00717             void Write(const RakNetGuid &var);
00718 
00721         template <>
00722             void Write(const char* const &var);
00723         template <>
00724             void Write(const unsigned char* const &var);
00725         template <>
00726             void Write(char* const &var);
00727         template <>
00728             void Write(unsigned char* const &var);
00729         template <>
00730             void Write(const RakString &var);
00731         template <>
00732             void Write(const RakWString &var);
00733 
00739         template <>
00740             void WriteDelta(const SystemAddress &currentValue, const SystemAddress &lastValue);
00741 
00742         template <>
00743         void WriteDelta(const uint24_t &currentValue, const uint24_t &lastValue);
00744 
00745         template <>
00746             void WriteDelta(const RakNetGUID &currentValue, const RakNetGUID &lastValue);
00747 
00752         template <>
00753             void WriteDelta(const bool &currentValue, const bool &lastValue);
00754 
00755         template <>
00756             void WriteCompressed(const SystemAddress &var);
00757 
00758         template <>
00759         void WriteCompressed(const uint24_t &var);
00760 
00761         template <>
00762             void WriteCompressed(const RakNetGUID &var);
00763 
00764         template <>
00765             void WriteCompressed(const bool &var);
00766 
00768         template <>
00769             void WriteCompressed(const float &var);
00770 
00772         template <>
00773             void WriteCompressed(const double &var);
00774 
00776         template <>
00777             void WriteCompressed(const char* var);
00778         template <>
00779             void WriteCompressed(const unsigned char* var);
00780         template <>
00781             void WriteCompressed(char* var);
00782         template <>
00783             void WriteCompressed(unsigned char* var);
00784         template <>
00785             void WriteCompressed(const RakString &var);
00786         template <>
00787             void WriteCompressed(const RakWString &var);
00788 
00793         template <>
00794             void WriteCompressedDelta(const bool &currentValue, const bool &lastValue);
00795 
00798         template <>
00799             void WriteCompressedDelta(const bool &currentValue);
00800 
00804         template <>
00805             bool Read(bool &var);
00806 
00810         template <>
00811             bool Read(SystemAddress &var);
00812 
00813         template <>
00814         bool Read(uint24_t &var);
00815 
00816         template <>
00817             bool Read(RakNetGUID &var);
00818 
00822         template <>
00823             bool Read(char *&var);
00824         template <>
00825             bool Read(wchar_t *&var);
00826         template <>
00827             bool Read(unsigned char *&var);
00828         template <>
00829             bool Read(RakString &var);
00830         template <>
00831             bool Read(RakWString &var);
00832 
00836         template <>
00837             bool ReadDelta(bool &var);
00838 
00839         template <>
00840             bool ReadCompressed(SystemAddress &var);
00841 
00842         template <>
00843         bool ReadCompressed(uint24_t &var);
00844 
00845         template <>
00846             bool ReadCompressed(RakNetGUID &var);
00847 
00848         template <>
00849             bool ReadCompressed(bool &var);
00850 
00851         template <>
00852             bool ReadCompressed(float &var);
00853 
00856         template <>
00857         bool ReadCompressed(double &var);
00858 
00859         template <>
00860             bool ReadCompressed(char* &var);
00861         template <>
00862             bool ReadCompressed(wchar_t* &var);
00863         template <>
00864             bool ReadCompressed(unsigned char *&var);
00865         template <>
00866             bool ReadCompressed(RakString &var);
00867         template <>
00868             bool ReadCompressed(RakWString &var);
00869 
00873         template <>
00874             bool ReadCompressedDelta(bool &var);
00875 #endif
00876 
00877         inline static bool DoEndianSwap(void) {
00878 #ifndef __BITSTREAM_NATIVE_END
00879             return IsNetworkOrder()==false;
00880 #else
00881             return false;
00882 #endif
00883         }
00884         inline static bool IsBigEndian(void)
00885         {
00886             return IsNetworkOrder();
00887         }
00888         inline static bool IsNetworkOrder(void) {static const bool r = IsNetworkOrderInternal(); return r;}
00889         // Not inline, won't compile on PC due to winsock include errors
00890         static bool IsNetworkOrderInternal(void);
00891         static void ReverseBytes(unsigned char *inByteArray, unsigned char *inOutByteArray, const unsigned int length);
00892         static void ReverseBytesInPlace(unsigned char *inOutData,const unsigned int length);
00893 
00894     private:
00895 
00896         BitStream( const BitStream &invalid) {
00897             (void) invalid;
00898             RakAssert(0);
00899         }
00900 
00902         void WriteCompressed( const unsigned char* inByteArray, const unsigned int size, const bool unsignedData );
00903 
00905         bool ReadCompressed( unsigned char* inOutByteArray, const unsigned int size, const bool unsignedData );
00906 
00907 
00908         BitSize_t numberOfBitsUsed;
00909 
00910         BitSize_t numberOfBitsAllocated;
00911 
00912         BitSize_t readOffset;
00913 
00914         unsigned char *data;
00915 
00917         bool copyData;
00918 
00920         unsigned char stackData[BITSTREAM_STACK_ALLOCATION_SIZE];
00921     };
00922 
00923         template <class templateType>
00924         inline bool BitStream::Serialize(bool writeToBitstream, templateType &inOutTemplateVar)
00925         {
00926             if (writeToBitstream)
00927                 Write(inOutTemplateVar);
00928             else
00929                 return Read(inOutTemplateVar);
00930             return true;
00931         }
00932 
00933         template <class templateType>
00934         inline bool BitStream::SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue)
00935         {
00936             if (writeToBitstream)
00937                 WriteDelta(inOutCurrentValue, lastValue);
00938             else
00939                 return ReadDelta(inOutCurrentValue);
00940             return true;
00941         }
00942 
00943         template <class templateType>
00944         inline bool BitStream::SerializeDelta(bool writeToBitstream, templateType &inOutCurrentValue)
00945         {
00946             if (writeToBitstream)
00947                 WriteDelta(inOutCurrentValue);
00948             else
00949                 return ReadDelta(inOutCurrentValue);
00950             return true;
00951         }
00952 
00953         template <class templateType>
00954         inline bool BitStream::SerializeCompressed(bool writeToBitstream, templateType &inOutTemplateVar)
00955         {
00956             if (writeToBitstream)
00957                 WriteCompressed(inOutTemplateVar);
00958             else
00959                 return ReadCompressed(inOutTemplateVar);
00960             return true;
00961         }
00962 
00963         template <class templateType>
00964         inline bool BitStream::SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue, const templateType &lastValue)
00965         {
00966             if (writeToBitstream)
00967                 WriteCompressedDelta(inOutCurrentValue,lastValue);
00968             else
00969                 return ReadCompressedDelta(inOutCurrentValue);
00970             return true;
00971         }
00972 //Stoppedhere
00973         template <class templateType>
00974         inline bool BitStream::SerializeCompressedDelta(bool writeToBitstream, templateType &inOutCurrentValue)
00975         {
00976             if (writeToBitstream)
00977                 WriteCompressedDelta(inOutCurrentValue);
00978             else
00979                 return ReadCompressedDelta(inOutCurrentValue);
00980             return true;
00981         }
00982 
00983         inline bool BitStream::Serialize(bool writeToBitstream, char* inOutByteArray, const unsigned int numberOfBytes )
00984         {
00985             if (writeToBitstream)
00986                 Write(inOutByteArray, numberOfBytes);
00987             else
00988                 return Read(inOutByteArray, numberOfBytes);
00989             return true;
00990         }
00991         
00992         template <class serializationType, class sourceType >
00993         bool BitStream::SerializeCasted( bool writeToBitstream, sourceType &value )
00994         {
00995             if (writeToBitstream) WriteCasted<serializationType>(value);
00996             else return ReadCasted<serializationType>(value);
00997             return true;
00998         }
00999 
01000         template <class templateType, class rangeType>
01001         bool BitStream::SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange )
01002         {
01003             static int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum));
01004             return SerializeBitsFromIntegerRange(writeToBitstream,value,minimum,maximum,requiredBits,allowOutsideRange);
01005         }
01006         template <class templateType, class rangeType>
01007         bool BitStream::SerializeBitsFromIntegerRange( bool writeToBitstream, templateType &value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange )
01008         {
01009             if (writeToBitstream) WriteBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
01010             else return ReadBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
01011             return true;
01012         }
01013 
01014         template <class templateType>
01015         inline bool BitStream::SerializeNormVector(bool writeToBitstream, templateType &x, templateType &y, templateType &z )
01016         {
01017             if (writeToBitstream)
01018                 WriteNormVector(x,y,z);
01019             else
01020                 return ReadNormVector(x,y,z);
01021             return true;
01022         }
01023 
01024         template <class templateType>
01025         inline bool BitStream::SerializeVector(bool writeToBitstream,  templateType &x, templateType &y, templateType &z )
01026         {
01027             if (writeToBitstream)
01028                 WriteVector(x,y,z);
01029             else
01030                 return ReadVector(x,y,z);
01031             return true;
01032         }
01033 
01034         template <class templateType>
01035         inline bool BitStream::SerializeNormQuat(bool writeToBitstream,  templateType &w, templateType &x, templateType &y, templateType &z)
01036         {
01037             if (writeToBitstream)
01038                 WriteNormQuat(w,x,y,z);
01039             else
01040                 return ReadNormQuat(w,x,y,z);
01041             return true;
01042         }
01043 
01044         template <class templateType>
01045         inline bool BitStream::SerializeOrthMatrix(
01046         bool writeToBitstream,
01047         templateType &m00, templateType &m01, templateType &m02,
01048         templateType &m10, templateType &m11, templateType &m12,
01049         templateType &m20, templateType &m21, templateType &m22 )
01050         {
01051             if (writeToBitstream)
01052                 WriteOrthMatrix(m00,m01,m02,m10,m11,m12,m20,m21,m22);
01053             else
01054                 return ReadOrthMatrix(m00,m01,m02,m10,m11,m12,m20,m21,m22);
01055             return true;
01056         }
01057 
01058         inline bool BitStream::SerializeBits(bool writeToBitstream, unsigned char* inOutByteArray, const BitSize_t numberOfBitsToSerialize, const bool rightAlignedBits )
01059         {
01060             if (writeToBitstream)
01061                 WriteBits(inOutByteArray,numberOfBitsToSerialize,rightAlignedBits);
01062             else
01063                 return ReadBits(inOutByteArray,numberOfBitsToSerialize,rightAlignedBits);
01064             return true;
01065         }
01066 
01067     template <class templateType>
01068         inline void BitStream::Write(const templateType &inTemplateVar)
01069     {
01070 #ifdef _MSC_VER
01071 #pragma warning(disable:4127)   // conditional expression is constant
01072 #endif
01073         if (sizeof(inTemplateVar)==1)
01074             WriteBits( ( unsigned char* ) & inTemplateVar, sizeof( templateType ) * 8, true );
01075         else
01076         {
01077 #ifndef __BITSTREAM_NATIVE_END
01078             if (DoEndianSwap())
01079             {
01080                 unsigned char output[sizeof(templateType)];
01081                 ReverseBytes((unsigned char*)&inTemplateVar, output, sizeof(templateType));
01082                 WriteBits( ( unsigned char* ) output, sizeof(templateType) * 8, true );
01083             }
01084             else
01085 #endif
01086                 WriteBits( ( unsigned char* ) & inTemplateVar, sizeof(templateType) * 8, true );
01087         }
01088     }
01089 
01090     template <class templateType>
01091     inline void BitStream::WritePtr(templateType *inTemplateVar)
01092     {
01093 #ifdef _MSC_VER
01094 #pragma warning(disable:4127)   // conditional expression is constant
01095 #endif
01096         if (sizeof(templateType)==1)
01097             WriteBits( ( unsigned char* ) inTemplateVar, sizeof( templateType ) * 8, true );
01098         else
01099         {
01100 #ifndef __BITSTREAM_NATIVE_END
01101             if (DoEndianSwap())
01102             {
01103                 unsigned char output[sizeof(templateType)];
01104                 ReverseBytes((unsigned char*) inTemplateVar, output, sizeof(templateType));
01105                 WriteBits( ( unsigned char* ) output, sizeof(templateType) * 8, true );
01106             }
01107             else
01108 #endif
01109                 WriteBits( ( unsigned char* ) inTemplateVar, sizeof(templateType) * 8, true );
01110         }
01111     }
01112 
01115     template <>
01116         inline void BitStream::Write(const bool &inTemplateVar)
01117         {
01118             if ( inTemplateVar )
01119                 Write1();
01120             else
01121                 Write0();
01122         }
01123 
01124 
01127     template <>
01128         inline void BitStream::Write(const SystemAddress &inTemplateVar)
01129     {
01130         Write(inTemplateVar.GetIPVersion());
01131         if (inTemplateVar.GetIPVersion()==4)
01132         {
01133             // Hide the address so routers don't modify it
01134             SystemAddress var2=inTemplateVar;
01135             uint32_t binaryAddress=~inTemplateVar.address.addr4.sin_addr.s_addr;
01136             // Don't endian swap the address or port
01137             WriteBits((unsigned char*)&binaryAddress, sizeof(binaryAddress)*8, true);
01138             unsigned short p = var2.GetPortNetworkOrder();
01139             WriteBits((unsigned char*)&p, sizeof(unsigned short)*8, true);
01140         }
01141         else
01142         {
01143 #if RAKNET_SUPPORT_IPV6==1
01144             // Don't endian swap
01145             WriteBits((const unsigned char*) &inTemplateVar.address.addr6, sizeof(inTemplateVar.address.addr6)*8, true);
01146 #endif
01147         }
01148     }
01149 
01150     template <>
01151     inline void BitStream::Write(const uint24_t &inTemplateVar)
01152     {
01153         AlignWriteToByteBoundary();
01154         AddBitsAndReallocate(3*8);
01155 
01156         if (IsBigEndian()==false)
01157         {
01158             data[( numberOfBitsUsed >> 3 ) + 0] = ((char *)&inTemplateVar.val)[0];
01159             data[( numberOfBitsUsed >> 3 ) + 1] = ((char *)&inTemplateVar.val)[1];
01160             data[( numberOfBitsUsed >> 3 ) + 2] = ((char *)&inTemplateVar.val)[2];
01161         }
01162         else
01163         {
01164             data[( numberOfBitsUsed >> 3 ) + 0] = ((char *)&inTemplateVar.val)[3];
01165             data[( numberOfBitsUsed >> 3 ) + 1] = ((char *)&inTemplateVar.val)[2];
01166             data[( numberOfBitsUsed >> 3 ) + 2] = ((char *)&inTemplateVar.val)[1];
01167         }
01168 
01169         numberOfBitsUsed+=3*8;
01170     }
01171 
01172     template <>
01173         inline void BitStream::Write(const RakNetGUID &inTemplateVar)
01174         {
01175             Write(inTemplateVar.g);
01176         }
01177 
01180     template <>
01181         inline void BitStream::Write(const RakString &inTemplateVar)
01182     {
01183         inTemplateVar.Serialize(this);
01184     }
01185     template <>
01186         inline void BitStream::Write(const RakWString &inTemplateVar)
01187     {
01188         inTemplateVar.Serialize(this);
01189     }
01190     template <>
01191         inline void BitStream::Write(const char * const &inStringVar)
01192     {
01193         RakString::Serialize(inStringVar, this);
01194     }
01195     template <>
01196         inline void BitStream::Write(const wchar_t * const &inStringVar)
01197     {
01198         RakWString::Serialize(inStringVar, this);
01199     }
01200     template <>
01201         inline void BitStream::Write(const unsigned char * const &inTemplateVar)
01202     {
01203         Write((const char*)inTemplateVar);
01204     }
01205     template <>
01206         inline void BitStream::Write(char * const &inTemplateVar)
01207     {
01208         Write((const char*)inTemplateVar);
01209     }
01210     template <>
01211         inline void BitStream::Write(unsigned char * const &inTemplateVar)
01212     {
01213         Write((const char*)inTemplateVar);
01214     }
01215 
01221     template <class templateType>
01222         inline void BitStream::WriteDelta(const templateType &currentValue, const templateType &lastValue)
01223     {
01224         if (currentValue==lastValue)
01225         {
01226             Write(false);
01227         }
01228         else
01229         {
01230             Write(true);
01231             Write(currentValue);
01232         }
01233     }
01234 
01238     template <>
01239         inline void BitStream::WriteDelta(const bool &currentValue, const bool &lastValue)
01240     {
01241         (void) lastValue;
01242 
01243         Write(currentValue);
01244     }
01245 
01248     template <class templateType>
01249         inline void BitStream::WriteDelta(const templateType &currentValue)
01250     {
01251         Write(true);
01252         Write(currentValue);
01253     }
01254 
01261     template <class templateType>
01262         inline void BitStream::WriteCompressed(const templateType &inTemplateVar)
01263     {
01264 #ifdef _MSC_VER
01265 #pragma warning(disable:4127)   // conditional expression is constant
01266 #endif
01267         if (sizeof(inTemplateVar)==1)
01268             WriteCompressed( ( unsigned char* ) & inTemplateVar, sizeof( templateType ) * 8, true );
01269         else
01270         {
01271 #ifndef __BITSTREAM_NATIVE_END
01272 #ifdef _MSC_VER
01273 #pragma warning(disable:4244)   // '=' : conversion from 'unsigned long' to 'unsigned short', possible loss of data
01274 #endif
01275 
01276             if (DoEndianSwap())
01277             {
01278                 unsigned char output[sizeof(templateType)];
01279                 ReverseBytes((unsigned char*)&inTemplateVar, output, sizeof(templateType));
01280                 WriteCompressed( ( unsigned char* ) output, sizeof(templateType) * 8, true );
01281             }
01282             else
01283 #endif
01284                 WriteCompressed( ( unsigned char* ) & inTemplateVar, sizeof(templateType) * 8, true );
01285         }
01286     }
01287 
01288     template <>
01289         inline void BitStream::WriteCompressed(const SystemAddress &inTemplateVar)
01290     {
01291         Write(inTemplateVar);
01292     }
01293 
01294     template <>
01295     inline void BitStream::WriteCompressed(const RakNetGUID &inTemplateVar)
01296     {
01297         Write(inTemplateVar);
01298     }
01299 
01300     template <>
01301     inline void BitStream::WriteCompressed(const uint24_t &var)
01302     {
01303         Write(var);
01304     }
01305 
01306     template <>
01307         inline void BitStream::WriteCompressed(const bool &inTemplateVar)
01308     {
01309         Write(inTemplateVar);
01310     }
01311 
01313     template <>
01314         inline void BitStream::WriteCompressed(const float &inTemplateVar)
01315     {
01316         RakAssert(inTemplateVar > -1.01f && inTemplateVar < 1.01f);
01317         float varCopy=inTemplateVar;
01318         if (varCopy < -1.0f)
01319             varCopy=-1.0f;
01320         if (varCopy > 1.0f)
01321             varCopy=1.0f;
01322         Write((unsigned short)((varCopy+1.0f)*32767.5f));
01323     }
01324 
01326     template <>
01327         inline void BitStream::WriteCompressed(const double &inTemplateVar)
01328     {
01329         RakAssert(inTemplateVar > -1.01 && inTemplateVar < 1.01);
01330         double varCopy=inTemplateVar;
01331         if (varCopy < -1.0f)
01332             varCopy=-1.0f;
01333         if (varCopy > 1.0f)
01334             varCopy=1.0f;
01335         Write((uint32_t)((varCopy+1.0)*2147483648.0));
01336     }
01337 
01339     template <>
01340         inline void BitStream::WriteCompressed(const RakString &inTemplateVar)
01341     {
01342         inTemplateVar.SerializeCompressed(this,0,false);
01343     }
01344     template <>
01345     inline void BitStream::WriteCompressed(const RakWString &inTemplateVar)
01346     {
01347         inTemplateVar.Serialize(this);
01348     }
01349     template <>
01350         inline void BitStream::WriteCompressed(const char * const &inStringVar)
01351     {
01352         RakString::SerializeCompressed(inStringVar,this,0,false);
01353     }
01354     template <>
01355     inline void BitStream::WriteCompressed(const wchar_t * const &inStringVar)
01356     {
01357         RakWString::Serialize(inStringVar,this);
01358     }
01359     template <>
01360         inline void BitStream::WriteCompressed(const unsigned char * const &inTemplateVar)
01361     {
01362         WriteCompressed((const char*) inTemplateVar);
01363     }
01364     template <>
01365         inline void BitStream::WriteCompressed(char * const &inTemplateVar)
01366     {
01367         WriteCompressed((const char*) inTemplateVar);
01368     }
01369     template <>
01370         inline void BitStream::WriteCompressed(unsigned char * const &inTemplateVar)
01371     {
01372         WriteCompressed((const char*) inTemplateVar);
01373     }
01374     
01375 
01384     template <class templateType>
01385         inline void BitStream::WriteCompressedDelta(const templateType &currentValue, const templateType &lastValue)
01386     {
01387         if (currentValue==lastValue)
01388         {
01389             Write(false);
01390         }
01391         else
01392         {
01393             Write(true);
01394             WriteCompressed(currentValue);
01395         }
01396     }
01397 
01401     template <>
01402         inline void BitStream::WriteCompressedDelta(const bool &currentValue, const bool &lastValue)
01403     {
01404         (void) lastValue;
01405 
01406         Write(currentValue);
01407     }
01408 
01411     template <class templateType>
01412         inline void BitStream::WriteCompressedDelta(const templateType &currentValue)
01413     {
01414         Write(true);
01415         WriteCompressed(currentValue);
01416     }
01417 
01420     template <>
01421         inline void BitStream::WriteCompressedDelta(const bool &currentValue)
01422     {
01423         Write(currentValue);
01424     }
01425 
01428     template <class templateType>
01429         inline bool BitStream::Read(templateType &outTemplateVar)
01430     {
01431 #ifdef _MSC_VER
01432 #pragma warning(disable:4127)   // conditional expression is constant
01433 #endif
01434         if (sizeof(outTemplateVar)==1)
01435             return ReadBits( ( unsigned char* ) &outTemplateVar, sizeof(templateType) * 8, true );
01436         else
01437         {
01438 #ifndef __BITSTREAM_NATIVE_END
01439 #ifdef _MSC_VER
01440 #pragma warning(disable:4244)   // '=' : conversion from 'unsigned long' to 'unsigned short', possible loss of data
01441 #endif
01442             if (DoEndianSwap())
01443             {
01444                 unsigned char output[sizeof(templateType)];
01445                 if (ReadBits( ( unsigned char* ) output, sizeof(templateType) * 8, true ))
01446                 {
01447                     ReverseBytes(output, (unsigned char*)&outTemplateVar, sizeof(templateType));
01448                     return true;
01449                 }
01450                 return false;
01451             }
01452             else
01453 #endif
01454                 return ReadBits( ( unsigned char* ) & outTemplateVar, sizeof(templateType) * 8, true );
01455         }
01456     }
01457 
01460     template <>
01461         inline bool BitStream::Read(bool &outTemplateVar)
01462     {
01463         if ( readOffset + 1 > numberOfBitsUsed )
01464             return false;
01465 
01466         if ( data[ readOffset >> 3 ] & ( 0x80 >> ( readOffset & 7 ) ) )   // Is it faster to just write it out here?
01467             outTemplateVar = true;
01468         else
01469             outTemplateVar = false;
01470 
01471         // Has to be on a different line for Mac
01472         readOffset++;
01473 
01474         return true;
01475     }
01476 
01479     template <>
01480         inline bool BitStream::Read(SystemAddress &outTemplateVar)
01481     {
01482         unsigned char ipVersion;
01483         Read(ipVersion);
01484         if (ipVersion==4)
01485         {
01486             outTemplateVar.address.addr4.sin_family=AF_INET;
01487             // Read(var.binaryAddress);
01488             // Don't endian swap the address or port
01489             uint32_t binaryAddress;
01490             ReadBits( ( unsigned char* ) & binaryAddress, sizeof(binaryAddress) * 8, true );
01491             // Unhide the IP address, done to prevent routers from changing it
01492             outTemplateVar.address.addr4.sin_addr.s_addr=~binaryAddress;
01493             bool b = ReadBits(( unsigned char* ) & outTemplateVar.address.addr4.sin_port, sizeof(outTemplateVar.address.addr4.sin_port) * 8, true);
01494             outTemplateVar.debugPort=ntohs(outTemplateVar.address.addr4.sin_port);
01495             return b;
01496         }
01497         else
01498         {
01499 #if RAKNET_SUPPORT_IPV6==1
01500             bool b = ReadBits((unsigned char*) &outTemplateVar.address.addr6, sizeof(outTemplateVar.address.addr6)*8, true);
01501             outTemplateVar.debugPort=ntohs(outTemplateVar.address.addr6.sin6_port);
01502             return b;
01503 #else
01504             return false;
01505 #endif
01506         }   
01507     }
01508 
01509     template <>
01510     inline bool BitStream::Read(uint24_t &outTemplateVar)
01511     {
01512         AlignReadToByteBoundary();
01513         if ( readOffset + 3*8 > numberOfBitsUsed )
01514             return false;
01515 
01516         if (IsBigEndian()==false)
01517         {
01518             ((char *)&outTemplateVar.val)[0]=data[ (readOffset >> 3) + 0];
01519             ((char *)&outTemplateVar.val)[1]=data[ (readOffset >> 3) + 1];
01520             ((char *)&outTemplateVar.val)[2]=data[ (readOffset >> 3) + 2];
01521             ((char *)&outTemplateVar.val)[3]=0;
01522         }
01523         else
01524         {
01525 
01526             ((char *)&outTemplateVar.val)[3]=data[ (readOffset >> 3) + 0];
01527             ((char *)&outTemplateVar.val)[2]=data[ (readOffset >> 3) + 1];
01528             ((char *)&outTemplateVar.val)[1]=data[ (readOffset >> 3) + 2];
01529             ((char *)&outTemplateVar.val)[0]=0;
01530         }
01531 
01532         readOffset+=3*8;
01533         return true;
01534     }
01535 
01536     template <>
01537     inline bool BitStream::Read(RakNetGUID &outTemplateVar)
01538     {
01539         return Read(outTemplateVar.g);
01540     }
01541 
01542 
01543     template <>
01544         inline bool BitStream::Read(RakString &outTemplateVar)
01545     {
01546         return outTemplateVar.Deserialize(this);
01547     }
01548     template <>
01549     inline bool BitStream::Read(RakWString &outTemplateVar)
01550     {
01551         return outTemplateVar.Deserialize(this);
01552     }
01553     template <>
01554         inline bool BitStream::Read(char *&varString)
01555     {
01556         return RakString::Deserialize(varString,this);
01557     }
01558     template <>
01559     inline bool BitStream::Read(wchar_t *&varString)
01560     {
01561         return RakWString::Deserialize(varString,this);
01562     }
01563     template <>
01564         inline bool BitStream::Read(unsigned char *&varString)
01565     {
01566         return RakString::Deserialize((char*) varString,this);
01567     }
01568 
01574     template <class templateType>
01575         inline bool BitStream::ReadDelta(templateType &outTemplateVar)
01576     {
01577         bool dataWritten;
01578         bool success;
01579         success=Read(dataWritten);
01580         if (dataWritten)
01581             success=Read(outTemplateVar);
01582         return success;
01583     }
01584 
01587     template <>
01588         inline bool BitStream::ReadDelta(bool &outTemplateVar)
01589     {
01590         return Read(outTemplateVar);
01591     }
01592 
01599     template <class templateType>
01600         inline bool BitStream::ReadCompressed(templateType &outTemplateVar)
01601     {
01602 #ifdef _MSC_VER
01603 #pragma warning(disable:4127)   // conditional expression is constant
01604 #endif
01605         if (sizeof(outTemplateVar)==1)
01606             return ReadCompressed( ( unsigned char* ) &outTemplateVar, sizeof(templateType) * 8, true );
01607         else
01608         {
01609 #ifndef __BITSTREAM_NATIVE_END
01610             if (DoEndianSwap())
01611             {
01612                 unsigned char output[sizeof(templateType)];
01613                 if (ReadCompressed( ( unsigned char* ) output, sizeof(templateType) * 8, true ))
01614                 {
01615                     ReverseBytes(output, (unsigned char*)&outTemplateVar, sizeof(templateType));
01616                     return true;
01617                 }
01618                 return false;
01619             }
01620             else
01621 #endif
01622                 return ReadCompressed( ( unsigned char* ) & outTemplateVar, sizeof(templateType) * 8, true );
01623         }
01624     }
01625 
01626     template <>
01627         inline bool BitStream::ReadCompressed(SystemAddress &outTemplateVar)
01628     {
01629         return Read(outTemplateVar);
01630     }
01631 
01632     template <>
01633     inline bool BitStream::ReadCompressed(uint24_t &outTemplateVar)
01634     {
01635         return Read(outTemplateVar);
01636     }
01637 
01638     template <>
01639     inline bool BitStream::ReadCompressed(RakNetGUID &outTemplateVar)
01640     {
01641         return Read(outTemplateVar);
01642     }
01643 
01644     template <>
01645         inline bool BitStream::ReadCompressed(bool &outTemplateVar)
01646     {
01647         return Read(outTemplateVar);
01648     }
01649 
01651     template <>
01652         inline bool BitStream::ReadCompressed(float &outTemplateVar)
01653     {
01654         unsigned short compressedFloat;
01655         if (Read(compressedFloat))
01656         {
01657             outTemplateVar = ((float)compressedFloat / 32767.5f - 1.0f);
01658             return true;
01659         }
01660         return false;
01661     }
01662 
01664     template <>
01665         inline bool BitStream::ReadCompressed(double &outTemplateVar)
01666     {
01667         uint32_t compressedFloat;
01668         if (Read(compressedFloat))
01669         {
01670             outTemplateVar = ((double)compressedFloat / 2147483648.0 - 1.0);
01671             return true;
01672         }
01673         return false;
01674     }
01675 
01677     template <>
01678         inline bool BitStream::ReadCompressed(RakString &outTemplateVar)
01679     {
01680         return outTemplateVar.DeserializeCompressed(this,false);
01681     }
01682     template <>
01683     inline bool BitStream::ReadCompressed(RakWString &outTemplateVar)
01684     {
01685         return outTemplateVar.Deserialize(this);
01686     }
01687     template <>
01688     inline bool BitStream::ReadCompressed(char *&outTemplateVar)
01689     {
01690         return RakString::DeserializeCompressed(outTemplateVar,this,false);
01691     }
01692     template <>
01693     inline bool BitStream::ReadCompressed(wchar_t *&outTemplateVar)
01694     {
01695         return RakWString::Deserialize(outTemplateVar,this);
01696     }
01697     template <>
01698     inline bool BitStream::ReadCompressed(unsigned char *&outTemplateVar)
01699     {
01700         return RakString::DeserializeCompressed((char*) outTemplateVar,this,false);
01701     }
01702 
01712     template <class templateType>
01713         inline bool BitStream::ReadCompressedDelta(templateType &outTemplateVar)
01714     {
01715         bool dataWritten;
01716         bool success;
01717         success=Read(dataWritten);
01718         if (dataWritten)
01719             success=ReadCompressed(outTemplateVar);
01720         return success;
01721     }
01722 
01725     template <>
01726         inline bool BitStream::ReadCompressedDelta(bool &outTemplateVar)
01727     {
01728         return Read(outTemplateVar);
01729     }
01730 
01731     template <class destinationType, class sourceType >
01732     void BitStream::WriteCasted( const sourceType &value )
01733     {
01734         destinationType val = (destinationType) value;
01735         Write(val);
01736     }
01737 
01738     template <class templateType, class rangeType>
01739     void BitStream::WriteBitsFromIntegerRange( const templateType value, const rangeType minimum,const rangeType maximum, bool allowOutsideRange )
01740     {
01741         static int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum));
01742         WriteBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
01743     }
01744     template <class templateType, class rangeType>
01745     void BitStream::WriteBitsFromIntegerRange( const templateType value, const rangeType minimum,const rangeType maximum, const int requiredBits, bool allowOutsideRange )
01746     {
01747         RakAssert(maximum>=minimum);
01748         RakAssert(allowOutsideRange==true || (value>=minimum && value<=maximum));
01749         if (allowOutsideRange)
01750         {
01751             if (value<minimum || value>maximum)
01752             {
01753                 Write(true);
01754                 Write(value);
01755                 return;
01756             }
01757             Write(false);
01758         }
01759         templateType valueOffMin=value-minimum;
01760         if (IsBigEndian()==true)
01761         {
01762             unsigned char output[sizeof(templateType)];
01763             ReverseBytes((unsigned char*)&valueOffMin, output, sizeof(templateType));
01764             WriteBits(output,requiredBits);
01765         }
01766         else
01767         {
01768             WriteBits((unsigned char*) &valueOffMin,requiredBits);
01769         }
01770     }
01771 
01772     template <class templateType> // templateType for this function must be a float or double
01773         void BitStream::WriteNormVector( templateType x, templateType y, templateType z )
01774     {
01775 #ifdef _DEBUG
01776         RakAssert(x <= 1.01 && y <= 1.01 && z <= 1.01 && x >= -1.01 && y >= -1.01 && z >= -1.01);
01777 #endif
01778 
01779         WriteFloat16((float)x,-1.0f,1.0f);
01780         WriteFloat16((float)y,-1.0f,1.0f);
01781         WriteFloat16((float)z,-1.0f,1.0f);
01782     }
01783 
01784     template <class templateType> // templateType for this function must be a float or double
01785         void BitStream::WriteVector( templateType x, templateType y, templateType z )
01786     {
01787         templateType magnitude = sqrt(x * x + y * y + z * z);
01788         Write((float)magnitude);
01789         if (magnitude > 0.00001f)
01790         {
01791             WriteCompressed((float)(x/magnitude));
01792             WriteCompressed((float)(y/magnitude));
01793             WriteCompressed((float)(z/magnitude));
01794             //  Write((unsigned short)((x/magnitude+1.0f)*32767.5f));
01795             //  Write((unsigned short)((y/magnitude+1.0f)*32767.5f));
01796             //  Write((unsigned short)((z/magnitude+1.0f)*32767.5f));
01797         }
01798     }
01799 
01800     template <class templateType> // templateType for this function must be a float or double
01801         void BitStream::WriteNormQuat( templateType w, templateType x, templateType y, templateType z)
01802     {
01803         Write((bool)(w<0.0));
01804         Write((bool)(x<0.0));
01805         Write((bool)(y<0.0));
01806         Write((bool)(z<0.0));
01807         Write((unsigned short)(fabs(x)*65535.0));
01808         Write((unsigned short)(fabs(y)*65535.0));
01809         Write((unsigned short)(fabs(z)*65535.0));
01810         // Leave out w and calculate it on the target
01811     }
01812 
01813     template <class templateType> // templateType for this function must be a float or double
01814         void BitStream::WriteOrthMatrix(
01815         templateType m00, templateType m01, templateType m02,
01816         templateType m10, templateType m11, templateType m12,
01817         templateType m20, templateType m21, templateType m22 )
01818     {
01819 
01820         double qw;
01821         double qx;
01822         double qy;
01823         double qz;
01824 
01825         // Convert matrix to quat
01826         // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
01827         float sum;
01828         sum = 1 + m00 + m11 + m22;
01829         if (sum < 0.0f) sum=0.0f;
01830         qw = sqrt( sum  ) / 2;
01831         sum = 1 + m00 - m11 - m22;
01832         if (sum < 0.0f) sum=0.0f;
01833         qx = sqrt( sum  ) / 2;
01834         sum = 1 - m00 + m11 - m22;
01835         if (sum < 0.0f) sum=0.0f;
01836         qy = sqrt( sum  ) / 2;
01837         sum = 1 - m00 - m11 + m22;
01838         if (sum < 0.0f) sum=0.0f;
01839         qz = sqrt( sum  ) / 2;
01840         if (qw < 0.0) qw=0.0;
01841         if (qx < 0.0) qx=0.0;
01842         if (qy < 0.0) qy=0.0;
01843         if (qz < 0.0) qz=0.0;
01844         qx = _copysign( (double) qx, (double) (m21 - m12) );
01845         qy = _copysign( (double) qy, (double) (m02 - m20) );
01846         qz = _copysign( (double) qz, (double) (m10 - m01) );
01847 
01848         WriteNormQuat(qw,qx,qy,qz);
01849     }
01850 
01851     template <class serializationType, class sourceType >
01852     bool BitStream::ReadCasted( sourceType &value )
01853     {
01854         serializationType val;
01855         bool success = Read(val);
01856         value=(sourceType) val;
01857         return success;
01858     }
01859 
01860     template <class templateType, class rangeType>
01861     bool BitStream::ReadBitsFromIntegerRange( templateType &value, const rangeType minimum, const rangeType maximum, bool allowOutsideRange )
01862     {
01863         static int requiredBits=BYTES_TO_BITS(sizeof(templateType))-NumberOfLeadingZeroes(templateType(maximum-minimum));
01864         return ReadBitsFromIntegerRange(value,minimum,maximum,requiredBits,allowOutsideRange);
01865     }
01866     template <class templateType, class rangeType>
01867     bool BitStream::ReadBitsFromIntegerRange( templateType &value, const rangeType minimum, const rangeType maximum, const int requiredBits, bool allowOutsideRange )
01868     {
01869         RakAssert(maximum>=minimum);
01870         if (allowOutsideRange)
01871         {
01872             bool isOutsideRange;
01873             Read(isOutsideRange);
01874             if (isOutsideRange)
01875                 return Read(value);
01876         }
01877         unsigned char output[sizeof(templateType)];
01878         memset(output,0,sizeof(output));
01879         bool success = ReadBits(output,requiredBits);
01880         if (success)
01881         {
01882             if (IsBigEndian()==true)
01883                 ReverseBytesInPlace(output,sizeof(output));
01884             memcpy(&value,output,sizeof(output));
01885 
01886             value+=minimum;
01887         }
01888 
01889         return success;
01890     }
01891 
01892     template <class templateType> // templateType for this function must be a float or double
01893         bool BitStream::ReadNormVector( templateType &x, templateType &y, templateType &z )
01894     {
01895         float xIn,yIn,zIn;
01896         ReadFloat16(xIn,-1.0f,1.0f);
01897         ReadFloat16(yIn,-1.0f,1.0f);
01898         ReadFloat16(zIn,-1.0f,1.0f);
01899         x=xIn;
01900         y=yIn;
01901         z=zIn;
01902         return true;
01903     }
01904 
01905     template <class templateType> // templateType for this function must be a float or double
01906         bool BitStream::ReadVector( templateType &x, templateType &y, templateType &z )
01907     {
01908         float magnitude;
01909         //unsigned short sx,sy,sz;
01910         if (!Read(magnitude))
01911             return false;
01912         if (magnitude>0.00001f)
01913         {
01914             //  Read(sx);
01915             //  Read(sy);
01916             //  if (!Read(sz))
01917             //      return false;
01918             //  x=((float)sx / 32767.5f - 1.0f) * magnitude;
01919             //  y=((float)sy / 32767.5f - 1.0f) * magnitude;
01920             //  z=((float)sz / 32767.5f - 1.0f) * magnitude;
01921             float cx,cy,cz;
01922             ReadCompressed(cx);
01923             ReadCompressed(cy);
01924             if (!ReadCompressed(cz))
01925                 return false;
01926             x=cx;
01927             y=cy;
01928             z=cz;
01929             x*=magnitude;
01930             y*=magnitude;
01931             z*=magnitude;
01932         }
01933         else
01934         {
01935             x=0.0;
01936             y=0.0;
01937             z=0.0;
01938         }
01939         return true;
01940     }
01941 
01942     template <class templateType> // templateType for this function must be a float or double
01943         bool BitStream::ReadNormQuat( templateType &w, templateType &x, templateType &y, templateType &z)
01944     {
01945         bool cwNeg=false, cxNeg=false, cyNeg=false, czNeg=false;
01946         unsigned short cx,cy,cz;
01947         Read(cwNeg);
01948         Read(cxNeg);
01949         Read(cyNeg);
01950         Read(czNeg);
01951         Read(cx);
01952         Read(cy);
01953         if (!Read(cz))
01954             return false;
01955 
01956         // Calculate w from x,y,z
01957         x=(templateType)(cx/65535.0);
01958         y=(templateType)(cy/65535.0);
01959         z=(templateType)(cz/65535.0);
01960         if (cxNeg) x=-x;
01961         if (cyNeg) y=-y;
01962         if (czNeg) z=-z;
01963         float difference = 1.0f - x*x - y*y - z*z;
01964         if (difference < 0.0f)
01965             difference=0.0f;
01966         w = (templateType)(sqrt(difference));
01967         if (cwNeg)
01968             w=-w;
01969 
01970         return true;
01971     }
01972 
01973     template <class templateType> // templateType for this function must be a float or double
01974         bool BitStream::ReadOrthMatrix(
01975         templateType &m00, templateType &m01, templateType &m02,
01976         templateType &m10, templateType &m11, templateType &m12,
01977         templateType &m20, templateType &m21, templateType &m22 )
01978     {
01979         float qw,qx,qy,qz;
01980         if (!ReadNormQuat(qw,qx,qy,qz))
01981             return false;
01982 
01983         // Quat to orthogonal rotation matrix
01984         // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm
01985         double sqw = (double)qw*(double)qw;
01986         double sqx = (double)qx*(double)qx;
01987         double sqy = (double)qy*(double)qy;
01988         double sqz = (double)qz*(double)qz;
01989         m00 =  (templateType)(sqx - sqy - sqz + sqw); // since sqw + sqx + sqy + sqz =1
01990         m11 = (templateType)(-sqx + sqy - sqz + sqw);
01991         m22 = (templateType)(-sqx - sqy + sqz + sqw);
01992 
01993         double tmp1 = (double)qx*(double)qy;
01994         double tmp2 = (double)qz*(double)qw;
01995         m10 = (templateType)(2.0 * (tmp1 + tmp2));
01996         m01 = (templateType)(2.0 * (tmp1 - tmp2));
01997 
01998         tmp1 = (double)qx*(double)qz;
01999         tmp2 = (double)qy*(double)qw;
02000         m20 =(templateType)(2.0 * (tmp1 - tmp2));
02001         m02 = (templateType)(2.0 * (tmp1 + tmp2));
02002         tmp1 = (double)qy*(double)qz;
02003         tmp2 = (double)qx*(double)qw;
02004         m21 = (templateType)(2.0 * (tmp1 + tmp2));
02005         m12 = (templateType)(2.0 * (tmp1 - tmp2));
02006 
02007         return true;
02008     }
02009 
02010     template <class templateType>
02011     BitStream& operator<<(BitStream& out, templateType& c)
02012     {
02013         out.Write(c);
02014         return out;
02015     }
02016     template <class templateType>
02017     BitStream& operator>>(BitStream& in, templateType& c)
02018     {
02019         bool success = in.Read(c);
02020         RakAssert(success);
02021         return in;
02022     }
02023 
02024 }
02025 
02026 #ifdef _MSC_VER
02027 #pragma warning( pop )
02028 #endif
02029 
02030 #endif
02031 
02032 #endif // VC6

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net