From d7cd4ff3ae10cc75e006f1b927d831899810e4a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E7=9A=93?= Date: Mon, 10 Feb 2025 18:58:47 -0500 Subject: [PATCH] Implement serialization for big-endian platforms --- src/util/serial-util.h | 50 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/src/util/serial-util.h b/src/util/serial-util.h index 45a6bde..49e9f6f 100644 --- a/src/util/serial-util.h +++ b/src/util/serial-util.h @@ -23,14 +23,11 @@ #define SERIALUTIL_H #include +#include #include #include -#if SDL_BYTEORDER != SDL_LIL_ENDIAN -#error "Non little endian systems not supported" -#endif - static inline int32_t readInt32(const char **dataP) { @@ -39,23 +36,56 @@ readInt32(const char **dataP) memcpy(&result, *dataP, 4); *dataP += 4; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN +# ifdef _MSC_VER + static_assert(sizeof(unsigned long) == sizeof(int32_t), "unsigned long should be 32 bits"); + result = (int32_t)_byteswap_ulong((unsigned long)result); +# else + result = (int32_t)__builtin_bswap32((uint32_t)result); +# endif +#endif + return result; } static inline double readDouble(const char **dataP) { +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + uint64_t result; + + memcpy(&result, *dataP, 8); + *dataP += 8; + +# ifdef _MSC_VER + result = (uint64_t)_byteswap_uint64((unsigned __int64)result); +# else + result = __builtin_bswap64(result); +# endif + + return *(double *)&result; +#else double result; memcpy(&result, *dataP, 8); *dataP += 8; return result; +#endif } static inline void writeInt32(char **dataP, int32_t value) { +#if SDL_BYTEORDER == SDL_BIG_ENDIAN +# ifdef _MSC_VER + static_assert(sizeof(unsigned long) == sizeof(int32_t), "unsigned long should be 32 bits"); + value = (int32_t)_byteswap_ulong((unsigned long)value); +# else + value = (int32_t)__builtin_bswap32((uint32_t)value); +# endif +#endif + memcpy(*dataP, &value, 4); *dataP += 4; } @@ -63,7 +93,19 @@ writeInt32(char **dataP, int32_t value) static inline void writeDouble(char **dataP, double value) { +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + uint64_t valueUint = *(uint64_t *)&value; + +# ifdef _MSC_VER + valueUint = (uint64_t)_byteswap_uint64((unsigned __int64)valueUint); +# else + valueUint = __builtin_bswap64(valueUint); +# endif + + memcpy(*dataP, &valueUint, 8); +#else memcpy(*dataP, &value, 8); +#endif *dataP += 8; }