From bce37f59df17c2381057086e581b214b2d165c41 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Thu, 31 Jul 2025 15:01:37 +0200 Subject: [PATCH] allow message serialization through DataBuffer --- include/sp/common/DataBuffer.h | 198 +----------------------------- include/sp/common/DataBuffer.inl | 201 +++++++++++++++++++++++++++++++ include/sp/io/MessageSerialize.h | 47 ++++++++ 3 files changed, 250 insertions(+), 196 deletions(-) create mode 100644 include/sp/common/DataBuffer.inl create mode 100644 include/sp/io/MessageSerialize.h diff --git a/include/sp/common/DataBuffer.h b/include/sp/common/DataBuffer.h index 3d33a43..8b5af48 100644 --- a/include/sp/common/DataBuffer.h +++ b/include/sp/common/DataBuffer.h @@ -84,97 +84,6 @@ class DataBuffer { */ DataBuffer& operator<<(const DataBuffer& data); - /** - * \brief Append a pointer to the buffer - * \param data The data to append - */ - template - DataBuffer& operator<<(const std::shared_ptr& data) { - return *this << *data; - } - - /** - * \brief Append a pointer to the buffer - * \param data The data to append - */ - template - DataBuffer& operator<<(const std::unique_ptr& data) { - return *this << *data; - } - - /** - * \brief Append a vector to the buffer by first writing the size - * \param data The vector to append - */ - template - DataBuffer& operator<<(const std::vector& data) { - *this << VarInt{data.size()}; - for (const auto& element : data) { - *this << element; - } - return *this; - } - - /** - * \brief Append a list to the buffer by first writing the size - * \param data The list to append - */ - template - DataBuffer& operator<<(const std::list& data) { - *this << VarInt{data.size()}; - for (const auto& element : data) { - *this << element; - } - return *this; - } - - /** - * \brief Append a map to the buffer by first writing the size - * \param data The map to append - */ - template - DataBuffer& operator<<(const std::map& data) { - *this << VarInt{data.size()}; - for (const auto& [key, value] : data) { - *this << key << value; - } - return *this; - } - - /** - * \brief Append a map to the buffer by first writing the size - * \param data The map to append - */ - template - DataBuffer& operator<<(const std::unordered_map& data) { - *this << VarInt{data.size()}; - for (const auto& [key, value] : data) { - *this << key << value; - } - return *this; - } - - /** - * \brief Append a pair to the buffer - * \param data The pair to append - */ - template - DataBuffer& operator<<(const std::pair& data) { - return *this << data.first << data.second; - } - - /** - * \brief Append an array to the buffer by first writing the size - * \param data The buffer to append - */ - template - DataBuffer& operator<<(const std::array& data) { - for (const auto& element : data) { - *this << element; - } - return *this; - } - /** * \brief Read data into a_Data * \warning No endian checks @@ -209,111 +118,6 @@ class DataBuffer { */ DataBuffer& operator>>(std::string& str); - /** - * \brief Read a pointer - */ - template - DataBuffer& operator>>(std::shared_ptr& data) { - data = std::make_shared(); - return *this >> *data; - } - - /** - * \brief Read a pointer - */ - template - DataBuffer& operator>>(std::unique_ptr& data) { - data = std::make_unique(); - return *this >> *data; - } - - /** - * \brief Read a vector (size + data) from the buffer - * \pre The vector is assumed to be empty - */ - template - DataBuffer& operator>>(std::vector& data) { - VarInt arraySize; - *this >> arraySize; - for (std::size_t i = 0; i < arraySize.GetValue(); i++) { - T newElement; - *this >> newElement; - data.push_back(newElement); - } - return *this; - } - - /** - * \brief Read a list (size + data) from the buffer - * \pre The list is assumed to be empty - */ - template - DataBuffer& operator>>(std::list& data) { - VarInt arraySize; - *this >> arraySize; - for (std::size_t i = 0; i < arraySize.GetValue(); i++) { - T newElement; - *this >> newElement; - data.push_back(newElement); - } - return *this; - } - - /** - * \brief Read a map (size + data) from the buffer - * \pre The map is assumed to be empty - */ - template - DataBuffer& operator>>(std::map& data) { - VarInt mapSize; - *this >> mapSize; - for (std::size_t i = 0; i < mapSize.GetValue(); i++) { - K newKey; - V newValue; - *this >> newKey >> newValue; - data.emplace(newKey, newValue); - } - return *this; - } - - /** - * \brief Read a map (size + data) from the buffer - * \pre The map is assumed to be empty - */ - template - DataBuffer& operator>>(std::unordered_map& data) { - VarInt mapSize; - *this >> mapSize; - for (std::size_t i = 0; i < mapSize.GetValue(); i++) { - K newKey; - V newValue; - *this >> newKey >> newValue; - data.emplace(newKey, newValue); - } - return *this; - } - - /** - * \brief Read a pair - */ - template - DataBuffer& operator>>(std::pair& data) { - return *this >> data.first >> data.second; - } - - /** - * \brief Read an array from the buffer - */ - template - DataBuffer& operator>>(std::array& data) { - for (std::size_t i = 0; i < Size; i++) { - T newElement; - *this >> newElement; - data[i] = newElement; - } - return *this; - } - /** * \brief Write some data to the buffer * \param buffer The buffer to write @@ -459,3 +263,5 @@ class DataBuffer { std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer); } // namespace sp + +#include "DataBuffer.inl" \ No newline at end of file diff --git a/include/sp/common/DataBuffer.inl b/include/sp/common/DataBuffer.inl new file mode 100644 index 0000000..f8dead8 --- /dev/null +++ b/include/sp/common/DataBuffer.inl @@ -0,0 +1,201 @@ +#pragma once + +namespace sp { + +/** + * \brief Append a pointer to the buffer + * \param data The data to append + */ +template >> +DataBuffer& operator<<(DataBuffer& buffer, const std::shared_ptr& data) { + return buffer << *data; +} + +/** + * \brief Append a pointer to the buffer + * \param data The data to append + */ +template >> +DataBuffer& operator<<(DataBuffer& buffer, const std::unique_ptr& data) { + return buffer << *data; +} + +/** + * \brief Append a vector to the buffer by first writing the size + * \param data The vector to append + */ +template +DataBuffer& operator<<(DataBuffer& buffer, const std::vector& data) { + buffer << VarInt{data.size()}; + for (const auto& element : data) { + buffer << element; + } + return buffer; +} + +/** + * \brief Append a list to the buffer by first writing the size + * \param data The list to append + */ +template +DataBuffer& operator<<(DataBuffer& buffer, const std::list& data) { + buffer << VarInt{data.size()}; + for (const auto& element : data) { + buffer << element; + } + return buffer; +} + +/** + * \brief Append a map to the buffer by first writing the size + * \param data The map to append + */ +template +DataBuffer& operator<<(DataBuffer& buffer, const std::map& data) { + buffer << VarInt{data.size()}; + for (const auto& [key, value] : data) { + buffer << key << value; + } + return buffer; +} + +/** + * \brief Append a map to the buffer by first writing the size + * \param data The map to append + */ +template +DataBuffer& operator<<(DataBuffer& buffer, const std::unordered_map& data) { + buffer << VarInt{data.size()}; + for (const auto& [key, value] : data) { + buffer << key << value; + } + return buffer; +} + +/** + * \brief Append a pair to the buffer + * \param data The pair to append + */ +template +DataBuffer& operator<<(DataBuffer& buffer, const std::pair& data) { + return buffer << data.first << data.second; +} + +/** + * \brief Append an array to the buffer by first writing the size + * \param data The buffer to append + */ +template +DataBuffer& operator<<(DataBuffer& buffer, const std::array& data) { + for (const auto& element : data) { + buffer << element; + } + return buffer; +} + +/** + * \brief Read a pointer + */ +template >> +DataBuffer& operator>>(DataBuffer& buffer, std::shared_ptr& data) { + data = std::make_shared(); + return buffer >> *data; +} + +/** + * \brief Read a pointer + */ +template >> +DataBuffer& operator>>(DataBuffer& buffer, std::unique_ptr& data) { + data = std::make_unique(); + return buffer >> *data; +} + +/** + * \brief Read a vector (size + data) from the buffer + * \pre The vector is assumed to be empty + */ +template +DataBuffer& operator>>(DataBuffer& buffer, std::vector& data) { + VarInt arraySize; + buffer >> arraySize; + for (std::size_t i = 0; i < arraySize.GetValue(); i++) { + T newElement; + buffer >> newElement; + data.push_back(newElement); + } + return buffer; +} + +/** + * \brief Read a list (size + data) from the buffer + * \pre The list is assumed to be empty + */ +template +DataBuffer& operator>>(DataBuffer& buffer, std::list& data) { + VarInt arraySize; + buffer >> arraySize; + for (std::size_t i = 0; i < arraySize.GetValue(); i++) { + T newElement; + buffer >> newElement; + data.push_back(newElement); + } + return buffer; +} + +/** + * \brief Read a map (size + data) from the buffer + * \pre The map is assumed to be empty + */ +template +DataBuffer& operator>>(DataBuffer& buffer, std::map& data) { + VarInt mapSize; + buffer >> mapSize; + for (std::size_t i = 0; i < mapSize.GetValue(); i++) { + K newKey; + V newValue; + buffer >> newKey >> newValue; + data.emplace(newKey, newValue); + } + return buffer; +} + +/** + * \brief Read a map (size + data) from the buffer + * \pre The map is assumed to be empty + */ +template +DataBuffer& operator>>(DataBuffer& buffer, std::unordered_map& data) { + VarInt mapSize; + buffer >> mapSize; + for (std::size_t i = 0; i < mapSize.GetValue(); i++) { + K newKey; + V newValue; + buffer >> newKey >> newValue; + data.emplace(newKey, newValue); + } + return buffer; +} + +/** + * \brief Read a pair + */ +template +DataBuffer& operator>>(DataBuffer& buffer, std::pair& data) { + return buffer >> data.first >> data.second; +} + +/** + * \brief Read an array from the buffer + */ +template +DataBuffer& operator>>(DataBuffer& buffer, std::array& data) { + for (std::size_t i = 0; i < Size; i++) { + T newElement; + buffer >> newElement; + data[i] = newElement; + } + return buffer; +} + +} // namespace sp \ No newline at end of file diff --git a/include/sp/io/MessageSerialize.h b/include/sp/io/MessageSerialize.h new file mode 100644 index 0000000..035227a --- /dev/null +++ b/include/sp/io/MessageSerialize.h @@ -0,0 +1,47 @@ +#pragma once + +#include + +namespace sp { + +template +DataBuffer& operator<<(DataBuffer& a_Buffer, const std::unique_ptr>& a_Message) { + return a_Buffer << VarInt{static_cast(a_Message->GetId())} << a_Message->Write(); +} + +template +DataBuffer& operator<<(DataBuffer& a_Buffer, const std::shared_ptr>& a_Message) { + return a_Buffer << VarInt{static_cast(a_Message->GetId())} << a_Message->Write(); +} + +template +DataBuffer& operator>>(DataBuffer& a_Buffer, std::unique_ptr>& a_Message) { + using TBase = MessageBase; + using MsgId = typename TBase::MessageIdType; + static MessageFactory factory; + + VarInt msgId; + a_Buffer >> msgId; + + a_Message = factory.CreateMessage(MsgId(msgId.GetValue())); + a_Message->Read(a_Buffer); + + return a_Buffer; +} + +template +DataBuffer& operator>>(DataBuffer& a_Buffer, std::shared_ptr>& a_Message) { + using TBase = MessageBase; + using MsgId = typename TBase::MessageIdType; + static MessageFactory factory; + + VarInt msgId; + a_Buffer >> msgId; + + a_Message = std::shared_ptr(factory.CreateMessage(MsgId(msgId.GetValue())).release()); + a_Message->Read(a_Buffer); + + return a_Buffer; +} + +} // namespace sp \ No newline at end of file