Enigma  3.2.0
A Simple, Reliable and Efficient Encryption Tool
Endianness.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #if defined(_MSC_VER)
4 #include <stdlib.h>
5 #endif
6 
7 #include <cstdint>
8 #include <bit>
9 
10 #ifdef __has_builtin
11 #define ENIGMA_HAVE_BUILTIN(x) __has_builtin(x)
12 #else
13 #define ENIGMA_HAVE_BUILTIN(x) false
14 #endif
15 
16 namespace Enigma {
17 
18  inline std::uint64_t BSwap64(std::uint64_t host_int) {
19 #if defined(__GNUC__) || ENIGMA_HAVE_BUILTIN(__builtin_bswap64)
20  return __builtin_bswap64(host_int);
21 #elif defined(_MSC_VER)
22  return _byteswap_uint64(host_int);
23 #else
24  return (((host_int & std::uint64_t{0xFF}) << 56) |
25  ((host_int & std::uint64_t{0xFF00}) << 40) |
26  ((host_int & std::uint64_t{0xFF0000}) << 24) |
27  ((host_int & std::uint64_t{0xFF000000}) << 8) |
28  ((host_int & std::uint64_t{0xFF00000000}) >> 8) |
29  ((host_int & std::uint64_t{0xFF0000000000}) >> 24) |
30  ((host_int & std::uint64_t{0xFF000000000000}) >> 40) |
31  ((host_int & std::uint64_t{0xFF00000000000000}) >> 56));
32 #endif
33  }
34 
35  inline std::uint32_t BSwap32(std::uint32_t host_int) {
36 #if defined(__GNUC__) || ENIGMA_HAVE_BUILTIN(__builtin_bswap32)
37  return __builtin_bswap32(host_int);
38 #elif defined(_MSC_VER)
39  return _byteswap_ulong(host_int);
40 #else
41  return (((host_int & std::uint32_t{0xFF}) << 24) |
42  ((host_int & std::uint32_t{0xFF00}) << 8) |
43  ((host_int & std::uint32_t{0xFF0000}) >> 8) |
44  ((host_int & std::uint32_t{0xFF000000}) >> 24));
45 #endif
46  }
47 
48  inline std::uint16_t BSwap16(std::uint16_t host_int) {
49 #if defined(__GNUC__) || ENIGMA_HAVE_BUILTIN(__builtin_bswap16)
50  return __builtin_bswap16(host_int);
51 #elif defined(_MSC_VER)
52  return _byteswap_ushort(host_int);
53 #else
54  return (((host_int & std::uint16_t{0xFF}) << 8) |
55  ((host_int & std::uint16_t{0xFF00}) >> 8));
56 #endif
57  }
58 
59  namespace LittleEndian {
60 
61  inline std::uint16_t fromHost(std::uint16_t value) {
62  if (std::endian::native == std::endian::big) {
63  return BSwap16(value);
64  } else {
65  return value;
66  }
67  }
68 
69  inline std::uint32_t fromHost(std::uint32_t value) {
70  if (std::endian::native == std::endian::big) {
71  return BSwap32(value);
72  } else {
73  return value;
74  }
75  }
76 
77  inline std::uint64_t fromHost(std::uint64_t value) {
78  if (std::endian::native == std::endian::big) {
79  return BSwap64(value);
80  } else {
81  return value;
82  }
83  }
84 
85  inline std::uint16_t toHost(std::uint16_t value) {
86  if (std::endian::native == std::endian::big) {
87  return BSwap16(value);
88  } else {
89  return value;
90  }
91  }
92 
93  inline std::uint32_t toHost(std::uint32_t value) {
94  if (std::endian::native == std::endian::big) {
95  return BSwap32(value);
96  } else {
97  return value;
98  }
99  }
100 
101  inline std::uint64_t toHost(std::uint64_t value) {
102  if (std::endian::native == std::endian::big) {
103  return BSwap64(value);
104  } else {
105  return value;
106  }
107  }
108 
109  } // namespace LittleEndian
110 
111  //[[maybe_unused]]
112  namespace BigEndian {
113 
114  inline std::uint16_t fromHost(std::uint16_t value) {
115  if (std::endian::native == std::endian::big) {
116  return value;
117  } else {
118  return BSwap16(value);
119  }
120  if (std::endian::native == std::endian::big) {
121  return value;
122  } else {
123  return BSwap16(value);
124  }
125  }
126 
127  inline std::uint32_t fromHost(std::uint32_t value) {
128  if (std::endian::native == std::endian::big) {
129  return value;
130  } else {
131  return BSwap32(value);
132  }
133  }
134 
135  inline std::uint64_t fromHost(std::uint64_t value) {
136  if (std::endian::native == std::endian::big) {
137  return value;
138  } else {
139  return BSwap64(value);
140  }
141  }
142 
143  inline std::uint16_t toHost(std::uint16_t value) {
144  if (std::endian::native == std::endian::big) {
145  return value;
146  } else {
147  return BSwap16(value);
148  }
149  }
150 
151  inline std::uint32_t toHost(std::uint32_t value) {
152  if (std::endian::native == std::endian::big) {
153  return value;
154  } else {
155  return BSwap32(value);
156  }
157  }
158 
159  inline std::uint64_t toHost(std::uint64_t value) {
160  if (std::endian::native == std::endian::big) {
161  return value;
162  } else {
163  return BSwap64(value);
164  }
165  }
166 
167  } // namespace BigEndian
168 
169 } // namespace Enigma
std::uint16_t toHost(std::uint16_t value)
Definition: Endianness.hpp:143
std::uint16_t fromHost(std::uint16_t value)
Definition: Endianness.hpp:114
std::uint16_t fromHost(std::uint16_t value)
Definition: Endianness.hpp:61
std::uint16_t toHost(std::uint16_t value)
Definition: Endianness.hpp:85
std::uint64_t BSwap64(std::uint64_t host_int)
Definition: Endianness.hpp:18
std::uint32_t BSwap32(std::uint32_t host_int)
Definition: Endianness.hpp:35
std::uint16_t BSwap16(std::uint16_t host_int)
Definition: Endianness.hpp:48