diff --git a/include/blitz/protocol/ByteBuffer.h b/include/blitz/protocol/ByteBuffer.h index 5540bae..95adeda 100644 --- a/include/blitz/protocol/ByteBuffer.h +++ b/include/blitz/protocol/ByteBuffer.h @@ -2,6 +2,7 @@ #include #include +#include #include namespace blitz { @@ -9,25 +10,17 @@ namespace protocol { class PlayerInfo; -#define Operators(Type, GodotType) \ - ByteBuffer& operator>>(Type& a_Data) { \ - a_Data = m_Buffer.decode_##GodotType(m_ReadOffset); \ - m_ReadOffset += sizeof(a_Data); \ - return *this; \ - } \ - \ - ByteBuffer& operator<<(Type a_Data) { \ - m_Buffer.resize(m_Buffer.size() + sizeof(a_Data)); \ - m_Buffer.encode_##GodotType(m_Buffer.size() - sizeof(a_Data), a_Data); \ - return *this; \ - } - class ByteBuffer { private: godot::PackedByteArray m_Buffer; std::size_t m_ReadOffset; public: + class ReadError : public std::runtime_error { + public: + ReadError(const std::string& msg) : std::runtime_error(msg) {} + }; + ByteBuffer(godot::PackedByteArray&& a_Buffer) : m_Buffer(std::move(a_Buffer)), m_ReadOffset(0) {} ByteBuffer() : m_ReadOffset(0) { m_Buffer.resize(0); @@ -42,18 +35,30 @@ class ByteBuffer { } // Integers - Operators(int8_t, s8); - Operators(uint8_t, u8); - Operators(int16_t, s16); - Operators(uint16_t, u16); - Operators(int32_t, s32); - Operators(uint32_t, u32); - Operators(int64_t, s64); - Operators(uint64_t, u64); + ByteBuffer& operator<<(int8_t a_Data); + ByteBuffer& operator>>(int8_t& a_Data); + ByteBuffer& operator<<(uint8_t a_Data); + ByteBuffer& operator>>(uint8_t& a_Data); - // Reals - Operators(float, float); - Operators(double, double); + ByteBuffer& operator<<(int16_t a_Data); + ByteBuffer& operator>>(int16_t& a_Data); + ByteBuffer& operator<<(uint16_t a_Data); + ByteBuffer& operator>>(uint16_t& a_Data); + + ByteBuffer& operator<<(int32_t a_Data); + ByteBuffer& operator>>(int32_t& a_Data); + ByteBuffer& operator<<(uint32_t a_Data); + ByteBuffer& operator>>(uint32_t& a_Data); + + ByteBuffer& operator<<(int64_t a_Data); + ByteBuffer& operator>>(int64_t& a_Data); + ByteBuffer& operator<<(uint64_t a_Data); + ByteBuffer& operator>>(uint64_t& a_Data); + + ByteBuffer& operator<<(float a_Data); + ByteBuffer& operator>>(float& a_Data); + ByteBuffer& operator<<(double a_Data); + ByteBuffer& operator>>(double& a_Data); ByteBuffer& operator<<(const godot::String& a_Data); ByteBuffer& operator>>(godot::String& a_Data); diff --git a/src/blitz/protocol/ByteBuffer.cpp b/src/blitz/protocol/ByteBuffer.cpp index 1916f7e..f0572fd 100644 --- a/src/blitz/protocol/ByteBuffer.cpp +++ b/src/blitz/protocol/ByteBuffer.cpp @@ -5,6 +5,36 @@ namespace blitz { namespace protocol { +#define Operators(Type, GodotType) \ + ByteBuffer& ByteBuffer::operator>>(Type& a_Data) { \ + if (sizeof(a_Data) + m_ReadOffset > m_Buffer.size()) { \ + throw ReadError("Buffer is too small ! Can't read " #Type); \ + } \ + a_Data = m_Buffer.decode_##GodotType(m_ReadOffset); \ + m_ReadOffset += sizeof(a_Data); \ + return *this; \ + } \ + \ + ByteBuffer& ByteBuffer::operator<<(Type a_Data) { \ + m_Buffer.resize(m_Buffer.size() + sizeof(a_Data)); \ + m_Buffer.encode_##GodotType(m_Buffer.size() - sizeof(a_Data), a_Data); \ + return *this; \ + } + +// Integers +Operators(int8_t, s8); +Operators(uint8_t, u8); +Operators(int16_t, s16); +Operators(uint16_t, u16); +Operators(int32_t, s32); +Operators(uint32_t, u32); +Operators(int64_t, s64); +Operators(uint64_t, u64); + +// Reals +Operators(float, float); +Operators(double, double); + ByteBuffer& ByteBuffer::operator>>(PlayerInfo& a_Data) { *this >> a_Data.m_PlayerId >> a_Data.m_PlayerName; return *this; @@ -27,9 +57,9 @@ ByteBuffer& ByteBuffer::operator>>(godot::Vector3& a_Data) { ByteBuffer& ByteBuffer::operator>>(godot::String& a_Data) { int nullPos = m_Buffer.find(0, m_ReadOffset); - // TODO: error handling if (nullPos < 0) - return *this; + throw ReadError("String does not have an and in buffer !"); + godot::PackedByteArray stringBuffer = m_Buffer.slice(m_ReadOffset, nullPos); a_Data = stringBuffer.get_string_from_utf8(); diff --git a/src/blitz/protocol/PacketSerializer.cpp b/src/blitz/protocol/PacketSerializer.cpp index 74b7bb1..5df73b3 100644 --- a/src/blitz/protocol/PacketSerializer.cpp +++ b/src/blitz/protocol/PacketSerializer.cpp @@ -68,7 +68,8 @@ class Deserializer : public PacketVisitor { bool Deserialize(const PacketPtr& a_Packet) { try { Check(*a_Packet.get()); - } catch (std::exception& e) { + } catch (ByteBuffer::ReadError& e) { + godot::UtilityFunctions::printerr("[PacketSerializer::Deserializer] ", e.what()); return false; } return true; @@ -109,6 +110,7 @@ std::unique_ptr Deserialize(godot::PackedByteArray& a_Data) { const PacketPtr& emptyPacket = PacketFactory::CreateReadOnlyPacket(packetType); Deserializer deserializer(std::move(stream)); + if (deserializer.Deserialize(emptyPacket)) { PacketPtr packet = std::move(deserializer.GetPacket()); return packet;