49 lines
1.0 KiB
C++
49 lines
1.0 KiB
C++
#include "VarInt.h"
|
|
|
|
#include "DataBuffer.h"
|
|
#include <stdexcept>
|
|
|
|
static constexpr int SEGMENT_BITS = 0x7F;
|
|
static constexpr int CONTINUE_BIT = 0x80;
|
|
|
|
std::size_t VarInt::GetSerializedLength() const {
|
|
DataBuffer buffer;
|
|
buffer << *this;
|
|
return buffer.GetSize();
|
|
}
|
|
|
|
DataBuffer& operator<<(DataBuffer& out, const VarInt& var) {
|
|
std::uint64_t value = var.m_Value;
|
|
while (true) {
|
|
if ((value & ~static_cast<std::uint64_t>(SEGMENT_BITS)) == 0) {
|
|
out << static_cast<std::uint8_t>(value);
|
|
return out;
|
|
}
|
|
|
|
out << static_cast<std::uint8_t>((value & SEGMENT_BITS) | CONTINUE_BIT);
|
|
|
|
value >>= 7;
|
|
}
|
|
}
|
|
|
|
DataBuffer& operator>>(DataBuffer& in, VarInt& var) {
|
|
var.m_Value = 0;
|
|
unsigned int position = 0;
|
|
std::uint8_t currentByte;
|
|
|
|
while (true) {
|
|
in.ReadSome(¤tByte, 1);
|
|
var.m_Value |= static_cast<std::uint64_t>(currentByte & SEGMENT_BITS) << position;
|
|
|
|
if ((currentByte & CONTINUE_BIT) == 0)
|
|
break;
|
|
|
|
position += 7;
|
|
|
|
if (position >= 8 * sizeof(var.m_Value))
|
|
throw std::runtime_error("VarInt is too big");
|
|
}
|
|
|
|
return in;
|
|
}
|