From 132c3c3c8d0949e5e48614280d5f9d8d70830b67 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Tue, 25 Feb 2025 23:25:12 +0100 Subject: [PATCH 1/7] add base io interface --- include/examples/PacketExample.h | 7 +- include/sp/io/IOInterface.h | 98 +++++++++++++++++++ include/sp/io/IOInterfaceImpl.inl | 1 + include/sp/protocol/MessageDispatcher.h | 5 +- include/sp/protocol/MessageFactory.h | 2 +- .../protocol/message/MessageInterfacesImpl.h | 14 +++ test/test_io.cpp | 62 ++++++++++++ test/test_packets.cpp | 7 +- 8 files changed, 187 insertions(+), 9 deletions(-) create mode 100644 include/sp/io/IOInterface.h create mode 100644 include/sp/io/IOInterfaceImpl.inl create mode 100644 test/test_io.cpp diff --git a/include/examples/PacketExample.h b/include/examples/PacketExample.h index c185c8f..bf51532 100644 --- a/include/examples/PacketExample.h +++ b/include/examples/PacketExample.h @@ -6,12 +6,13 @@ enum PacketId { UpgradeTower, }; -#include #include +#include #include // they must be in the same order as in the enum ! using AllPackets = std::tuple; -#include -#include \ No newline at end of file +#include +#include +#include \ No newline at end of file diff --git a/include/sp/io/IOInterface.h b/include/sp/io/IOInterface.h new file mode 100644 index 0000000..31b96a7 --- /dev/null +++ b/include/sp/io/IOInterface.h @@ -0,0 +1,98 @@ +#pragma once + +#include +#include + +namespace sp { + +template +class IOInterface { + public: + DataBuffer Read(std::size_t a_Amount); + void Write(const DataBuffer& a_Data); +}; + +template +class IOStream { + protected: + MessageDispatcher m_Dispatcher; + IOInterface m_Interface; + + using MessageBase = typename MessageDispatcher::MessageBaseType; + using MsgIdType = typename MessageBase::MsgIdType; + + public: + IOStream() {} + IOStream(IOInterface&& a_Interface) : m_Interface(std::move(a_Interface)) {} + IOStream(IOStream&& a_Stream) : m_Dispatcher(std::move(a_Stream.m_Dispatcher)), m_Interface(std::move(a_Stream.m_Interface)) {} + + void RecieveMessages(); + void SendMessage(const MessageBase& a_Message); + + MessageDispatcher& GetDispatcher() { + return m_Dispatcher; + } +}; + +template +void IOStream::SendMessage(const MessageBase& a_Message) { + // TODO: process compress + encryption + DataBuffer data = a_Message.Write(); + DataBuffer dataSize; + m_Interface.Write(dataSize << sp::VarInt{data.GetSize()} << data); +} + +template +void IOStream::RecieveMessages() { + // TODO: process compress + encryption + while (true) { + + // reading the first VarInt part byte by byte + std::uint64_t lenghtValue = 0; + unsigned int readPos = 0; + + while (true) { + static constexpr int SEGMENT_BITS = (1 << 7) - 1; + static constexpr int CONTINUE_BIT = 1 << 7; + + DataBuffer buffer = m_Interface.Read(sizeof(std::uint8_t)); + + // if non-blocking call + if (buffer.GetSize() == 0) + return; + + std::uint8_t part; + buffer >> part; + lenghtValue |= static_cast(part & SEGMENT_BITS) << readPos; + + if ((part & CONTINUE_BIT) == 0) + break; + + readPos += 7; + + if (readPos >= 8 * sizeof(lenghtValue)) + throw std::runtime_error("VarInt is too big"); + } + + + DataBuffer buffer; + buffer = m_Interface.Read(lenghtValue); + + // TODO: process compress + encryption + + MsgIdType packetType; + buffer >> packetType; + + static const MessageFactory messageFactory; + + std::unique_ptr message = messageFactory.CreateMessage(packetType); + + assert(message != nullptr); + + message->Read(buffer); + + GetDispatcher().Dispatch(*message); + } +} + +} // namespace sp diff --git a/include/sp/io/IOInterfaceImpl.inl b/include/sp/io/IOInterfaceImpl.inl new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/include/sp/io/IOInterfaceImpl.inl @@ -0,0 +1 @@ +#pragma once diff --git a/include/sp/protocol/MessageDispatcher.h b/include/sp/protocol/MessageDispatcher.h index eb346e6..cd6b5cd 100644 --- a/include/sp/protocol/MessageDispatcher.h +++ b/include/sp/protocol/MessageDispatcher.h @@ -6,6 +6,7 @@ */ #include +#include namespace sp { @@ -19,6 +20,8 @@ class MessageDispatcher { std::map>> m_Handlers; public: + using MessageBaseType = MessageBase; + /** * \brief Constructor */ @@ -51,4 +54,4 @@ class MessageDispatcher { #include -} // namespace blitz +} // namespace sp diff --git a/include/sp/protocol/MessageFactory.h b/include/sp/protocol/MessageFactory.h index 3212dd9..20742c4 100644 --- a/include/sp/protocol/MessageFactory.h +++ b/include/sp/protocol/MessageFactory.h @@ -16,7 +16,7 @@ class MessageFactory { MessageFactory() : m_Factory(details::ArrayFiller::ArrayCreate()) {} - std::unique_ptr CreateMessage(IdType id) { + std::unique_ptr CreateMessage(IdType id) const { if (id >= m_Factory.size()) return nullptr; return m_Factory.at(id)(); diff --git a/include/sp/protocol/message/MessageInterfacesImpl.h b/include/sp/protocol/message/MessageInterfacesImpl.h index 5f464a8..e04f054 100644 --- a/include/sp/protocol/message/MessageInterfacesImpl.h +++ b/include/sp/protocol/message/MessageInterfacesImpl.h @@ -75,6 +75,13 @@ class MessageInterfaceWriteBase : public TBase { WriteImpl(buffer); } + // helper + DataBuffer Write() const { + DataBuffer buffer; + this->Write(buffer); + return buffer; + } + protected: virtual void WriteImpl(DataBuffer& buffer) const = 0; }; @@ -113,6 +120,13 @@ class MessageInterfaceWriteIdBase : public TBase { this->WriteData(this->GetId(), buffer); this->WriteImpl(buffer); } + + // helper + DataBuffer Write() const { + DataBuffer buffer; + this->Write(buffer); + return buffer; + } }; } // namespace details diff --git a/test/test_io.cpp b/test/test_io.cpp new file mode 100644 index 0000000..01ff612 --- /dev/null +++ b/test/test_io.cpp @@ -0,0 +1,62 @@ +#include + +#include +#include + +struct DBTag {}; + +template <> +class sp::IOInterface { + private: + sp::DataBuffer m_VirtualIO; + + public: + sp::DataBuffer Read(std::size_t a_Amount) { + // since we are just testing it, we ignore reads that overflows + if (m_VirtualIO.GetReadOffset() + a_Amount > m_VirtualIO.GetSize()) + return {}; + + DataBuffer data; + m_VirtualIO.ReadSome(data, a_Amount); + return data; + } + void Write(const sp::DataBuffer& a_Data) { + m_VirtualIO << a_Data; + } +}; + +using DataBufferStream = sp::IOStream; + +class CustomPacketHandler : public sp::PacketHandler { + void Handle(const KeepAlivePacket& packet) { + std::cout << "KeepAlive handled ! " << packet.GetKeepAliveId() << "\n"; + } + + void Handle(const DisconnectPacket& packet) { + std::cout << "Disconnect handled ! " << packet.GetReason() << "\n"; + } + + void Handle(const UpgradeTowerPacket& packet) { + std::cout << "UpgradeTower handled !\n"; + } +}; + +int main() { + auto handler = std::make_shared(); + + DataBufferStream stream; + stream.GetDispatcher().RegisterHandler(PacketId::Disconnect, handler); + + // this should not be dispatched + stream.SendMessage(KeepAlivePacket{96}); + stream.RecieveMessages(); + + stream.GetDispatcher().RegisterHandler(PacketId::KeepAlive, handler); + + stream.SendMessage(KeepAlivePacket{69}); + stream.RecieveMessages(); // here, it's non-blocking + stream.SendMessage(DisconnectPacket{"I don't know"}); + stream.RecieveMessages(); // here, it's non-blocking + + return 0; +} \ No newline at end of file diff --git a/test/test_packets.cpp b/test/test_packets.cpp index 3af7410..e89e171 100644 --- a/test/test_packets.cpp +++ b/test/test_packets.cpp @@ -3,8 +3,8 @@ #include #include -#include #include +#include class KeepAliveHandler : public sp::PacketHandler { void Handle(const KeepAlivePacket& packet) { @@ -28,8 +28,7 @@ int main() { auto handler = std::make_shared(); msg->Dispatch(*handler); - sp::DataBuffer buffer; - msg->Write(buffer); + sp::DataBuffer buffer = msg->Write(); std::uint8_t msgId; buffer >> msgId; @@ -37,7 +36,7 @@ int main() { auto upgradeTower2 = std::make_unique(); upgradeTower2->Read(buffer); - std::cout << "Test : " << (unsigned) upgradeTower2->GetTowerId() << "\n"; + std::cout << "Test : " << (unsigned)upgradeTower2->GetTowerId() << "\n"; sp::PacketFactory factory; auto packet = factory.CreateMessage(msgId); -- 2.49.1 From a2eb10ec6da9a04e14eef9607fe84a19b4e3fd07 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Wed, 26 Feb 2025 00:01:51 +0100 Subject: [PATCH 2/7] add file interface --- include/sp/io/FileIO.h | 35 +++++++++++++++++++++++++++++++++++ include/sp/io/IOInterface.h | 3 +++ test/test_file.cpp | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 include/sp/io/FileIO.h create mode 100644 test/test_file.cpp diff --git a/include/sp/io/FileIO.h b/include/sp/io/FileIO.h new file mode 100644 index 0000000..23a659b --- /dev/null +++ b/include/sp/io/FileIO.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +namespace sp { + +struct FileTag {}; + +template <> +class IOInterface { + private: + std::ofstream m_FileOutput; + std::ifstream m_FileInput; + + public: + IOInterface(const std::string& filePath) : m_FileOutput(filePath), m_FileInput(filePath) {} + IOInterface(IOInterface&& other) : m_FileOutput(std::move(other.m_FileOutput)), m_FileInput(std::move(other.m_FileInput)) {} + + DataBuffer Read(std::size_t a_Amount) { + DataBuffer buffer; + buffer.Resize(a_Amount); + m_FileInput.read(reinterpret_cast(buffer.data()), a_Amount); + return buffer; + } + + void Write(const sp::DataBuffer& a_Data) { + m_FileOutput.write(reinterpret_cast(a_Data.data()), a_Data.GetSize()); + m_FileOutput.flush(); + } +}; + +using FileIO = IOInterface; + +} // namespace sp diff --git a/include/sp/io/IOInterface.h b/include/sp/io/IOInterface.h index 31b96a7..a749f54 100644 --- a/include/sp/io/IOInterface.h +++ b/include/sp/io/IOInterface.h @@ -74,6 +74,9 @@ void IOStream::RecieveMessages() { throw std::runtime_error("VarInt is too big"); } + // nothing to read + if (lenghtValue == 0) + return; DataBuffer buffer; buffer = m_Interface.Read(lenghtValue); diff --git a/test/test_file.cpp b/test/test_file.cpp new file mode 100644 index 0000000..35d9251 --- /dev/null +++ b/test/test_file.cpp @@ -0,0 +1,37 @@ +#include + +#include +#include + +class CustomPacketHandler : public sp::PacketHandler { + void Handle(const KeepAlivePacket& packet) { + std::cout << "KeepAlive handled ! " << packet.GetKeepAliveId() << "\n"; + } + + void Handle(const DisconnectPacket& packet) { + std::cout << "Disconnect handled ! " << packet.GetReason() << "\n"; + } + + void Handle(const UpgradeTowerPacket& packet) { + std::cout << "UpgradeTower handled !\n"; + } +}; + +using FileStream = sp::IOStream; + + +int main() { + auto handler = std::make_shared(); + + FileStream stream(sp::FileIO{"test.txt"}); + 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 file !"}); + + stream.RecieveMessages(); + + return 0; +} \ No newline at end of file -- 2.49.1 From 37ff881819f9545c060a163352fad75d0dc13ac9 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Wed, 26 Feb 2025 00:07:06 +0100 Subject: [PATCH 3/7] add file input/output --- include/sp/io/FileIO.h | 19 +++++++++++++------ test/test_file.cpp | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/include/sp/io/FileIO.h b/include/sp/io/FileIO.h index 23a659b..2729616 100644 --- a/include/sp/io/FileIO.h +++ b/include/sp/io/FileIO.h @@ -10,23 +10,30 @@ struct FileTag {}; template <> class IOInterface { private: - std::ofstream m_FileOutput; - std::ifstream m_FileInput; + std::unique_ptr m_FileInput; + std::unique_ptr m_FileOutput; public: - IOInterface(const std::string& filePath) : m_FileOutput(filePath), m_FileInput(filePath) {} + IOInterface(const std::string& fileInput, const std::string& fileOutput) { + if (!fileInput.empty()) + m_FileInput = std::make_unique(fileInput); + if (!fileOutput.empty()) + m_FileOutput = std::make_unique(fileOutput); + } IOInterface(IOInterface&& other) : m_FileOutput(std::move(other.m_FileOutput)), m_FileInput(std::move(other.m_FileInput)) {} DataBuffer Read(std::size_t a_Amount) { DataBuffer buffer; buffer.Resize(a_Amount); - m_FileInput.read(reinterpret_cast(buffer.data()), a_Amount); + assert(m_FileInput != nullptr); + m_FileInput->read(reinterpret_cast(buffer.data()), a_Amount); return buffer; } void Write(const sp::DataBuffer& a_Data) { - m_FileOutput.write(reinterpret_cast(a_Data.data()), a_Data.GetSize()); - m_FileOutput.flush(); + assert(m_FileOutput != nullptr); + m_FileOutput->write(reinterpret_cast(a_Data.data()), a_Data.GetSize()); + m_FileOutput->flush(); } }; diff --git a/test/test_file.cpp b/test/test_file.cpp index 35d9251..727a5bd 100644 --- a/test/test_file.cpp +++ b/test/test_file.cpp @@ -23,7 +23,7 @@ using FileStream = sp::IOStream(); - FileStream stream(sp::FileIO{"test.txt"}); + FileStream stream(sp::FileIO{"test.txt", "text.txt"}); stream.GetDispatcher().RegisterHandler(PacketId::Disconnect, handler); stream.GetDispatcher().RegisterHandler(PacketId::KeepAlive, handler); -- 2.49.1 From b77c650fdf7fee13016bf537763bdf31e92d014d Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Wed, 26 Feb 2025 10:12:58 +0100 Subject: [PATCH 4/7] fix xmake target --- xmake.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/xmake.lua b/xmake.lua index 6bd68e8..79ca7d5 100644 --- a/xmake.lua +++ b/xmake.lua @@ -47,9 +47,16 @@ end target("SimpleProtocolLib") add_includedirs("include") - add_headerfiles("include/(sp/common/**.h)", "include/(sp/common/**.h)", "include/(sp/common/**.h)") + add_files("src/sp/**.cpp") + + local includeFolders = {"common", "default", "io", "protocol"} + for _, folder in ipairs(includeFolders) do + add_headerfiles("include/(sp/" .. folder .. "/**.h)") + end + + -- we don't want extensions + remove_files("src/sp/extensions/**.cpp") set_group("Library") - add_files("src/sp/common/*.cpp") set_kind("$(kind)") -- Tests -- 2.49.1 From 605a310ede1210bf0aca97277729ccc5fd49fe6f Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Wed, 26 Feb 2025 10:14:06 +0100 Subject: [PATCH 5/7] refactor io --- include/sp/io/File.h | 33 ++++++++++++++ include/sp/io/FileIO.h | 42 ----------------- include/sp/io/IOInterface.h | 76 ++++--------------------------- include/sp/io/IOInterfaceImpl.inl | 72 +++++++++++++++++++++++++++++ include/sp/io/Memory.h | 23 ++++++++++ src/sp/io/File.cpp | 31 +++++++++++++ src/sp/io/Memory.cpp | 16 +++++++ test/test_file.cpp | 7 ++- test/test_io.cpp | 30 ++---------- 9 files changed, 190 insertions(+), 140 deletions(-) create mode 100644 include/sp/io/File.h delete mode 100644 include/sp/io/FileIO.h create mode 100644 include/sp/io/Memory.h create mode 100644 src/sp/io/File.cpp create mode 100644 src/sp/io/Memory.cpp diff --git a/include/sp/io/File.h b/include/sp/io/File.h new file mode 100644 index 0000000..2b329e6 --- /dev/null +++ b/include/sp/io/File.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +namespace sp { +namespace io { + +struct FileTag { + enum OpenMode { + In = 1, + Out = 1 << 1, + }; +}; + +template <> +class IOInterface { + private: + std::unique_ptr m_FileInput; + std::unique_ptr m_FileOutput; + + public: + IOInterface(const std::string& a_FilePath, unsigned int a_OpenMode); + IOInterface(IOInterface&& other); + + DataBuffer Read(std::size_t a_Amount); + void Write(const sp::DataBuffer& a_Data); +}; + +using File = IOInterface; + +} // namespace io +} // namespace sp diff --git a/include/sp/io/FileIO.h b/include/sp/io/FileIO.h deleted file mode 100644 index 2729616..0000000 --- a/include/sp/io/FileIO.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include -#include - -namespace sp { - -struct FileTag {}; - -template <> -class IOInterface { - private: - std::unique_ptr m_FileInput; - std::unique_ptr m_FileOutput; - - public: - IOInterface(const std::string& fileInput, const std::string& fileOutput) { - if (!fileInput.empty()) - m_FileInput = std::make_unique(fileInput); - if (!fileOutput.empty()) - m_FileOutput = std::make_unique(fileOutput); - } - IOInterface(IOInterface&& other) : m_FileOutput(std::move(other.m_FileOutput)), m_FileInput(std::move(other.m_FileInput)) {} - - DataBuffer Read(std::size_t a_Amount) { - DataBuffer buffer; - buffer.Resize(a_Amount); - assert(m_FileInput != nullptr); - m_FileInput->read(reinterpret_cast(buffer.data()), a_Amount); - return buffer; - } - - void Write(const sp::DataBuffer& a_Data) { - assert(m_FileOutput != nullptr); - m_FileOutput->write(reinterpret_cast(a_Data.data()), a_Data.GetSize()); - m_FileOutput->flush(); - } -}; - -using FileIO = IOInterface; - -} // namespace sp diff --git a/include/sp/io/IOInterface.h b/include/sp/io/IOInterface.h index a749f54..41420d2 100644 --- a/include/sp/io/IOInterface.h +++ b/include/sp/io/IOInterface.h @@ -4,6 +4,7 @@ #include namespace sp { +namespace io { template class IOInterface { @@ -13,7 +14,7 @@ class IOInterface { }; template -class IOStream { +class Stream { protected: MessageDispatcher m_Dispatcher; IOInterface m_Interface; @@ -22,9 +23,9 @@ class IOStream { using MsgIdType = typename MessageBase::MsgIdType; public: - IOStream() {} - IOStream(IOInterface&& a_Interface) : m_Interface(std::move(a_Interface)) {} - IOStream(IOStream&& a_Stream) : m_Dispatcher(std::move(a_Stream.m_Dispatcher)), m_Interface(std::move(a_Stream.m_Interface)) {} + Stream() {} + Stream(IOInterface&& a_Interface) : m_Interface(std::move(a_Interface)) {} + Stream(Stream&& a_Stream) : m_Dispatcher(std::move(a_Stream.m_Dispatcher)), m_Interface(std::move(a_Stream.m_Interface)) {} void RecieveMessages(); void SendMessage(const MessageBase& a_Message); @@ -34,68 +35,7 @@ class IOStream { } }; -template -void IOStream::SendMessage(const MessageBase& a_Message) { - // TODO: process compress + encryption - DataBuffer data = a_Message.Write(); - DataBuffer dataSize; - m_Interface.Write(dataSize << sp::VarInt{data.GetSize()} << data); -} - -template -void IOStream::RecieveMessages() { - // TODO: process compress + encryption - while (true) { - - // reading the first VarInt part byte by byte - std::uint64_t lenghtValue = 0; - unsigned int readPos = 0; - - while (true) { - static constexpr int SEGMENT_BITS = (1 << 7) - 1; - static constexpr int CONTINUE_BIT = 1 << 7; - - DataBuffer buffer = m_Interface.Read(sizeof(std::uint8_t)); - - // if non-blocking call - if (buffer.GetSize() == 0) - return; - - std::uint8_t part; - buffer >> part; - lenghtValue |= static_cast(part & SEGMENT_BITS) << readPos; - - if ((part & CONTINUE_BIT) == 0) - break; - - readPos += 7; - - if (readPos >= 8 * sizeof(lenghtValue)) - throw std::runtime_error("VarInt is too big"); - } - - // nothing to read - if (lenghtValue == 0) - return; - - DataBuffer buffer; - buffer = m_Interface.Read(lenghtValue); - - // TODO: process compress + encryption - - MsgIdType packetType; - buffer >> packetType; - - static const MessageFactory messageFactory; - - std::unique_ptr message = messageFactory.CreateMessage(packetType); - - assert(message != nullptr); - - message->Read(buffer); - - GetDispatcher().Dispatch(*message); - } -} - +} // namespace io } // namespace sp + +#include \ No newline at end of file diff --git a/include/sp/io/IOInterfaceImpl.inl b/include/sp/io/IOInterfaceImpl.inl index 6f70f09..d0b8937 100644 --- a/include/sp/io/IOInterfaceImpl.inl +++ b/include/sp/io/IOInterfaceImpl.inl @@ -1 +1,73 @@ #pragma once + +#include + +namespace sp { +namespace io { + +template +void Stream::SendMessage(const MessageBase& a_Message) { + // TODO: process compress + encryption + DataBuffer data = a_Message.Write(); + DataBuffer dataSize; + m_Interface.Write(dataSize << sp::VarInt{data.GetSize()} << data); +} + +template +void Stream::RecieveMessages() { + // TODO: process compress + encryption + while (true) { + + // reading the first VarInt part byte by byte + std::uint64_t lenghtValue = 0; + unsigned int readPos = 0; + + while (true) { + static constexpr int SEGMENT_BITS = (1 << 7) - 1; + static constexpr int CONTINUE_BIT = 1 << 7; + + DataBuffer buffer = m_Interface.Read(sizeof(std::uint8_t)); + + // eof + if (buffer.GetSize() == 0) + return; + + std::uint8_t part; + buffer >> part; + lenghtValue |= static_cast(part & SEGMENT_BITS) << readPos; + + if ((part & CONTINUE_BIT) == 0) + break; + + readPos += 7; + + if (readPos >= 8 * sizeof(lenghtValue)) + throw std::runtime_error("VarInt is too big"); + } + + // nothing to read + if (lenghtValue == 0) + return; + + DataBuffer buffer; + buffer = m_Interface.Read(lenghtValue); + + // TODO: process compress + encryption + + MsgIdType packetType; + buffer >> packetType; + + static const MessageFactory messageFactory; + + std::unique_ptr message = messageFactory.CreateMessage(packetType); + + assert(message != nullptr); + + message->Read(buffer); + + GetDispatcher().Dispatch(*message); + } +} + +} // namespace io +} // namespace sp \ No newline at end of file diff --git a/include/sp/io/Memory.h b/include/sp/io/Memory.h new file mode 100644 index 0000000..83021bc --- /dev/null +++ b/include/sp/io/Memory.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +namespace sp { +namespace io { + +struct MemoryTag {}; + +template <> +class IOInterface { + private: + sp::DataBuffer m_VirtualIO; + + public: + sp::DataBuffer Read(std::size_t a_Amount); + void Write(const sp::DataBuffer& a_Data); +}; + +using Memory = IOInterface; + +} // namespace io +} // namespace sp diff --git a/src/sp/io/File.cpp b/src/sp/io/File.cpp new file mode 100644 index 0000000..2bccc19 --- /dev/null +++ b/src/sp/io/File.cpp @@ -0,0 +1,31 @@ +#include + +namespace sp { +namespace io { + +File::IOInterface(const std::string& a_FilePath, unsigned int a_OpenMode) { + if (a_OpenMode & FileTag::OpenMode::In) + m_FileInput = std::make_unique(a_FilePath, std::ios::binary); + if (a_OpenMode & FileTag::OpenMode::Out) + m_FileOutput = std::make_unique(a_FilePath, std::ios::binary); +} + +File::IOInterface(File&& other) : + m_FileOutput(std::move(other.m_FileOutput)), m_FileInput(std::move(other.m_FileInput)) {} + +DataBuffer File::Read(std::size_t a_Amount) { + DataBuffer buffer; + buffer.Resize(a_Amount); + assert(m_FileInput != nullptr); + m_FileInput->read(reinterpret_cast(buffer.data()), a_Amount); + return buffer; +} + +void File::Write(const sp::DataBuffer& a_Data) { + assert(m_FileOutput != nullptr); + m_FileOutput->write(reinterpret_cast(a_Data.data()), a_Data.GetSize()); + m_FileOutput->flush(); +} + +} // namespace io +} // namespace sp diff --git a/src/sp/io/Memory.cpp b/src/sp/io/Memory.cpp new file mode 100644 index 0000000..57ffd4f --- /dev/null +++ b/src/sp/io/Memory.cpp @@ -0,0 +1,16 @@ +#include + +namespace sp { +namespace io { + +sp::DataBuffer Memory::Read(std::size_t a_Amount) { + DataBuffer data; + m_VirtualIO.ReadSome(data, a_Amount > m_VirtualIO.GetRemaining() ? m_VirtualIO.GetRemaining() : a_Amount); + return data; +} +void Memory::Write(const sp::DataBuffer& a_Data) { + m_VirtualIO << a_Data; +} + +} // namespace io +} // namespace sp diff --git a/test/test_file.cpp b/test/test_file.cpp index 727a5bd..f05d696 100644 --- a/test/test_file.cpp +++ b/test/test_file.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include class CustomPacketHandler : public sp::PacketHandler { void Handle(const KeepAlivePacket& packet) { @@ -17,13 +17,12 @@ class CustomPacketHandler : public sp::PacketHandler { } }; -using FileStream = sp::IOStream; - +using FileStream = sp::io::Stream; int main() { auto handler = std::make_shared(); - FileStream stream(sp::FileIO{"test.txt", "text.txt"}); + FileStream stream(sp::io::File{"test.txt", sp::io::FileTag::In | sp::io::FileTag::Out}); stream.GetDispatcher().RegisterHandler(PacketId::Disconnect, handler); stream.GetDispatcher().RegisterHandler(PacketId::KeepAlive, handler); diff --git a/test/test_io.cpp b/test/test_io.cpp index 01ff612..8bb78ec 100644 --- a/test/test_io.cpp +++ b/test/test_io.cpp @@ -1,31 +1,9 @@ #include #include -#include +#include -struct DBTag {}; - -template <> -class sp::IOInterface { - private: - sp::DataBuffer m_VirtualIO; - - public: - sp::DataBuffer Read(std::size_t a_Amount) { - // since we are just testing it, we ignore reads that overflows - if (m_VirtualIO.GetReadOffset() + a_Amount > m_VirtualIO.GetSize()) - return {}; - - DataBuffer data; - m_VirtualIO.ReadSome(data, a_Amount); - return data; - } - void Write(const sp::DataBuffer& a_Data) { - m_VirtualIO << a_Data; - } -}; - -using DataBufferStream = sp::IOStream; +using DataBufferStream = sp::io::Stream; class CustomPacketHandler : public sp::PacketHandler { void Handle(const KeepAlivePacket& packet) { @@ -54,9 +32,9 @@ int main() { stream.GetDispatcher().RegisterHandler(PacketId::KeepAlive, handler); stream.SendMessage(KeepAlivePacket{69}); - stream.RecieveMessages(); // here, it's non-blocking + stream.RecieveMessages(); stream.SendMessage(DisconnectPacket{"I don't know"}); - stream.RecieveMessages(); // here, it's non-blocking + stream.RecieveMessages(); return 0; } \ No newline at end of file -- 2.49.1 From 2097207c6b55b86790a79b3de288aec9c1beb16d Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Wed, 26 Feb 2025 10:17:22 +0100 Subject: [PATCH 6/7] rename ArrayFiller --- include/sp/protocol/MessageFactory.h | 4 ++-- .../message/{ArrayFillerImpl.inl => ArrayFillerImpl.h} | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) rename include/sp/protocol/message/{ArrayFillerImpl.inl => ArrayFillerImpl.h} (94%) diff --git a/include/sp/protocol/MessageFactory.h b/include/sp/protocol/MessageFactory.h index 20742c4..abc5a99 100644 --- a/include/sp/protocol/MessageFactory.h +++ b/include/sp/protocol/MessageFactory.h @@ -5,9 +5,9 @@ #include #include -namespace sp { +#include -#include +namespace sp { template class MessageFactory { diff --git a/include/sp/protocol/message/ArrayFillerImpl.inl b/include/sp/protocol/message/ArrayFillerImpl.h similarity index 94% rename from include/sp/protocol/message/ArrayFillerImpl.inl rename to include/sp/protocol/message/ArrayFillerImpl.h index 410afba..f0bf3dd 100644 --- a/include/sp/protocol/message/ArrayFillerImpl.inl +++ b/include/sp/protocol/message/ArrayFillerImpl.h @@ -1,12 +1,12 @@ #pragma once +namespace sp { namespace details { template using ArrayType = std::vector(void)>>; - template struct ArrayFiller {}; @@ -35,4 +35,5 @@ struct ArrayFiller { } }; -} // namespace details \ No newline at end of file +} // namespace details +} // namespace sp \ No newline at end of file -- 2.49.1 From 2be6b319c5c72799ba7bc7d07752c92de31fabd1 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Wed, 26 Feb 2025 10:22:41 +0100 Subject: [PATCH 7/7] move Stream constructor impl --- include/sp/io/IOInterface.h | 4 ++-- include/sp/io/IOInterfaceImpl.inl | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/sp/io/IOInterface.h b/include/sp/io/IOInterface.h index 41420d2..65c19f7 100644 --- a/include/sp/io/IOInterface.h +++ b/include/sp/io/IOInterface.h @@ -24,8 +24,8 @@ class Stream { public: Stream() {} - Stream(IOInterface&& a_Interface) : m_Interface(std::move(a_Interface)) {} - Stream(Stream&& a_Stream) : m_Dispatcher(std::move(a_Stream.m_Dispatcher)), m_Interface(std::move(a_Stream.m_Interface)) {} + Stream(IOInterface&& a_Interface); + Stream(Stream&& a_Stream); void RecieveMessages(); void SendMessage(const MessageBase& a_Message); diff --git a/include/sp/io/IOInterfaceImpl.inl b/include/sp/io/IOInterfaceImpl.inl index d0b8937..8c19734 100644 --- a/include/sp/io/IOInterfaceImpl.inl +++ b/include/sp/io/IOInterfaceImpl.inl @@ -4,6 +4,11 @@ namespace sp { 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) { -- 2.49.1