#ifndef UTIL_BIG_ENDIAN_H_
#define UTIL_BIG_ENDIAN_H_
#include <stdint.h>
#include <cstring>
#include <type_traits>
namespace openscreen {
inline bool IsBigEndianArchitecture() { … }
namespace internal {
template <int size>
struct MakeSizedUnsignedInteger;
template <>
struct MakeSizedUnsignedInteger<1> { … };
template <>
struct MakeSizedUnsignedInteger<2> { … };
template <>
struct MakeSizedUnsignedInteger<4> { … };
template <>
struct MakeSizedUnsignedInteger<8> { … };
template <int size>
inline typename MakeSizedUnsignedInteger<size>::type ByteSwap(
typename MakeSizedUnsignedInteger<size>::type x) { … }
template <>
inline uint8_t ByteSwap<1>(uint8_t x) { … }
#if defined(__clang__) || defined(__GNUC__)
template <>
inline uint64_t ByteSwap<8>(uint64_t x) { … }
template <>
inline uint32_t ByteSwap<4>(uint32_t x) { … }
template <>
inline uint16_t ByteSwap<2>(uint16_t x) { … }
#elif defined(_MSC_VER)
template <>
inline uint64_t ByteSwap<8>(uint64_t x) {
return _byteswap_uint64(x);
}
template <>
inline uint32_t ByteSwap<4>(uint32_t x) {
return _byteswap_ulong(x);
}
template <>
inline uint16_t ByteSwap<2>(uint16_t x) {
return _byteswap_ushort(x);
}
#else
#include <byteswap.h>
template <>
inline uint64_t ByteSwap<8>(uint64_t x) {
return bswap_64(x);
}
template <>
inline uint32_t ByteSwap<4>(uint32_t x) {
return bswap_32(x);
}
template <>
inline uint16_t ByteSwap<2>(uint16_t x) {
return bswap_16(x);
}
#endif
}
template <typename Integer>
inline std::enable_if_t<std::is_unsigned<Integer>::value, Integer> ByteSwap(
Integer x) { … }
template <typename Integer>
inline Integer ReadBigEndian(const void* src) { … }
template <typename Integer>
inline void WriteBigEndian(Integer val, void* dest) { … }
template <class T>
class BigEndianBuffer { … };
class BigEndianReader : public BigEndianBuffer<const uint8_t> { … };
class BigEndianWriter : public BigEndianBuffer<uint8_t> { … };
}
#endif