From 9b87071f2423f4e4e54355fdc0546b96d41d72ab Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 29 Aug 2024 11:37:05 +0300 Subject: [PATCH] add byteorder-related functions to data_io.hpp --- src/util/data_io.hpp | 63 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/src/util/data_io.hpp b/src/util/data_io.hpp index c36007b5..02642a54 100644 --- a/src/util/data_io.hpp +++ b/src/util/data_io.hpp @@ -3,16 +3,67 @@ #include "typedefs.hpp" namespace dataio { - /* Read big-endian 16 bit signed integer from bytes */ + /// @brief Swap byte-order for value of type T + /// @tparam T value type + /// @param value source integer + /// @return swapped integer + template + T swap(T value) { + union{ + T value; + ubyte bytes[sizeof(T)]; + } source, dest; + + source.value = value; + + for (size_t i = 0; i < sizeof(T); i++) { + dest.bytes[i] = source.bytes[sizeof(T) - i - 1]; + } + return dest.value; + } + + inline bool is_big_endian() { + uint16_t num = 1; + auto bytes = reinterpret_cast(num); + return bytes[1] == 1; + } + + /// @brief Convert big-endian to hardware byte-order + /// @tparam T value type + /// @param value source integer + /// @return integer with hardware byte-order + template + T be2h(T value){ + if (is_big_endian()) { + return value; + } else { + return swap(value); + } + } + + /// @brief Convert little-endian to hardware byte-order + /// @tparam T value type + /// @param value source integer + /// @return integer with hardware byte-order + template + T le2h(T value){ + if (is_big_endian()) { + return swap(value); + } else { + return value; + } + } + + /// @brief Read big-endian 16 bit signed integer from bytes inline int16_t read_int16_big(const ubyte* src, size_t offset) { return (src[offset] << 8) | (src[offset + 1]); } - /* Read big-endian 32 bit signed integer from bytes */ + /// @brief Read big-endian 32 bit signed integer from bytes inline int32_t read_int32_big(const ubyte* src, size_t offset) { return (src[offset] << 24) | (src[offset + 1] << 16) | (src[offset + 2] << 8) | (src[offset + 3]); } - /* Read big-endian 64 bit signed integer from bytes */ + /// @brief Read big-endian 64 bit signed integer from bytes inline int64_t read_int64_big(const ubyte* src, size_t offset) { return (int64_t(src[offset]) << 56) | (int64_t(src[offset + 1]) << 48) | (int64_t(src[offset + 2]) << 40) | @@ -21,19 +72,19 @@ namespace dataio { (int64_t(src[offset + 5]) << 16) | (int64_t(src[offset + 6]) << 8) | (int64_t(src[offset + 7])); } - /* Write big-endian 16 bit signed integer to bytes */ + /// @brief Write big-endian 16 bit signed integer to bytes inline void write_int16_big(int16_t value, ubyte* dest, size_t offset) { dest[offset] = (char)(value >> 8 & 255); dest[offset + 1] = (char)(value >> 0 & 255); } - /* Write big-endian 32 bit signed integer to bytes */ + /// @brief Write big-endian 32 bit signed integer to bytes inline void write_int32_big(int32_t value, ubyte* dest, size_t offset) { dest[offset] = (char)(value >> 24 & 255); dest[offset + 1] = (char)(value >> 16 & 255); dest[offset + 2] = (char)(value >> 8 & 255); dest[offset + 3] = (char)(value >> 0 & 255); } - /* Write big-endian 64 bit signed integer to bytes */ + /// @brief Write big-endian 64 bit signed integer to bytes inline void write_int64_big(int64_t value, ubyte* dest, size_t offset) { dest[offset] = (char)(value >> 56 & 255); dest[offset + 1] = (char)(value >> 48 & 255);