9#define BSWAP16 _byteswap_ushort
10#define BSWAP32 _byteswap_ulong
11#define BSWAP64 _byteswap_uint64
13#define BSWAP16 __builtin_bswap16
14#define BSWAP32 __builtin_bswap32
15#define BSWAP64 __builtin_bswap64
24enum class Endianness {
28#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || defined(__BIG_ENDIAN__)
54 static inline int8_t ToInt8BE(
const uint8_t* data, int32_t offset) {
55 return (uint8_t)data[offset + 0];
59 static inline int8_t ToInt8BE(
const std::vector<uint8_t>& data, int32_t offset) {
60 return (uint8_t)data[offset + 0];
66 static inline uint8_t ToUInt8BE(
const uint8_t* data, int32_t offset) {
67 return (uint8_t)data[offset + 0];
71 static inline uint8_t ToUInt8BE(
const std::vector<uint8_t>& data, int32_t offset) {
72 return (uint8_t)data[offset + 0];
78 static inline int16_t ToInt16BE(
const uint8_t* data, int32_t offset) {
79 return ((uint16_t)data[offset + 0] << 8) + (uint16_t)data[offset + 1];
83 static inline int16_t ToInt16BE(
const std::vector<uint8_t>& data, int32_t offset) {
84 return ((uint16_t)data[offset + 0] << 8) + (uint16_t)data[offset + 1];
90 static inline uint16_t ToUInt16BE(
const uint8_t* data, int32_t offset) {
91 return ((uint16_t)data[offset + 0] << 8) + (uint16_t)data[offset + 1];
95 static inline uint16_t ToUInt16BE(
const std::vector<uint8_t>& data, int32_t offset) {
96 return ((uint16_t)data[offset + 0] << 8) + (uint16_t)data[offset + 1];
102 static inline int32_t ToInt32BE(
const uint8_t* data, int32_t offset) {
103 return ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) +
104 ((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3];
108 static inline int32_t ToInt32BE(
const std::vector<uint8_t>& data, int32_t offset) {
109 return ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) +
110 ((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3];
116 static inline uint32_t ToUInt32BE(
const uint8_t* data, int32_t offset) {
117 return ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) +
118 ((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3];
122 static inline uint32_t ToUInt32BE(
const std::vector<uint8_t>& data, int32_t offset) {
123 return ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) +
124 ((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3];
130 static inline int64_t ToInt64BE(
const uint8_t* data, int32_t offset) {
131 return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) +
132 ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) +
133 ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) +
134 ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]);
138 static inline int64_t ToInt64BE(
const std::vector<uint8_t>& data, int32_t offset) {
139 return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) +
140 ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) +
141 ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) +
142 ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]);
148 static inline uint64_t ToUInt64BE(
const uint8_t* data, int32_t offset) {
149 return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) +
150 ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) +
151 ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) +
152 ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]);
156 static inline uint64_t ToUInt64BE(
const std::vector<uint8_t>& data, int32_t offset) {
157 return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) +
158 ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) +
159 ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) +
160 ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]);
169 static inline float ToFloatBE(
const uint8_t* data, int32_t offset) {
171 uint32_t floatData = ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) +
172 ((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3];
173 static_assert(
sizeof(uint32_t) ==
sizeof(
float),
"expected 32-bit float");
174 std::memcpy(&value, &floatData,
sizeof(value));
179 static inline float ToFloatBE(
const std::vector<uint8_t>& data, int32_t offset) {
181 uint32_t floatData = ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) +
182 ((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3];
183 static_assert(
sizeof(uint32_t) ==
sizeof(
float),
"expected 32-bit float");
184 std::memcpy(&value, &floatData,
sizeof(value));
193 static inline double ToDoubleBE(
const uint8_t* data, int32_t offset) {
195 uint64_t floatData = ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) +
196 ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) +
197 ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) +
198 ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]);
199 static_assert(
sizeof(uint64_t) ==
sizeof(
double),
"expected 64-bit double");
202 static_assert(std::numeric_limits<float>::is_iec559,
"expected IEC559 floats on host machine");
203 std::memcpy(&value, &floatData,
sizeof(value));
208 static inline double ToDoubleBE(
const std::vector<uint8_t>& data, int32_t offset) {
210 uint64_t floatData = ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) +
211 ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) +
212 ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) +
213 ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]);
214 static_assert(
sizeof(uint64_t) ==
sizeof(
double),
"expected 64-bit double");
217 static_assert(std::numeric_limits<double>::is_iec559,
"expected IEC559 doubles on host machine");
218 std::memcpy(&value, &floatData,
sizeof(value));
233 static inline void RomToBigEndian(uint8_t* rom,
size_t romSize) {
239 uint8_t firstByte = rom[0];
243 for (
size_t pos = 0; pos < (romSize / 2); pos++) {
244 ((uint16_t*)rom)[pos] = ToUInt16BE(rom, pos * 2);
248 for (
size_t pos = 0; pos < (romSize / 4); pos++) {
249 ((uint32_t*)rom)[pos] = ToUInt32BE(rom, pos * 4);
@ Little
Least-significant byte first.
@ Native
Platform is little-endian; Native resolves to Little.
@ Big
Most-significant byte first.