Last active
May 15, 2022 06:48
-
-
Save Alexhuszagh/b0e8336d5af4cce31877f7da48765bc2 to your computer and use it in GitHub Desktop.
Cross-Platform Solution to Determine System Byte-Order
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// :copyright: (c) 2014-2016 Mathias Panzenböck | |
// :license: Public Domain/MIT, see licenses/MIT.txt for more details. | |
// :modified: Alex Huszagh, 2016. Added Windows-specific pre-processor definitions and byte-swap algorithms. | |
/** Endian utilties for determining and swapping byte order in | |
* applications. | |
*/ | |
#include <algorithm> | |
#pragma once | |
// MACROS | |
// ------ | |
// INTEGERS | |
// -------- | |
#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__) | |
# define __WINDOWS__ | |
#endif | |
#if defined(__linux__) || defined(__CYGWIN__) | |
# include <endian.h> | |
#elif defined(__APPLE__) | |
# include <libkern/OSByteOrder.h> | |
# define htobe16(x) OSSwapHostToBigInt16(x) | |
# define htole16(x) OSSwapHostToLittleInt16(x) | |
# define be16toh(x) OSSwapBigToHostInt16(x) | |
# define le16toh(x) OSSwapLittleToHostInt16(x) | |
# define htobe32(x) OSSwapHostToBigInt32(x) | |
# define htole32(x) OSSwapHostToLittleInt32(x) | |
# define be32toh(x) OSSwapBigToHostInt32(x) | |
# define le32toh(x) OSSwapLittleToHostInt32(x) | |
# define htobe64(x) OSSwapHostToBigInt64(x) | |
# define htole64(x) OSSwapHostToLittleInt64(x) | |
# define be64toh(x) OSSwapBigToHostInt64(x) | |
# define le64toh(x) OSSwapLittleToHostInt64(x) | |
# define __BYTE_ORDER BYTE_ORDER | |
# define __BIG_ENDIAN BIG_ENDIAN | |
# define __LITTLE_ENDIAN LITTLE_ENDIAN | |
# define __PDP_ENDIAN PDP_ENDIAN | |
#elif defined(__OpenBSD__) | |
# include <sys/endian.h> | |
#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) | |
# include <sys/endian.h> | |
# define be16toh(x) betoh16(x) | |
# define le16toh(x) letoh16(x) | |
# define be32toh(x) betoh32(x) | |
# define le32toh(x) letoh32(x) | |
# define be64toh(x) betoh64(x) | |
# define le64toh(x) letoh64(x) | |
#elif defined(__WINDOWS__) | |
# include <winsock2.h> | |
# include <Windows.h> | |
# ifndef BIG_ENDIAN | |
/* Windows does not always set byte order, such as MSVC */ | |
# define LITTLE_ENDIAN REG_DWORD_LITTLE_ENDIAN | |
# define BIG_ENDIAN REG_DWORD_BIG_ENDIAN | |
# if REG_DWORD == REG_DWORD_BIG_ENDIAN | |
# define BYTE_ORDER BIG_ENDIAN | |
# else | |
# define BYTE_ORDER LITTLE_ENDIAN | |
# endif | |
# endif | |
# if BYTE_ORDER == LITTLE_ENDIAN | |
# define htobe16(x) htons(x) | |
# define htole16(x) (x) | |
# define be16toh(x) ntohs(x) | |
# define le16toh(x) (x) | |
# define htobe32(x) htonl(x) | |
# define htole32(x) (x) | |
# define be32toh(x) ntohl(x) | |
# define le32toh(x) (x) | |
# define htobe64(x) htonll(x) | |
# define htole64(x) (x) | |
# define be64toh(x) ntohll(x) | |
# define le64toh(x) (x) | |
# elif BYTE_ORDER == BIG_ENDIAN | |
/* that would be xbox 360 */ | |
# define htobe16(x) (x) | |
# define htole16(x) __builtin_bswap16(x) | |
# define be16toh(x) (x) | |
# define le16toh(x) __builtin_bswap16(x) | |
# define htobe32(x) (x) | |
# define htole32(x) __builtin_bswap32(x) | |
# define be32toh(x) (x) | |
# define le32toh(x) __builtin_bswap32(x) | |
# define htobe64(x) (x) | |
# define htole64(x) __builtin_bswap64(x) | |
# define be64toh(x) (x) | |
# define le64toh(x) __builtin_bswap64(x) | |
# else | |
# error byte order not supported | |
# endif | |
# define __BYTE_ORDER BYTE_ORDER | |
# define __BIG_ENDIAN BIG_ENDIAN | |
# define __LITTLE_ENDIAN LITTLE_ENDIAN | |
# define __PDP_ENDIAN PDP_ENDIAN | |
#else | |
# error platform not supported | |
#endif | |
// FLOATS | |
// ------ | |
#ifndef __FLOAT_WORD_ORDER | |
#define __FLOAT_WORD_ORDER LITTLE_ENDIAN | |
#endif | |
#ifndef FLOAT_WORD_ORDER | |
#define FLOAT_WORD_ORDER __FLOAT_WORD_ORDER | |
#endif | |
// DEFINITIONS | |
// ----------- | |
/** Reverse byte order for a single C primitive. | |
* | |
* @param value Value to swap byte order (inplace) for | |
*/ | |
template <typename T> | |
void byteswap(T *value) | |
{ | |
const int size = sizeof(*value); | |
char *cast = (char *) value; | |
char *lo = cast; | |
char *hi = cast + size - 1; | |
char swap; | |
while (lo < hi) { | |
swap = *lo; | |
*lo++ = *hi; | |
*hi-- = swap; | |
} | |
} | |
/** Reverse byte order for an array of C primitives. | |
* | |
* @param value Array of values to swap byteorder for | |
* @param size Size of array | |
*/ | |
template <typename T> | |
void byteswap(T *value, const unsigned int &size) | |
{ | |
#pragma omp parallel for | |
for (int i = 0; i < size; i++) { | |
byteswap(&value[i]); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment