From c60cc4c17191bc432e89af914dde700724633b38 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Sat, 16 Nov 2013 01:10:01 +0100 Subject: Moved endian functions into convenience header --- src/uscxml/Convenience.h | 146 +++++++++++++++++++++ .../plugins/datamodel/ecmascript/TypedArray.cpp | 2 +- .../plugins/datamodel/ecmascript/TypedArray.h | 136 ------------------- 3 files changed, 147 insertions(+), 137 deletions(-) diff --git a/src/uscxml/Convenience.h b/src/uscxml/Convenience.h index 64abbda..f764d06 100644 --- a/src/uscxml/Convenience.h +++ b/src/uscxml/Convenience.h @@ -20,6 +20,8 @@ #ifndef CONVENIENCE_H_LU7GZ6CB #define CONVENIENCE_H_LU7GZ6CB +#include + namespace uscxml { inline bool isnan(double x) { return x != x; @@ -57,6 +59,150 @@ inline bool iequals(const std::string& a, const std::string& b) { return true; } +// see http://www.cplusplus.com/forum/general/27544/ + +// Little-endian operating systems: +//--------------------------------- +// Linux on x86, x64, Alpha and Itanium +// Mac OS on x86, x64 +// Solaris on x86, x64, PowerPC +// Tru64 on Alpha +// Windows on x86, x64 and Itanium + +// Big-endian operating systems: +//------------------------------ +// AIX on POWER +// AmigaOS on PowerPC and 680x0 +// HP-UX on Itanium and PA-RISC +// Linux on MIPS, SPARC, PA-RISC, POWER, PowerPC, and 680x0 +// Mac OS on PowerPC and 680x0 +// Solaris on SPARC + +/** +Detect endianness, see http://stackoverflow.com/questions/809902/64-bit-ntohl-in-c +union { + unsigned long long ull; + char c[8]; +} x; +x.ull = 0x0123456789abcdef; // may need special suffix for ULL. +*/ + +enum endianness { + little_endian, + big_endian, + network_endian = big_endian, + +#if defined(BOOST_LITTLE_ENDIAN) + host_endian = little_endian +#elif defined(BOOST_BIG_ENDIAN) + host_endian = big_endian +#else +#error "unable to determine system endianness" +#endif +}; + +namespace detail { + + template + struct swap_bytes { + inline T operator()(T val) { + throw std::out_of_range("data size"); + } + }; + + template + struct swap_bytes { + inline T operator()(T val) { + return val; + } + }; + + template + struct swap_bytes { // for 16 bit + inline T operator()(T val) { + return ((((val) >> 8) & 0xff) | (((val) & 0xff) << 8)); + } + }; + + template + struct swap_bytes { // for 32 bit + inline T operator()(T val) { +#if defined(_USE_BUILTIN_BSWAPS) && defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4) + return __builtin_bswap32(val); +#else + return ((((val) & 0xff000000) >> 24) | + (((val) & 0x00ff0000) >> 8) | + (((val) & 0x0000ff00) << 8) | + (((val) & 0x000000ff) << 24)); +#endif + } + }; + + template<> + struct swap_bytes { + inline float operator()(float val) { + uint32_t mem = swap_bytes()(*(uint32_t*)&val); + return *(float*)&mem; + } + }; + + template + struct swap_bytes { // for 64 bit + inline T operator()(T val) { +#if defined(_USE_BUILTIN_BSWAPS) && defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4) + return __builtin_bswap64(val); +#else + return ((((val) & 0xff00000000000000ull) >> 56) | + (((val) & 0x00ff000000000000ull) >> 40) | + (((val) & 0x0000ff0000000000ull) >> 24) | + (((val) & 0x000000ff00000000ull) >> 8 ) | + (((val) & 0x00000000ff000000ull) << 8 ) | + (((val) & 0x0000000000ff0000ull) << 24) | + (((val) & 0x000000000000ff00ull) << 40) | + (((val) & 0x00000000000000ffull) << 56)); +#endif + } + }; + + template<> + struct swap_bytes { + inline double operator()(double val) { + uint64_t mem = swap_bytes()(*(uint64_t*)&val); + return *(double*)&mem; + } + }; + + template + struct do_byte_swap { + inline T operator()(T value) { + return swap_bytes()(value); + } + }; + // specialisations when attempting to swap to the same endianess + template struct do_byte_swap { + inline T operator()(T value) { + return value; + } + }; + template struct do_byte_swap { + inline T operator()(T value) { + return value; + } + }; + +} // namespace detail + +template +inline T byte_swap(T value) { + // ensure the data is only 1, 2, 4 or 8 bytes + BOOST_STATIC_ASSERT(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8); + // ensure we're only swapping arithmetic types + BOOST_STATIC_ASSERT(boost::is_arithmetic::value); + + return detail::do_byte_swap()(value); +} + + } diff --git a/src/uscxml/plugins/datamodel/ecmascript/TypedArray.cpp b/src/uscxml/plugins/datamodel/ecmascript/TypedArray.cpp index 591a48a..fd1f936 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/TypedArray.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/TypedArray.cpp @@ -18,8 +18,8 @@ */ #include "TypedArray.h" +#include "uscxml/Convenience.h" #include -#include #define DATAVIEW_TYPED_GET(type) \ type retVal;\ diff --git a/src/uscxml/plugins/datamodel/ecmascript/TypedArray.h b/src/uscxml/plugins/datamodel/ecmascript/TypedArray.h index de32078..205ef5a 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/TypedArray.h +++ b/src/uscxml/plugins/datamodel/ecmascript/TypedArray.h @@ -31,7 +31,6 @@ #include #include -#include #include @@ -459,141 +458,6 @@ typedef TypedArray Uint32Array; typedef TypedArray Float32Array; typedef TypedArray Float64Array; - -// see http://www.cplusplus.com/forum/general/27544/ - -// Little-endian operating systems: -//--------------------------------- -// Linux on x86, x64, Alpha and Itanium -// Mac OS on x86, x64 -// Solaris on x86, x64, PowerPC -// Tru64 on Alpha -// Windows on x86, x64 and Itanium - -// Big-endian operating systems: -//------------------------------ -// AIX on POWER -// AmigaOS on PowerPC and 680x0 -// HP-UX on Itanium and PA-RISC -// Linux on MIPS, SPARC, PA-RISC, POWER, PowerPC, and 680x0 -// Mac OS on PowerPC and 680x0 -// Solaris on SPARC - -enum endianness { - little_endian, - big_endian, - network_endian = big_endian, - -#if defined(BOOST_LITTLE_ENDIAN) - host_endian = little_endian -#elif defined(BOOST_BIG_ENDIAN) - host_endian = big_endian -#else -#error "unable to determine system endianness" -#endif -}; - -namespace detail { - -template -struct swap_bytes { - inline T operator()(T val) { - throw std::out_of_range("data size"); - } -}; - -template -struct swap_bytes { - inline T operator()(T val) { - return val; - } -}; - -template -struct swap_bytes { // for 16 bit - inline T operator()(T val) { - return ((((val) >> 8) & 0xff) | (((val) & 0xff) << 8)); - } -}; - -template -struct swap_bytes { // for 32 bit - inline T operator()(T val) { -#if defined(_USE_BUILTIN_BSWAPS) && defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4) - return __builtin_bswap32(val); -#else - return ((((val) & 0xff000000) >> 24) | - (((val) & 0x00ff0000) >> 8) | - (((val) & 0x0000ff00) << 8) | - (((val) & 0x000000ff) << 24)); -#endif - } -}; - -template<> -struct swap_bytes { - inline float operator()(float val) { - uint32_t mem = swap_bytes()(*(uint32_t*)&val); - return *(float*)&mem; - } -}; - -template -struct swap_bytes { // for 64 bit - inline T operator()(T val) { -#if defined(_USE_BUILTIN_BSWAPS) && defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4) - return __builtin_bswap64(val); -#else - return ((((val) & 0xff00000000000000ull) >> 56) | - (((val) & 0x00ff000000000000ull) >> 40) | - (((val) & 0x0000ff0000000000ull) >> 24) | - (((val) & 0x000000ff00000000ull) >> 8 ) | - (((val) & 0x00000000ff000000ull) << 8 ) | - (((val) & 0x0000000000ff0000ull) << 24) | - (((val) & 0x000000000000ff00ull) << 40) | - (((val) & 0x00000000000000ffull) << 56)); -#endif - } -}; - -template<> -struct swap_bytes { - inline double operator()(double val) { - uint64_t mem = swap_bytes()(*(uint64_t*)&val); - return *(double*)&mem; - } -}; - -template -struct do_byte_swap { - inline T operator()(T value) { - return swap_bytes()(value); - } -}; -// specialisations when attempting to swap to the same endianess -template struct do_byte_swap { - inline T operator()(T value) { - return value; - } -}; -template struct do_byte_swap { - inline T operator()(T value) { - return value; - } -}; - -} // namespace detail - -template -inline T byte_swap(T value) { - // ensure the data is only 1, 2, 4 or 8 bytes - BOOST_STATIC_ASSERT(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8); - // ensure we're only swapping arithmetic types - BOOST_STATIC_ASSERT(boost::is_arithmetic::value); - - return detail::do_byte_swap()(value); -} - } #endif /* end of include guard: TYPEDARRAY_H_99815BLY */ -- cgit v0.12