• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #pragma once
2 
3 #include <type_traits>
4 #include <byteswap.h>
5 #include <stdint.h>
6 
7 static_assert((__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) ||
8 		      (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__),
9 	      "Unable to detect endianness");
10 
11 enum class endian {
12 	little = __ORDER_LITTLE_ENDIAN__,
13 	big = __ORDER_BIG_ENDIAN__,
14 	native = __BYTE_ORDER__
15 };
16 
17 template<typename T>
byteswap(T value)18 constexpr T byteswap(T value) noexcept
19 {
20 	static_assert(std::is_integral<T>(), "Type is not integral");
21 	static_assert(sizeof(T) == 2 ||
22 			      sizeof(T) == 4 ||
23 			      sizeof(T) == 8,
24 		      "Illegal value size");
25 
26 	switch (sizeof(T)) {
27 	case 2:
28 		return bswap_16(value);
29 	case 4:
30 		return bswap_32(value);
31 	case 8:
32 		return bswap_64(value);
33 	}
34 }
35 
36 template<endian E, typename T>
write_endian(T * dst,T val)37 static void write_endian(T* dst, T val)
38 {
39 	if constexpr (E != endian::native)
40 		val = byteswap(val);
41 
42 	*dst = val;
43 }
44 
write16le(uint16_t * dst,uint16_t val)45 [[maybe_unused]] static void write16le(uint16_t* dst, uint16_t val)
46 {
47 	write_endian<endian::little, uint16_t>(dst, val);
48 }
49