#pragma once #include "../Common.h" #include #include #include using std::string; namespace Feather::Network { // Class to read packet data, such as is produced by NetworkMessage class PacketReader { public: PacketReader(const uint8_t *const dataPtr) : m_data(dataPtr), m_length(ReadVarInt()) { } inline uint8_t ReadByte() { return m_data[m_offset++]; } inline int ReadVarInt() { int numRead = 0; int result = 0; uint8_t read; do { read = ReadByte(); int value = (read & 0b01111111); result |= (value << (7 * numRead)); numRead++; if (numRead > 5) { // complain //throw new RuntimeException("VarInt is too big"); } } while ((read & 0b10000000) != 0); return result; } inline uint16_t ReadUnsignedShort() { return (ReadByte() << 8) | ReadByte(); } inline int64_t ReadLong() { int64_t value = 0; // FIXME value |= (ReadByte() << 56); value |= (ReadByte() << 48); value |= (ReadByte() << 40); value |= (ReadByte() << 32); value |= (ReadByte() << 24); value |= (ReadByte() << 16); value |= (ReadByte() << 8); value |= (ReadByte() << 0); return value; } string ReadString() { int size = ReadVarInt(); string str; for (int i = 0; i < size; i++) { str += ReadByte(); } //printf("Read string of length %d: %s\n", size, str); return str; } uint32_t Length() const { return m_length; } private: const uint8_t *const m_data; const uint32_t m_length; uint32_t m_offset = 0; }; }