diff --git a/include/sp/common/DataBuffer.h b/include/sp/common/DataBuffer.h index b8d0b97..3d33a43 100644 --- a/include/sp/common/DataBuffer.h +++ b/include/sp/common/DataBuffer.h @@ -10,9 +10,11 @@ #include #include #include +#include #include -#include +#include #include +#include #include #include @@ -82,6 +84,24 @@ 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 @@ -95,6 +115,19 @@ class DataBuffer { 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 @@ -102,12 +135,34 @@ class DataBuffer { template DataBuffer& operator<<(const std::map& data) { *this << VarInt{data.size()}; - for (const auto& element : data) { - *this << element.first << element.second; + 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 @@ -154,6 +209,24 @@ 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 @@ -170,6 +243,22 @@ class DataBuffer { 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 @@ -187,6 +276,31 @@ class DataBuffer { 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 */ diff --git a/include/sp/protocol/ConcreteMessage.h b/include/sp/protocol/ConcreteMessage.h index 6c82965..0e65f95 100644 --- a/include/sp/protocol/ConcreteMessage.h +++ b/include/sp/protocol/ConcreteMessage.h @@ -13,7 +13,7 @@ class ConcreteMessage : public MessageBase { using HandlerType = typename MessageBase::HandlerType; template - ConcreteMessage(const T&... args) : m_Data{args...} {} + ConcreteMessage(T&&... args) : m_Data{std::move(args)...} {} virtual ~ConcreteMessage() {} diff --git a/test/test_message.cpp b/test/test_message.cpp index 31b52e1..fdd0f2f 100644 --- a/test/test_message.cpp +++ b/test/test_message.cpp @@ -24,11 +24,13 @@ using Message = sp::ConcreteMessage; struct KeepAlivePacket { sp::BitField one; sp::BitField two; + std::shared_ptr test; }; struct MDCPacket { sp::BitField one; sp::BitField two; + std::unique_ptr test; }; using KeepAliveMessage = Message; @@ -41,10 +43,10 @@ class PacketHandler : public sp::GenericHandler {}; class MyHandler : public PacketHandler { public: virtual void Handle(const KeepAliveMessage& msg) override { - std::cout << "I recieved a keep alive : " << *msg->one << " : " << *msg->two << "\n"; + std::cout << "I recieved a keep alive : " << *msg->one << " : " << *msg->two << " : " << (msg->test ? *msg->test : "nullptr") << "\n"; } virtual void Handle(const MDCMessage& msg) override { - std::cout << "I recieved a mdc : " << *msg->one << " : " << static_cast(*msg->two) << "\n"; + std::cout << "I recieved a mdc : " << *msg->one << " : " << static_cast(*msg->two) << " : " << *msg->test << "\n"; } }; @@ -55,7 +57,7 @@ using PacketFactory = sp::MessageFactory; using PacketStream = sp::MessageStream; int main() { - KeepAliveMessage m{69, 5}; + KeepAliveMessage m{69, 5, std::make_shared("I'm a keepalive")}; // dispatch tests @@ -79,7 +81,7 @@ int main() { PacketStream p(std::make_shared(file)); p.WriteMessage(m); - p.WriteMessage(MDCMessage{42, PacketID::MDC}); + p.WriteMessage(MDCMessage{42, PacketID::MDC, std::make_unique("Coucou")}); file.flush();