|
@@ -237,91 +237,108 @@ extern "C" {
|
|
|
#endif
|
|
|
|
|
|
/**
|
|
|
- * Detect Binary Overlaying for Encoding
|
|
|
- * -------------------------------------
|
|
|
- * Integers and floating point numbers are transmitted in little-endian (IEEE 754
|
|
|
- * for floating point) encoding. If the target architecture uses the same
|
|
|
- * format, numeral datatypes can be memcpy'd (overlayed) on the binary stream.
|
|
|
- * This speeds up encoding.
|
|
|
+ * Detect Endianness and IEEE 754 floating point
|
|
|
+ * ---------------------------------------------
|
|
|
+ * Integers and floating point numbers are transmitted in little-endian (IEEE
|
|
|
+ * 754 for floating point) encoding. If the target architecture uses the same
|
|
|
+ * format, numeral datatypes can be memcpy'd (overlayed) on the network buffer.
|
|
|
+ * Otherwise, a slow default encoding routine is used that works for every
|
|
|
+ * architecture.
|
|
|
*
|
|
|
* Integer Endianness
|
|
|
* ^^^^^^^^^^^^^^^^^^
|
|
|
- * The definition ``UA_BINARY_OVERLAYABLE_INTEGER`` is true when the integer
|
|
|
- * representation of the target architecture is little-endian. */
|
|
|
+ * The definition ``UA_LITTLE_ENDIAN`` is true when the integer representation
|
|
|
+ * of the target architecture is little-endian. */
|
|
|
#if defined(_WIN32)
|
|
|
-# define UA_BINARY_OVERLAYABLE_INTEGER 1
|
|
|
+# define UA_LITTLE_ENDIAN 1
|
|
|
#elif (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
|
|
|
(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
|
|
|
-# define UA_BINARY_OVERLAYABLE_INTEGER 1
|
|
|
+# define UA_LITTLE_ENDIAN 1
|
|
|
#elif defined(__linux__) /* Linux (including Android) */
|
|
|
# include <endian.h>
|
|
|
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
|
-# define UA_BINARY_OVERLAYABLE_INTEGER 1
|
|
|
+# define UA_LITTLE_ENDIAN 1
|
|
|
# endif
|
|
|
#elif defined(__OpenBSD__) /* OpenBSD */
|
|
|
# include <sys/endian.h>
|
|
|
# if BYTE_ORDER == LITTLE_ENDIAN
|
|
|
-# define UA_BINARY_OVERLAYABLE_INTEGER 1
|
|
|
+# define UA_LITTLE_ENDIAN 1
|
|
|
# endif
|
|
|
#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) /* Other BSD */
|
|
|
# include <sys/endian.h>
|
|
|
# if _BYTE_ORDER == _LITTLE_ENDIAN
|
|
|
-# define UA_BINARY_OVERLAYABLE_INTEGER 1
|
|
|
+# define UA_LITTLE_ENDIAN 1
|
|
|
# endif
|
|
|
#elif defined(__APPLE__) /* Apple (MacOS, iOS) */
|
|
|
# include <libkern/OSByteOrder.h>
|
|
|
# if defined(__LITTLE_ENDIAN__)
|
|
|
-# define UA_BINARY_OVERLAYABLE_INTEGER 1
|
|
|
+# define UA_LITTLE_ENDIAN 1
|
|
|
# endif
|
|
|
#elif defined(__QNX__) || defined(__QNXNTO__) /* QNX */
|
|
|
# include <gulliver.h>
|
|
|
# if defined(__LITTLEENDIAN__)
|
|
|
-# define UA_BINARY_OVERLAYABLE_INTEGER 1
|
|
|
+# define UA_LITTLE_ENDIAN 1
|
|
|
# endif
|
|
|
#endif
|
|
|
-
|
|
|
-#ifndef UA_BINARY_OVERLAYABLE_INTEGER
|
|
|
-# define UA_BINARY_OVERLAYABLE_INTEGER 0
|
|
|
+#ifndef UA_LITTLE_ENDIAN
|
|
|
+# define UA_LITTLE_ENDIAN 0
|
|
|
#endif
|
|
|
|
|
|
-/* Some platforms (e.g. QNX) have sizeof(bool) > 1. Disable overlayed integer
|
|
|
- * encoding if that is the case. */
|
|
|
-#if UA_BINARY_OVERLAYABLE_INTEGER == 1
|
|
|
+/* Can the integers be memcpy'd onto the network buffer? Add additional checks
|
|
|
+ * here. Some platforms (e.g. QNX) have sizeof(bool) > 1. Manually disable
|
|
|
+ * overlayed integer encoding if that is the case. */
|
|
|
+#if (UA_LITTLE_ENDIAN == 1)
|
|
|
UA_STATIC_ASSERT(sizeof(bool) == 1, cannot_overlay_integers_with_large_bool);
|
|
|
+# define UA_BINARY_OVERLAYABLE_INTEGER 1
|
|
|
+#else
|
|
|
+# define UA_BINARY_OVERLAYABLE_INTEGER 0
|
|
|
#endif
|
|
|
|
|
|
/**
|
|
|
* Float Endianness
|
|
|
* ^^^^^^^^^^^^^^^^
|
|
|
- * The definition ``UA_BINARY_OVERLAYABLE_FLOAT`` is true when the floating
|
|
|
- * point number representation of the target architecture is IEEE 754. Note that
|
|
|
- * this cannot be reliable detected with macros for the clang compiler
|
|
|
- * (beginning of 2017). ``UA_BINARY_OVERLAYABLE_FLOAT`` can be manually set if
|
|
|
- * the target is known to be little endian with floats in the IEEE 754
|
|
|
- * format. */
|
|
|
+ * The definition ``UA_FLOAT_IEEE754`` is set to true when the floating point
|
|
|
+ * number representation of the target architecture is IEEE 754. The definition
|
|
|
+ * ``UA_FLOAT_LITTLE_ENDIAN`` is set to true when the floating point number
|
|
|
+ * representation is in little-endian encoding. */
|
|
|
|
|
|
#if defined(_WIN32)
|
|
|
-# define UA_BINARY_OVERLAYABLE_FLOAT 1
|
|
|
+# define UA_FLOAT_IEEE754 1
|
|
|
+#elif defined(__i386__) || defined(__x86_64__) || defined(__amd64__) || \
|
|
|
+ defined(__ia64__) || defined(__powerpc__) || defined(__sparc__) || \
|
|
|
+ defined(__arm__)
|
|
|
+# define UA_FLOAT_IEEE754 1
|
|
|
+#elif defined(__STDC_IEC_559__)
|
|
|
+# define UA_FLOAT_IEEE754 1
|
|
|
+#else
|
|
|
+# define UA_FLOAT_IEEE754 0
|
|
|
+#endif
|
|
|
+
|
|
|
+/* Wikipedia says (https://en.wikipedia.org/wiki/Endianness): Although the
|
|
|
+ * ubiquitous x86 processors of today use little-endian storage for all types of
|
|
|
+ * data (integer, floating point, BCD), there are a number of hardware
|
|
|
+ * architectures where floating-point numbers are represented in big-endian form
|
|
|
+ * while integers are represented in little-endian form. */
|
|
|
+#if defined(_WIN32)
|
|
|
+# define UA_FLOAT_LITTLE_ENDIAN 1
|
|
|
+#elif defined(__i386__) || defined(__x86_64__) || defined(__amd64__)
|
|
|
+# define UA_FLOAT_LITTLE_ENDIAN 1
|
|
|
#elif defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
|
|
|
(__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__) /* Defined only in GCC */
|
|
|
-# define UA_BINARY_OVERLAYABLE_FLOAT 1
|
|
|
+# define UA_FLOAT_LITTLE_ENDIAN 1
|
|
|
#elif defined(__FLOAT_WORD_ORDER) && defined(__LITTLE_ENDIAN) && \
|
|
|
(__FLOAT_WORD_ORDER == __LITTLE_ENDIAN) /* Defined only in GCC */
|
|
|
-# define UA_BINARY_OVERLAYABLE_FLOAT 1
|
|
|
-#elif defined(__linux__) /* Linux (including Android) */
|
|
|
-# include <endian.h>
|
|
|
-# if defined(__ANDROID__)
|
|
|
-# if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
|
-# define UA_BINARY_OVERLAYABLE_INTEGER 1
|
|
|
-# endif
|
|
|
-# elif __FLOAT_WORD_ORDER == __LITTLE_ENDIAN
|
|
|
-# define UA_BINARY_OVERLAYABLE_FLOAT 1
|
|
|
-# endif
|
|
|
-#elif defined(_WRS_KERNEL)
|
|
|
-# define UA_BINARY_OVERLAYABLE_FLOAT 1
|
|
|
+# define UA_FLOAT_LITTLE_ENDIAN 1
|
|
|
+#endif
|
|
|
+#ifndef UA_FLOAT_LITTLE_ENDIAN
|
|
|
+# define UA_FLOAT_LITTLE_ENDIAN 0
|
|
|
#endif
|
|
|
|
|
|
-#ifndef UA_BINARY_OVERLAYABLE_FLOAT
|
|
|
+/* Only if the floating points are litle-endian **and** in IEEE 754 format can
|
|
|
+ * we memcpy directly onto the network buffer. */
|
|
|
+#if (UA_FLOAT_IEEE754 == 1) && (UA_FLOAT_LITTLE_ENDIAN == 1)
|
|
|
+# define UA_BINARY_OVERLAYABLE_FLOAT 1
|
|
|
+#else
|
|
|
# define UA_BINARY_OVERLAYABLE_FLOAT 0
|
|
|
#endif
|
|
|
|