diff options
Diffstat (limited to 'src/server/shared/Packets/ByteBuffer.h')
-rw-r--r-- | src/server/shared/Packets/ByteBuffer.h | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index d51fee27d24..9a4761ff3e0 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -159,9 +159,6 @@ class TC_SHARED_API ByteBuffer void ResetBitPos() { - if (_bitpos > 7) - return; - _bitpos = 8; _curbitval = 0; } @@ -184,14 +181,13 @@ class TC_SHARED_API ByteBuffer bool ReadBit() { - ++_bitpos; - if (_bitpos > 7) + if (_bitpos >= 8) { - _curbitval = read<uint8>(); + read(&_curbitval, 1); _bitpos = 0; } - return ((_curbitval >> (7 - _bitpos)) & 1) != 0; + return ((_curbitval >> (8 - ++_bitpos)) & 1) != 0; } void WriteBits(uint64 value, int32 bits) @@ -236,8 +232,34 @@ class TC_SHARED_API ByteBuffer uint32 ReadBits(int32 bits) { uint32 value = 0; - for (int32 i = bits - 1; i >= 0; --i) - value |= uint32(ReadBit()) << i; + if (bits > 8 - int32(_bitpos)) + { + // first retriever whatever is left in the bit buffer + int32 bitsInBuffer = 8 - _bitpos; + value = (_curbitval & ((UI64LIT(1) << bitsInBuffer) - 1)) << (bits - bitsInBuffer); + bits -= bitsInBuffer; + + // then read as many full bytes as possible + while (bits >= 8) + { + bits -= 8; + value |= read<uint8>() << bits; + } + + // and finally any remaining bits + if (bits) + { + read(&_curbitval, 1); + value |= (_curbitval >> (8 - bits)) & ((UI64LIT(1) << bits) - 1); + _bitpos = bits; + } + } + else + { + // entire value is in the bit buffer + value = (_curbitval >> (8 - _bitpos - bits)) & ((UI64LIT(1) << bits) - 1); + _bitpos += bits; + } return value; } @@ -667,8 +689,8 @@ class TC_SHARED_API ByteBuffer std::vector<uint8> _storage; }; -/// @todo Make a ByteBuffer.cpp and move all this inlining to it. -template <> inline std::string ByteBuffer::read<std::string>() +template <> +inline std::string ByteBuffer::read<std::string>() { return std::string(ReadCString()); } @@ -691,4 +713,15 @@ inline void ByteBuffer::read_skip<std::string>() read_skip<char*>(); } +extern template uint8 ByteBuffer::read<uint8>(); +extern template uint16 ByteBuffer::read<uint16>(); +extern template uint32 ByteBuffer::read<uint32>(); +extern template uint64 ByteBuffer::read<uint64>(); +extern template int8 ByteBuffer::read<int8>(); +extern template int16 ByteBuffer::read<int16>(); +extern template int32 ByteBuffer::read<int32>(); +extern template int64 ByteBuffer::read<int64>(); +extern template float ByteBuffer::read<float>(); +extern template double ByteBuffer::read<double>(); + #endif |