1 Commits

Author SHA1 Message Date
a1a4176801 add more DataBuffer serialization types
All checks were successful
Linux arm64 / Build (push) Successful in 17s
2025-07-31 14:12:33 +02:00
3 changed files with 124 additions and 8 deletions

View File

@@ -10,9 +10,11 @@
#include <cassert>
#include <cstdint>
#include <cstring>
#include <list>
#include <map>
#include <sp/common/VarInt.h>
#include <memory>
#include <sp/common/ByteSwapping.h>
#include <sp/common/VarInt.h>
#include <string>
#include <vector>
@@ -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 <typename T>
DataBuffer& operator<<(const std::shared_ptr<T>& data) {
return *this << *data;
}
/**
* \brief Append a pointer to the buffer
* \param data The data to append
*/
template <typename T>
DataBuffer& operator<<(const std::unique_ptr<T>& 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 <typename T>
DataBuffer& operator<<(const std::list<T>& 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 <typename K, typename V>
DataBuffer& operator<<(const std::map<K, V>& 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 <typename K, typename V>
DataBuffer& operator<<(const std::unordered_map<K, V>& 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 <typename K, typename V>
DataBuffer& operator<<(const std::pair<K, V>& 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 <typename T>
DataBuffer& operator>>(std::shared_ptr<T>& data) {
data = std::make_shared<T>();
return *this >> *data;
}
/**
* \brief Read a pointer
*/
template <typename T>
DataBuffer& operator>>(std::unique_ptr<T>& data) {
data = std::make_unique<T>();
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 <typename T>
DataBuffer& operator>>(std::list<T>& 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 <typename K, typename V>
DataBuffer& operator>>(std::unordered_map<K, V>& 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 <typename K, typename V>
DataBuffer& operator>>(std::pair<K, V>& data) {
return *this >> data.first >> data.second;
}
/**
* \brief Read an array from the buffer
*/

View File

@@ -13,7 +13,7 @@ class ConcreteMessage : public MessageBase {
using HandlerType = typename MessageBase::HandlerType;
template <typename... T>
ConcreteMessage(const T&... args) : m_Data{args...} {}
ConcreteMessage(T&&... args) : m_Data{std::move(args)...} {}
virtual ~ConcreteMessage() {}

View File

@@ -24,11 +24,13 @@ using Message = sp::ConcreteMessage<TData, PacketBase, ID>;
struct KeepAlivePacket {
sp::BitField<std::uint16_t, 12> one;
sp::BitField<std::uint16_t, 4> two;
std::shared_ptr<std::string> test;
};
struct MDCPacket {
sp::BitField<std::uint16_t, 12> one;
sp::BitField<PacketID, 4> two;
std::unique_ptr<std::string> test;
};
using KeepAliveMessage = Message<KeepAlivePacket, PacketID::KeepAlive>;
@@ -41,10 +43,10 @@ class PacketHandler : public sp::GenericHandler<AllMessages> {};
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<unsigned>(*msg->two) << "\n";
std::cout << "I recieved a mdc : " << *msg->one << " : " << static_cast<unsigned>(*msg->two) << " : " << *msg->test << "\n";
}
};
@@ -55,7 +57,7 @@ using PacketFactory = sp::MessageFactory<PacketBase, AllMessages>;
using PacketStream = sp::MessageStream<PacketFactory>;
int main() {
KeepAliveMessage m{69, 5};
KeepAliveMessage m{69, 5, std::make_shared<std::string>("I'm a keepalive")};
// dispatch tests
@@ -79,7 +81,7 @@ int main() {
PacketStream p(std::make_shared<sp::StdOuput>(file));
p.WriteMessage(m);
p.WriteMessage(MDCMessage{42, PacketID::MDC});
p.WriteMessage(MDCMessage{42, PacketID::MDC, std::make_unique<std::string>("Coucou")});
file.flush();