Browse Source

improve checking for endianness

Julius Pfrommer 9 years ago
parent
commit
4523086d70
1 changed files with 54 additions and 22 deletions
  1. 54 22
      include/ua_config.h.in

+ 54 - 22
include/ua_config.h.in

@@ -43,41 +43,73 @@
 #endif
 
 /* Endianness */
-#if defined(__linux__) || defined(__APPLE__)
-# ifndef __QNX__
-#  if defined(__APPLE__) || defined(__MACH__)
-#   include <machine/endian.h>
-#  else
-#   include <endian.h>
-#  endif
-# endif
-# if ( __BYTE_ORDER != __LITTLE_ENDIAN )
-#  define UA_NON_LITTLEENDIAN_ARCHITECTURE
-# endif
-#elif _WIN32
+// UA_NON_LITTLEENDIAN_ARCHITECTURE disables memcpying integer arrays directly
+// onto the message buffer. UA_MIXED_ENDIAN enables special encoding for floats
+// and doubles. Otherwise, they are endianness-switched similar to integers.
+
+#if defined(__LITTLE_ENDIAN__) || defined(_WIN32) || (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+/* little-endian is the default assumption */
 # define htole16(x) (x)
 # define htole32(x) (x)
 # define htole64(x) (x)
 # define le16toh(x) (x)
 # define le32toh(x) (x)
 # define le64toh(x) (x)
+#else
+# if defined(__linux__)
+#  include <endian.h>
+# elif defined(__OpenBSD__)
+#  include <sys/endian.h>
+# elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#  include <sys/endian.h>
+   /* the htole functions are defined correctly */
+#  define le16toh(x) letoh16(x)
+#  define le32toh(x) letoh32(x)
+#  define le64toh(x) letoh64(x)
+# elif defined(__APPLE__)
+#  include <libkern/OSByteOrder.h>
+#  define htole16(x) OSSwapHostToLittleInt16(x)
+#  define htole32(x) OSSwapHostToLittleInt32(x)
+#  define htole64(x) OSSwapHostToLittleInt64(x)
+#  define le16toh(x) OSSwapLittleToHostInt16(x)
+#  define le32toh(x) OSSwapLittleToHostInt32(x)
+#  define le64toh(x) OSSwapLittleToHostInt64(x)
+#  define __BYTE_ORDER BYTE_ORDER
+# elif defined(__QNX__) || defined(__QNXNTO__)
+#  include <gulliver.h>
+#  if defined(__LITTLEENDIAN__)
+#   define __BYTE_ORDER __LITTLE_ENDIAN
+#  else
+#   define __BYTE_ORDER NON_LITTLE_ENDIAN
+#  endif
+#  define htole16(x) ENDIAN_LE16(x)
+#  define htole32(x) ENDIAN_LE32(x)
+#  define htole64(x) ENDIAN_LE64(x)
+#  define le16toh(x) ENDIAN_LE16(x)
+#  define le32toh(x) ENDIAN_LE32(x)
+#  define le64toh(x) ENDIAN_LE64(x)
+# endif
+# if ( __BYTE_ORDER != __LITTLE_ENDIAN )
+#  define UA_NON_LITTLEENDIAN_ARCHITECTURE
+# endif
 #endif
 
-/* Force non-little endian manually by setting the following. */
-// #define UA_NON_LITTLEENDIAN_ARCHITECTURE
-// #define htole16(x) {...}(x)
-// #define htole32(x) {...}(x)
-// #define htole64(x) {...}(x)
-// #define le16toh(x) {...}(x)
-// #define le32toh(x) {...}(x)
-// #define le64toh(x) {...}(x)
-
-/* Mixed Endian */
+/* Mixed Endian Example */
 #ifdef __ARM_ARCH_4T__
 # define UA_MIXED_ENDIAN
 # define UA_NON_LITTLEENDIAN_ARCHITECTURE
 #endif
 
+/* Manually override */
+// If required, manually define UA_NON_LITTLEENDIAN_ARCHITECTURE and
+// UA_MIXED_ENDIAN, as well as the htole / letoh functions here. Even better,
+// post an issue on github or the mailing list, so we can include the
+// architecture in the standard release.
+
+#ifndef htole16
+# error The endianness of the architecture not known
+#endif
+
 /* Inline Functions */
 #ifdef _MSC_VER
 # define UA_INLINE __inline