#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() { static constexpr std::uint16_t test = 10; static const bool isBigEndian = reinterpret_cast(&test)[1] == 10; return isBigEndian; } /** * \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