• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

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 "RakAssert.h"
00023 #include <math.h>
00024 #include <float.h>
00025 
00026 #ifdef _MSC_VER
00027 #pragma warning( push )
00028 #endif
00029 
00030 // MSWin uses _copysign, others use copysign...
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                 // Destructor
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> // templateType for this function must be a float or double
00171                         bool SerializeNormVector(bool writeToBitstream,  templateType &x, templateType &y, templateType &z );
00172 
00180                 template <class templateType> // templateType for this function must be a float or double
00181                         bool SerializeVector(bool writeToBitstream,  templateType &x, templateType &y, templateType &z );
00182 
00190                 template <class templateType> // templateType for this function must be a float or double
00191                         bool SerializeNormQuat(bool writeToBitstream,  templateType &w, templateType &x, templateType &y, templateType &z);
00192 
00197                 template <class templateType> // templateType for this function must be a float or double
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                 // TODO - RakNet 4 Remove write, use only the WriteRef version, but rename it to Write
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> // templateType for this function must be a float or double
00370                 void WriteNormVector( templateType x, templateType y, templateType z );
00371 
00378                 template <class templateType> // templateType for this function must be a float or double
00379                 void WriteVector( templateType x, templateType y, templateType z );
00380 
00386                 template <class templateType> // templateType for this function must be a float or double
00387                 void WriteNormQuat( templateType w, templateType x, templateType y, templateType z);
00388 
00392                 template <class templateType> // templateType for this function must be a float or double
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> // templateType for this function must be a float or double
00439                 bool ReadNormVector( templateType &x, templateType &y, templateType &z );
00440 
00448                 template <class templateType> // templateType for this function must be a float or double
00449                 bool ReadVector( templateType &x, templateType &y, templateType &z );
00450 
00457                 template <class templateType> // templateType for this function must be a float or double
00458                 bool ReadNormQuat( templateType &w, templateType &x, templateType &y, templateType &z);
00459 
00464                 template <class templateType> // templateType for this function must be a float or double
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                 // Endian swap bytes already in the bitstream
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                 // Used for VC7
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                 // Not inline, won't compile on PC due to winsock include errors
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 //Stoppedhere
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                 // Hide the address so routers don't modify it
01117                 SystemAddress var2=inTemplateVar;
01118                 var2.binaryAddress=~inTemplateVar.binaryAddress;
01119                 // Don't endian swap the address
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 //              if (NetworkID::IsPeerToPeerMode()) // Use the function rather than directly access the member or DLL users will get an undefined external error
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                 Write(var.guid);
01179                 Write(var.systemAddress);
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         template <>
01238                 inline void BitStream::WriteDelta(SystemAddress currentValue, SystemAddress lastValue)
01239         {
01240                 if (currentValue==lastValue)
01241                 {
01242                         Write(false);
01243                 }
01244                 else
01245                 {
01246                         Write(true);
01247                         Write(currentValue);
01248                 }
01249         }
01250 
01251         template <>
01252                 inline void BitStream::WriteDelta(RakNetGUID currentValue, RakNetGUID lastValue)
01253                 {
01254                         if (currentValue==lastValue)
01255                         {
01256                                 Write(false);
01257                         }
01258                         else
01259                         {
01260                                 Write(true);
01261                                 Write(currentValue);
01262                         }
01263                 }
01264 
01270         template <>
01271                 inline void BitStream::WriteDelta(NetworkID currentValue, NetworkID lastValue)
01272         {
01273                 if (currentValue==lastValue)
01274                 {
01275                         Write(false);
01276                 }
01277                 else
01278                 {
01279                         Write(true);
01280                         Write(currentValue);
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 ) ) )   // Is it faster to just write it out here?
01543                         outTemplateVar = true;
01544                 else
01545                         outTemplateVar = false;
01546 
01547                 // Has to be on a different line for Mac
01548                 readOffset++;
01549 
01550                 return true;
01551         }
01552 
01555         template <>
01556                 inline bool BitStream::Read(SystemAddress &outTemplateVar)
01557         {
01558                 // Read(var.binaryAddress);
01559                 // Don't endian swap the address
01560                 ReadBits( ( unsigned char* ) & outTemplateVar.binaryAddress, sizeof(outTemplateVar.binaryAddress) * 8, true );
01561                 // Unhide the IP address, done to prevent routers from changing it
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                 //if (NetworkID::IsPeerToPeerMode()) // Use the function rather than directly access the member or DLL users will get an undefined external error
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                 Read(var.guid);
01623                 Read(var.systemAddress);
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> // templateType for this function must be a float or double
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> // templateType for this function must be a float or double
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                         //      Write((unsigned short)((x/magnitude+1.0f)*32767.5f));
01868                         //      Write((unsigned short)((y/magnitude+1.0f)*32767.5f));
01869                         //      Write((unsigned short)((z/magnitude+1.0f)*32767.5f));
01870                 }
01871         }
01872 
01873         template <class templateType> // templateType for this function must be a float or double
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                 // Leave out w and calculate it on the target
01884         }
01885 
01886         template <class templateType> // templateType for this function must be a float or double
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                 // Convert matrix to quat
01899                 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
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> // templateType for this function must be a float or double
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> // templateType for this function must be a float or double
01979                 bool BitStream::ReadVector( templateType &x, templateType &y, templateType &z )
01980         {
01981                 float magnitude;
01982                 //unsigned short sx,sy,sz;
01983                 if (!Read(magnitude))
01984                         return false;
01985                 if (magnitude>0.00001f)
01986                 {
01987                         //      Read(sx);
01988                         //      Read(sy);
01989                         //      if (!Read(sz))
01990                         //              return false;
01991                         //      x=((float)sx / 32767.5f - 1.0f) * magnitude;
01992                         //      y=((float)sy / 32767.5f - 1.0f) * magnitude;
01993                         //      z=((float)sz / 32767.5f - 1.0f) * magnitude;
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> // templateType for this function must be a float or double
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                 // Calculate w from x,y,z
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> // templateType for this function must be a float or double
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                 // Quat to orthogonal rotation matrix
02057                 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm
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); // since sqw + sqx + sqy + sqz =1
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

Generated on Thu Sep 30 2010 01:27:21 for RakNet by  doxygen 1.7.1