--- nono/lib/missing_endian.h 2026/04/29 17:04:30 1.1.1.2 +++ nono/lib/missing_endian.h 2026/04/29 17:05:57 1.1.1.5 @@ -1,50 +1,115 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // +// +// エンディアン関係 +// + +// エンディアン関係が定義してあるヘッダと、定義内容が全員微妙に異なる。 +// バイトオーダは BYTE_ORDER、LITTLE_ENDIAN、BIG_ENDIAN の3つの定義。 +// なお bswapNN() はここではなく missing_bswap.h 参照。 +// +// OS | ヘッダ | バイトオーダ | htobeNN() 系マクロ +// ---------+--------------------+--------------+------------------- +// NetBSD | | _BYTE_ORDER | あり +// FreeBSD | | | あり +// OpenBSD | | | あり(*1) +// Linux | | BYTE_ORDER | あり +// OSX | | BYTE_ORDER | なし +// +// *1: OpenBSD は本来 betohNN() のように NN は常に後置だったが beNNtoh() +// 形式も使える。 + #pragma once -#if !defined(_LITTLE_ENDIAN) -# define _LITTLE_ENDIAN 1234 -# define _BIG_ENDIAN 4321 -#endif - -#if !defined(_BYTE_ORDER) -# if defined(WORDS_BIGENDIAN) -# define _BYTE_ORDER _BIG_ENDIAN -# else -# define _BYTE_ORDER _LITTLE_ENDIAN -# endif -#endif - -// __builtin_bswap* がないような環境があったらその時考える -#if !defined(HAVE___BUILTIN_BSWAP16) || \ - !defined(HAVE___BUILTIN_BSWAP32) || \ - !defined(HAVE___BUILTIN_BSWAP64) -#error No __builtin_bswap* -#endif - -#if _BYTE_ORDER == _BIG_ENDIAN -#define be16toh(x) ((uint16)(x)) -#define be32toh(x) ((uint32)(x)) -#define be64toh(x) ((uint64)(x)) -#define le16toh(x) __builtin_bswap16((uint16)(x)) -#define le32toh(x) __builtin_bswap32((uint32)(x)) -#define le64toh(x) __builtin_bswap64((uint64)(x)) +#if defined(HAVE_ENDIAN_H) +#include // Linux +#endif +#if defined(HAVE_SYS_ENDIAN_H) +#include // *BSD +#endif +#if defined(HAVE_MACHINE_ENDIAN_H) +#include // OSX +#endif + +#if defined(BYTE_ORDER) +#elif defined(_BYTE_ORDER) +#define BYTE_ORDER _BYTE_ORDER +#elif defined(__BYTE_ORDER) +#define BYTE_ORDER __BYTE_ORDER +#else +#error no BYTE_ORDER defined +#endif + +#if defined(BIG_ENDIAN) +#elif defined(_BIG_ENDIAN) +#define BIG_ENDIAN _BIG_ENDIAN +#elif defined(__BIG_ENDIAN) +#define BIG_ENDIAN __BIG_ENDIAN +#else +#error no BIG_ENDIAN defined +#endif + +#if defined(LITTLE_ENDIAN) +#elif defined(_LITTLE_ENDIAN) +#define LITTLE_ENDIAN _LITTLE_ENDIAN +#elif defined(__LITTLE_ENDIAN) +#define LITTLE_ENDIAN __LITTLE_ENDIAN +#else +#error no LITTLE_ENDIAN defined +#endif + +// htobeNN() 系マクロ。 +// 代表として htobe16() の有無だけチェックしている。 +#if !defined(HAVE_HTOBE16) +#if defined(HAVE_LIBKERN_OSBYTEORDER_H) +#include +#define htobe16(x) OSSwapHostToBigInt16(x) +#define htobe32(x) OSSwapHostToBigInt32(x) +#define htobe64(x) OSSwapHostToBigInt64(x) +#define htole16(x) OSSwapHostToLittleInt16(x) +#define htole32(x) OSSwapHostToLittleInt32(x) +#define htole64(x) OSSwapHostToLittleInt64(x) + +#define be16toh(x) OSSwapBigToHostInt16(x) +#define be32toh(x) OSSwapBigToHostInt32(x) +#define be64toh(x) OSSwapBigToHostInt64(x) +#define le16toh(x) OSSwapLittleToHostInt16(x) +#define le32toh(x) OSSwapLittleToHostInt32(x) +#define le64toh(x) OSSwapLittleToHostInt64(x) + +#else +#error No htobeNN() family defined +#endif + +#endif // !HAVE_HTOBE16 + +// HTOBEnn() 系マクロ。 +// 代表として HTOBE16() の有無だけチェックしている。 +#if !defined(HAVE_INPLACE_HTOBE16) +#if BYTE_ORDER == BIG_ENDIAN +#define HTOBE16(x) (void)(x) +#define HTOBE32(x) (void)(x) +#define HTOBE64(x) (void)(x) +#define HTOLE16(x) (x) = (uint16)htole16(x) +#define HTOLE32(x) (x) = (uint32)htole32(x) +#define HTOLE64(x) (x) = (uint64)htole64(x) #else -#define be16toh(x) __builtin_bswap16((uint16)(x)) -#define be32toh(x) __builtin_bswap32((uint32)(x)) -#define be64toh(x) __builtin_bswap64((uint64)(x)) -#define le16toh(x) ((uint16)(x)) -#define le32toh(x) ((uint32)(x)) -#define le64toh(x) ((uint64)(x)) +#define HTOBE16(x) (x) = (uint16)htobe16(x) +#define HTOBE32(x) (x) = (uint32)htobe32(x) +#define HTOBE64(x) (x) = (uint64)htobe64(x) +#define HTOLE16(x) (void)(x) +#define HTOLE32(x) (void)(x) +#define HTOLE64(x) (void)(x) #endif -#define htobe16(x) be16toh(x) -#define htobe32(x) be32toh(x) -#define htobe64(x) be64toh(x) - -#define htole16(x) le16toh(x) -#define htole32(x) le32toh(x) -#define htole64(x) le64toh(x) +#define BE16TOH(x) HTOBE16(x) +#define BE32TOH(x) HTOBE32(x) +#define BE64TOH(x) HTOBE64(x) +#define LE16TOH(x) HTOLE16(x) +#define LE32TOH(x) HTOLE32(x) +#define LE64TOH(x) HTOLE64(x) +#endif // !HAVE_INPLACE_HTOBE16