From 06d69fb97645ef6b37b55326a5253112c8800e39 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Sat, 8 Feb 2025 13:44:04 +0100 Subject: [PATCH] feat: add support for all endianesses --- include/sp/common/ByteSwapping.h | 92 +++++++++++++++++++++++++ include/sp/protocol/MessageInterfaces.h | 11 +-- 2 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 include/sp/common/ByteSwapping.h diff --git a/include/sp/common/ByteSwapping.h b/include/sp/common/ByteSwapping.h new file mode 100644 index 0000000..55d2fdc --- /dev/null +++ b/include/sp/common/ByteSwapping.h @@ -0,0 +1,92 @@ +#pragma once + +#ifdef _WIN32 +#include +#else +#include +#endif + +#include + +namespace sp { + +template +void SwapBytes(T& value) { + char* ptr = reinterpret_cast(&value); + std::reverse(ptr, ptr + sizeof(T)); +} + +bool IsSystemBigEndian() { + std::uint16_t test = 0; + reinterpret_cast(&test)[1] = 1; + return test == 1; +} + +/** + * \brief Serialize value to (network byte order) big endian + */ +template +void ToNetwork(T& value) {} + +template <> +void ToNetwork(std::uint16_t& value) { + value = htons(value); +} + +template <> +void ToNetwork(std::uint32_t& value) { + value = htonl(value); +} + +template <> +void ToNetwork(std::uint64_t& value) { + if (IsSystemBigEndian()) + return; + SwapBytes(value); +} + +/** + * \brief Deserialize value from (network byte order) big endian + */ +template +void FromNetwork(T& value) {} + +template <> +void FromNetwork(std::uint16_t& value) { + value = ntohs(value); +} + +template <> +void FromNetwork(std::uint32_t& value) { + value = ntohl(value); +} + +template <> +void FromNetwork(std::uint64_t& value) { + if (IsSystemBigEndian()) + return; + SwapBytes(value); +} + +/** + * \brief Swap bytes if the value is any kind of integer + */ +template +void TrySwapBytes(T& value) {} + +template <> +void TrySwapBytes(std::uint16_t& value) { + SwapBytes(value); +} + +template <> +void TrySwapBytes(std::uint32_t& value) { + SwapBytes(value); +} + +template <> +void TrySwapBytes(std::uint64_t& value) { + SwapBytes(value); +} + +} // namespace sp diff --git a/include/sp/protocol/MessageInterfaces.h b/include/sp/protocol/MessageInterfaces.h index 592309a..bc15cb3 100644 --- a/include/sp/protocol/MessageInterfaces.h +++ b/include/sp/protocol/MessageInterfaces.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace sp { namespace details { @@ -83,13 +84,13 @@ class MessageInterfaceBigEndian : public TBase { protected: template void ReadData(T& value, DataBuffer& buffer) { - //TODO: use big endian buffer >> value; + FromNetwork(value); } template void WriteData(T value, DataBuffer& buffer) { - //TODO: use big endian + ToNetwork(value); buffer << value; } }; @@ -100,13 +101,15 @@ class MessageInterfaceLittleEndian : public TBase { protected: template void ReadData(T& value, DataBuffer& buffer) { - //TODO: use little endian buffer >> value; + TrySwapBytes(value); + FromNetwork(value); } template void WriteData(const T& value, DataBuffer& buffer) { - //TODO: use little endian + ToNetwork(value); + TrySwapBytes(value); buffer << value; } };