aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared/Packets/ByteBuffer.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/shared/Packets/ByteBuffer.h')
-rw-r--r--src/server/shared/Packets/ByteBuffer.h55
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