diff --git a/src/Utils/Utils/Endianness.cpp b/src/Utils/Utils/Endianness.cpp new file mode 100644 index 00000000..4047984e --- /dev/null +++ b/src/Utils/Utils/Endianness.cpp @@ -0,0 +1,219 @@ +#include "Endianness.h" + +#if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER) + +namespace endianness +{ + constexpr uint16_t byteswap16u(const uint16_t in) + { + return static_cast( + (in >> 8) | + (in << 8) + ); + } + + constexpr int16_t byteswap16s(const int16_t in) + { + return static_cast(byteswap16u(static_cast(in))); + } + + constexpr uint32_t byteswap32u(const uint32_t in) + { + return static_cast( + (in >> 24) | + ((in >> 8) & 0x0000FF00ui32) | + ((in << 8) & 0x00FF0000ui32) | + (in << 24) + ); + } + + constexpr int32_t byteswap32s(const int32_t in) + { + return static_cast(byteswap32u(static_cast(in))); + } + + constexpr uint64_t byteswap64u(const uint64_t in) + { + return static_cast( + (in >> 56) | + ((in >> 40) & 0x000000000000FF00ui64) | + ((in >> 24) & 0x0000000000FF0000ui64) | + ((in >> 8) & 0x00000000FF000000ui64) | + ((in << 8) & 0x000000FF00000000ui64) | + ((in << 24) & 0x0000FF0000000000ui64) | + ((in << 40) & 0x00FF000000000000ui64) | + (in << 56) + ); + } + + constexpr int64_t byteswap64s(const int64_t in) + { + return static_cast(byteswap64u(static_cast(in))); + } +} + +#else + +namespace endianness +{ + constexpr int16_t byteswap16s(const int16_t in) + { + return static_cast(__builtin_bswap16(static_cast(in))); + } + + constexpr uint16_t byteswap16u(const uint16_t in) + { + return __builtin_bswap16(in); + } + + constexpr int32_t byteswap32s(const int32_t in) + { + return static_cast(__builtin_bswap32(static_cast(in))); + } + + constexpr uint32_t byteswap32u(const uint32_t in) + { + return __builtin_bswap32(in); + } + + constexpr int64_t byteswap64s(const int64_t in) + { + return static_cast(__builtin_bswap64(static_cast(in))); + } + + constexpr uint64_t byteswap64u(const uint64_t in) + { + return __builtin_bswap64(in); + } +} + +#endif + +namespace endianness +{ +#if HOST_ENDIANNESS == LITTLE_ENDIAN_ENDIANNESS + + int16_t ToBigEndian(const int16_t in) + { + return byteswap16s(in); + } + + uint16_t ToBigEndian(const uint16_t in) + { + return byteswap16u(in); + } + + int32_t ToBigEndian(const int32_t in) + { + return byteswap32s(in); + } + + uint32_t ToBigEndian(const uint32_t in) + { + return byteswap32u(in); + } + + int64_t ToBigEndian(const int64_t in) + { + return byteswap64s(in); + } + + uint64_t ToBigEndian(const uint64_t in) + { + return byteswap64u(in); + } + + int16_t FromBigEndian(const int16_t in) + { + return byteswap16s(in); + } + + uint16_t FromBigEndian(const uint16_t in) + { + return byteswap16u(in); + } + + int32_t FromBigEndian(const int32_t in) + { + return byteswap32s(in); + } + + uint32_t FromBigEndian(const uint32_t in) + { + return byteswap32u(in); + } + + int64_t FromBigEndian(const int64_t in) + { + return byteswap64s(in); + } + + uint64_t FromBigEndian(const uint64_t in) + { + return byteswap64u(in); + } + +#else + + int16_t ToLittleEndian(const int16_t in) + { + return byteswap16s(in); + } + + uint16_t ToLittleEndian(const uint16_t in) + { + return byteswap16u(in); + } + + int32_t ToLittleEndian(const int32_t in) + { + return byteswap32s(in); + } + + uint32_t ToLittleEndian(const uint32_t in) + { + return byteswap32u(in); + } + + int64_t ToLittleEndian(const int64_t in) + { + return byteswap64s(in); + } + + uint64_t ToLittleEndian(const uint64_t in) + { + return byteswap64u(in); + } + + int16_t FromLittleEndian(const int16_t in) + { + return byteswap16s(in); + } + + uint16_t FromLittleEndian(const uint16_t in) + { + return byteswap16u(in); + } + + int32_t FromLittleEndian(const int32_t in) + { + return byteswap32s(in); + } + + uint32_t FromLittleEndian(const uint32_t in) + { + return byteswap32u(in); + } + + int64_t FromLittleEndian(const int64_t in) + { + return byteswap64s(in); + } + + uint64_t FromLittleEndian(const uint64_t in) + { + return byteswap64u(in); + } + +#endif +} diff --git a/src/Utils/Utils/Endianness.h b/src/Utils/Utils/Endianness.h new file mode 100644 index 00000000..196ae796 --- /dev/null +++ b/src/Utils/Utils/Endianness.h @@ -0,0 +1,82 @@ +#pragma once + +#include + +#define LITTLE_ENDIAN_ENDIANNESS 1234 +#define BIG_ENDIAN_ENDIANNESS 4321 + +#if defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER) + +// Windows always considered Little Endian +#define HOST_ENDIANNESS LITTLE_ENDIAN_ENDIANNESS + +#else + +#include +#if _BYTE_ORDER == _LITTLE_ENDIAN +#define HOST_ENDIANNESS LITTLE_ENDIAN_ENDIANNESS +#else +#define HOST_ENDIANNESS BIG_ENDIAN_ENDIANNESS +#endif + +#endif + +namespace endianness +{ +#if HOST_ENDIANNESS == LITTLE_ENDIAN_ENDIANNESS + constexpr int16_t ToLittleEndian(const int16_t in) { return in; } + constexpr uint16_t ToLittleEndian(const uint16_t in) { return in; } + constexpr int32_t ToLittleEndian(const int32_t in) { return in; } + constexpr uint32_t ToLittleEndian(const uint32_t in) { return in; } + constexpr int64_t ToLittleEndian(const int64_t in) { return in; } + constexpr uint64_t ToLittleEndian(const uint64_t in) { return in; } + constexpr int16_t FromLittleEndian(const int16_t in) { return in; } + constexpr uint16_t FromLittleEndian(const uint16_t in) { return in; } + constexpr int32_t FromLittleEndian(const int32_t in) { return in; } + constexpr uint32_t FromLittleEndian(const uint32_t in) { return in; } + constexpr int64_t FromLittleEndian(const int64_t in) { return in; } + constexpr uint64_t FromLittleEndian(const uint64_t in) { return in; } +#else + int16_t ToLittleEndian(int16_t in); + uint16_t ToLittleEndian(uint16_t in); + int32_t ToLittleEndian(int32_t in); + uint32_t ToLittleEndian(uint32_t in); + int64_t ToLittleEndian(int64_t in); + uint64_t ToLittleEndian(uint64_t in); + int16_t FromLittleEndian(int16_t in); + uint16_t FromLittleEndian(uint16_t in); + int32_t FromLittleEndian(int32_t in); + uint32_t FromLittleEndian(uint32_t in); + int64_t FromLittleEndian(int64_t in); + uint64_t FromLittleEndian(uint64_t in); +#endif + + +#if HOST_ENDIANNESS == BIG_ENDIAN_ENDIANNESS + constexpr int16_t ToBigEndian(const int16_t in) { return in; } + constexpr uint16_t ToBigEndian(const uint16_t in) { return in; } + constexpr int32_t ToBigEndian(const int32_t in) { return in; } + constexpr uint32_t ToBigEndian(const uint32_t in) { return in; } + constexpr int64_t ToBigEndian(const int64_t in) { return in; } + constexpr uint64_t ToBigEndian(const uint64_t in) { return in; } + constexpr int16_t FromBigEndian(const int16_t in) { return in; } + constexpr uint16_t FromBigEndian(const uint16_t in) { return in; } + constexpr int32_t FromBigEndian(const int32_t in) { return in; } + constexpr uint32_t FromBigEndian(const uint32_t in) { return in; } + constexpr int64_t FromBigEndian(const int64_t in) { return in; } + constexpr uint64_t FromBigEndian(const uint64_t in) { return in; } +#else + int16_t ToBigEndian(int16_t in); + uint16_t ToBigEndian(uint16_t in); + int32_t ToBigEndian(int32_t in); + uint32_t ToBigEndian(uint32_t in); + int64_t ToBigEndian(int64_t in); + uint64_t ToBigEndian(uint64_t in); + int16_t FromBigEndian(int16_t in); + uint16_t FromBigEndian(uint16_t in); + int32_t FromBigEndian(int32_t in); + uint32_t FromBigEndian(uint32_t in); + int64_t FromBigEndian(int64_t in); + uint64_t FromBigEndian(uint64_t in); +#endif +}