From a5b377745116de2b269cdfc5b90f08f46d0432d2 Mon Sep 17 00:00:00 2001 From: hovertank3d Date: Thu, 13 Nov 2025 23:02:56 +0100 Subject: initial commit --- include/net/packet.hpp | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 include/net/packet.hpp (limited to 'include/net/packet.hpp') diff --git a/include/net/packet.hpp b/include/net/packet.hpp new file mode 100644 index 0000000..f2094c0 --- /dev/null +++ b/include/net/packet.hpp @@ -0,0 +1,98 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "types.hpp" + +namespace net { + +namespace packet { + +using packet_header = std::tuple; + +template +void decode_packet(std::span payload, T& t) +{ + std::size_t offset = 0; + + boost::pfr::for_each_field(t, [&payload, &offset](auto& field, int i) { + if (offset >= payload.size()) { + throw std::runtime_error("Received invalid packet"); + } + offset += decode_field(payload.subspan(offset), field); + }); + + if (offset < payload.size()) { + throw std::runtime_error(std::format("{}: {}", offset, payload.size())); + } +} + +template +std::vector encode_raw_packet(T& t) +{ + std::vector payload; + + boost::pfr::for_each_field(t, [&payload](auto& field) { + encode_field(payload, field); + }); + + return payload; +} + +template +std::vector encode_packet(T& t) +{ + return encode_raw_packet(t); +} + +template +std::vector encode_packet(T& t) +{ + static constexpr auto chunk_size = 1024; + std::array buffer; + std::vector payload; + + int ret, flush; + z_stream strm; + + auto raw_payload = encode_raw_packet(t); + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = deflateInit(&strm, 15); + if (ret != Z_OK) + throw std::runtime_error("deflate init error"); + + strm.avail_in = raw_payload.size(); + strm.next_in = raw_payload.data(); + do { + strm.avail_out = chunk_size; + strm.next_out = reinterpret_cast(buffer.data()); + ret = deflate(&strm, flush); + assert(ret != Z_STREAM_ERROR); + payload.insert(payload.end(), buffer.begin(), buffer.end()-strm.avail_out); + } while (strm.avail_out == 0); + + assert(strm.avail_in == 0); /* all input will be used */ + + deflateEnd(&strm); + return payload; +} +} + +} \ No newline at end of file -- cgit v1.2.3