From 9fa023f7164907e9cc863843a6dad9ec0aff5da4 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Thu, 27 Feb 2025 22:50:51 +0100 Subject: [PATCH] generic encapsulator --- include/sp/extensions/Compress.h | 20 ++++++++- include/sp/io/IOInterface.h | 16 +++---- include/sp/io/IOInterfaceImpl.inl | 69 ++++++++++++++++++++----------- src/sp/extensions/Compress.cpp | 13 ++++++ test/test_file.cpp | 16 ++++--- 5 files changed, 96 insertions(+), 38 deletions(-) diff --git a/include/sp/extensions/Compress.h b/include/sp/extensions/Compress.h index 9c9b078..1ff2545 100644 --- a/include/sp/extensions/Compress.h +++ b/include/sp/extensions/Compress.h @@ -11,10 +11,17 @@ namespace sp { namespace option { -struct ZlibCompress {}; +struct ZlibCompress { + bool m_Enabled = true; + std::size_t m_CompressionThreshold = 64; +}; } // namespace option +} // namespace sp +#include + +namespace sp { namespace zlib { /** @@ -33,4 +40,15 @@ DataBuffer Compress(const DataBuffer& buffer, std::size_t a_CompressionThreshold DataBuffer Decompress(DataBuffer& buffer, std::uint64_t packetLength); } // namespace zlib + +namespace io { + +template <> +class MessageEncapsulator { + public: + static DataBuffer Encapsulate(const DataBuffer& a_Data, const option::ZlibCompress& a_Option); + static DataBuffer Decapsulate(DataBuffer& a_Data, std::size_t a_Length, const option::ZlibCompress& a_Option); +}; + +} // namespace io } // namespace sp diff --git a/include/sp/io/IOInterface.h b/include/sp/io/IOInterface.h index b0f73cf..451bb8d 100644 --- a/include/sp/io/IOInterface.h +++ b/include/sp/io/IOInterface.h @@ -13,14 +13,14 @@ class IOInterface { void Write(const DataBuffer& a_Data); }; -template +template class MessageEncapsulator { public: - static DataBuffer Encapsulate(const DataBuffer& a_Data); - static DataBuffer Decapsulate(DataBuffer& a_Data, std::size_t a_Length); + static DataBuffer Encapsulate(const DataBuffer& a_Data, const TOption& a_Option); + static DataBuffer Decapsulate(DataBuffer& a_Data, std::size_t a_Length, const TOption& a_Option); }; -template +template class Stream { protected: MessageDispatcher m_Dispatcher; @@ -33,16 +33,16 @@ class Stream { Stream(IOInterface&& a_Interface); Stream(Stream&& a_Stream); - void RecieveMessages(); - void SendMessage(const MessageBase& a_Message); + void RecieveMessages(const TOptions&... a_Options); + void SendMessage(const MessageBase& a_Message, const TOptions&... a_Options); MessageDispatcher& GetDispatcher() { return m_Dispatcher; } private: - static DataBuffer Encapsulate(const DataBuffer& a_Data); - static DataBuffer Decapsulate(DataBuffer& a_Data, std::size_t a_Length); + static DataBuffer Encapsulate(const DataBuffer& a_Data, const TOptions&... a_Options); + static DataBuffer Decapsulate(DataBuffer& a_Data, std::size_t a_Length, const TOptions&... a_Options); }; } // namespace io diff --git a/include/sp/io/IOInterfaceImpl.inl b/include/sp/io/IOInterfaceImpl.inl index 6e7d108..1e8c266 100644 --- a/include/sp/io/IOInterfaceImpl.inl +++ b/include/sp/io/IOInterfaceImpl.inl @@ -4,39 +4,60 @@ #include namespace sp { -namespace io { + +namespace details { + +template +struct MessageEncapsulatorPack {}; template <> -class MessageEncapsulator { - public: +struct MessageEncapsulatorPack<> { static DataBuffer Encapsulate(const DataBuffer& a_Data) { - return zlib::Compress(a_Data); + return a_Data; } static DataBuffer Decapsulate(DataBuffer& a_Data, std::size_t a_Length) { - return zlib::Decompress(a_Data, a_Length); + return a_Data; } }; -template -Stream::Stream(IOInterface&& a_Interface) : m_Interface(std::move(a_Interface)) {} +template +struct MessageEncapsulatorPack { + static DataBuffer Encapsulate(const DataBuffer& a_Data, const TOption& a_Option, const TOptions&... a_Options) { + DataBuffer data = io::MessageEncapsulator::Encapsulate(a_Data, a_Option); + return MessageEncapsulatorPack::Encapsulate(data, a_Options...); + } + static DataBuffer Decapsulate(DataBuffer& a_Data, std::size_t a_Length, const TOption& a_Option, const TOptions&... a_Options) { + DataBuffer data = io::MessageEncapsulator::Decapsulate(a_Data, a_Length, a_Option); + return MessageEncapsulatorPack::Decapsulate(data, data.GetSize(), a_Options...); + } +}; -template -Stream::Stream(Stream&& a_Stream) : +} // namespace details + +namespace io { + +template +Stream::Stream(IOInterface&& a_Interface) : + m_Interface(std::move(a_Interface)) {} + +template +Stream::Stream( + Stream&& a_Stream) : m_Dispatcher(std::move(a_Stream.m_Dispatcher)), m_Interface(std::move(a_Stream.m_Interface)) {} -template -void Stream::SendMessage(const MessageBase& a_Message) { +template +void Stream::SendMessage( + const MessageBase& a_Message, const TOptions&... a_Options) { DataBuffer data = a_Message.Write(); - DataBuffer encapsulated = Encapsulate(data); + DataBuffer encapsulated = Encapsulate(data, a_Options...); DataBuffer finalData; finalData << VarInt{encapsulated.GetSize()} << encapsulated; m_Interface.Write(finalData); } -template -void Stream::RecieveMessages() { +template +void Stream::RecieveMessages(const TOptions&... a_Options) { while (true) { - // reading the first VarInt part byte by byte std::uint64_t lenghtValue = 0; unsigned int readPos = 0; @@ -71,7 +92,7 @@ void Stream::RecieveMessages() { DataBuffer buffer; buffer = m_Interface.Read(lenghtValue); - buffer = Decapsulate(buffer, lenghtValue); + buffer = Decapsulate(buffer, lenghtValue, a_Options...); VarInt packetType; buffer >> packetType; @@ -88,16 +109,16 @@ void Stream::RecieveMessages() { } } -template -DataBuffer Stream::Encapsulate(const DataBuffer& a_Data) { - // TODO: process compress + encryption - return MessageEncapsulator::Encapsulate(a_Data); +template +DataBuffer Stream::Encapsulate( + const DataBuffer& a_Data, const TOptions&... a_Options) { + return details::MessageEncapsulatorPack::Encapsulate(a_Data, a_Options...); } -template -DataBuffer Stream::Decapsulate(DataBuffer& a_Data, std::size_t a_Length) { - // TODO: process compress + encryption - return MessageEncapsulator::Decapsulate(a_Data, a_Length); +template +DataBuffer Stream::Decapsulate( + DataBuffer& a_Data, std::size_t a_Length, const TOptions&... a_Options) { + return details::MessageEncapsulatorPack::Decapsulate(a_Data, a_Length, a_Options...); } } // namespace io diff --git a/src/sp/extensions/Compress.cpp b/src/sp/extensions/Compress.cpp index 3a73f74..10babb9 100644 --- a/src/sp/extensions/Compress.cpp +++ b/src/sp/extensions/Compress.cpp @@ -73,4 +73,17 @@ DataBuffer Decompress(DataBuffer& buffer, std::uint64_t packetLength) { } } // namespace zlib + +namespace io { + +DataBuffer MessageEncapsulator::Encapsulate(const DataBuffer& a_Data, const option::ZlibCompress& a_Option) { + return a_Option.m_Enabled ? zlib::Compress(a_Data, a_Option.m_CompressionThreshold) : a_Data; +} + +DataBuffer MessageEncapsulator::Decapsulate( + DataBuffer& a_Data, std::size_t a_Length, const option::ZlibCompress& a_Option) { + return a_Option.m_Enabled ? zlib::Decompress(a_Data, a_Length) : a_Data; +} + +} // namespace io } // namespace sp diff --git a/test/test_file.cpp b/test/test_file.cpp index 0d92188..f33a183 100644 --- a/test/test_file.cpp +++ b/test/test_file.cpp @@ -17,7 +17,7 @@ class CustomPacketHandler : public sp::PacketHandler { } }; -using FileStream = sp::io::Stream; +using FileStream = sp::io::Stream; int main() { auto handler = std::make_shared(); @@ -26,11 +26,17 @@ int main() { stream.GetDispatcher().RegisterHandler(PacketId::Disconnect, handler); stream.GetDispatcher().RegisterHandler(PacketId::KeepAlive, handler); - stream.SendMessage(KeepAlivePacket{96}); - stream.SendMessage(KeepAlivePacket{69}); - stream.SendMessage(DisconnectPacket{"This is in the fiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiile !"}); + auto zlibOptions = sp::option::ZlibCompress{}; - stream.RecieveMessages(); + stream.SendMessage(KeepAlivePacket{96}, zlibOptions); + stream.SendMessage(KeepAlivePacket{69}, zlibOptions); + stream.SendMessage( + DisconnectPacket{ + "This is in the " + "fiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiile !"}, + zlibOptions); + + stream.RecieveMessages(zlibOptions); return 0; } \ No newline at end of file