/*************************************************************************** * Copyright (C) 2009 by gempa GmbH * * * * All Rights Reserved. * * * * NOTICE: All information contained herein is, and remains * * the property of gempa GmbH and its suppliers, if any. The intellectual * * and technical concepts contained herein are proprietary to gempa GmbH * * and its suppliers. * * Dissemination of this information or reproduction of this material * * is strictly forbidden unless prior written permission is obtained * * from gempa GmbH. * ***************************************************************************/ #ifndef GEMPA_CAPS_ENDIANESS_H #define GEMPA_CAPS_ENDIANESS_H #include #include #include namespace Gempa { namespace CAPS { namespace Endianess { template inline const T1* lvalue(const T2 &value) { return reinterpret_cast(&value); } template struct Swapper { static T Take(const T &v) { return v; } static void Take(T *ar, int len) {} }; template struct Swapper { static T Take(const T &v) { return *lvalue((*reinterpret_cast(&v) >> 0x08) | (*reinterpret_cast(&v) << 0x08)); } static void Take(T *ar, int len) { for ( int i = 0; i < len; ++i ) ar[i] = Take(ar[i]); } }; template struct Swapper { static T Take(const T &v) { return *lvalue(((*reinterpret_cast(&v) << 24) & 0xFF000000) | ((*reinterpret_cast(&v) << 8) & 0x00FF0000) | ((*reinterpret_cast(&v) >> 8) & 0x0000FF00) | ((*reinterpret_cast(&v) >> 24) & 0x000000FF)); } static void Take(T *ar, int len) { for ( int i = 0; i < len; ++i ) ar[i] = Take(ar[i]); } }; template struct Swapper { static T Take(const T &v) { return *lvalue(((*reinterpret_cast(&v) << 56) & 0xFF00000000000000LL) | ((*reinterpret_cast(&v) << 40) & 0x00FF000000000000LL) | ((*reinterpret_cast(&v) << 24) & 0x0000FF0000000000LL) | ((*reinterpret_cast(&v) << 8) & 0x000000FF00000000LL) | ((*reinterpret_cast(&v) >> 8) & 0x00000000FF000000LL) | ((*reinterpret_cast(&v) >> 24) & 0x0000000000FF0000LL) | ((*reinterpret_cast(&v) >> 40) & 0x000000000000FF00LL) | ((*reinterpret_cast(&v) >> 56) & 0x00000000000000FFLL)); } static void Take(T *ar, int len) { for ( int i = 0; i < len; ++i ) ar[i] = Take(ar[i]); } }; template struct TypeMap { typedef void ValueType; }; template <> struct TypeMap<1> { typedef uint8_t ValueType; }; template <> struct TypeMap<2> { typedef uint16_t ValueType; }; template <> struct TypeMap<4> { typedef uint32_t ValueType; }; template <> struct TypeMap<8> { typedef uint64_t ValueType; }; template struct ByteSwapper { static void Take(void *ar, int len) {} }; template struct ByteSwapper<1,size> { static void Take(void *ar, int len) { typedef typename TypeMap::ValueType T; Swapper::Take(reinterpret_cast(ar), len); } }; struct Current { enum { LittleEndian = ((0x1234 >> 8) == 0x12?1:0), BigEndian = 1-LittleEndian }; }; struct Converter { template static T ToLittleEndian(const T &v) { return Swapper::Take(v); } template static void ToLittleEndian(T *data, int len) { Swapper::Take(data, len); } template static T FromLittleEndian(const T &v) { return Swapper::Take(v); } template static T ToBigEndian(const T &v) { return Swapper::Take(v); } template static T FromBigEndian(const T &v) { return Swapper::Take(v); } }; struct Reader { Reader(std::streambuf &input) : stream(input), good(true) {} void operator()(void *data, int size) { good = stream.sgetn((char*)data, size) == size; } template void operator()(T &v) { good = stream.sgetn((char*)&v, sizeof(T)) == sizeof(T); v = Converter::FromLittleEndian(v); } std::streambuf &stream; bool good; }; struct Writer { Writer(std::streambuf &output) : stream(output), good(true) {} bool operator()(const void *data, int size) { return (good = stream.sputn((char*)data, size) == size); } template bool operator()(T &v) { T tmp = Converter::ToLittleEndian(v); return (good = stream.sputn((char*)&tmp, sizeof(T)) == sizeof(T)); } std::streambuf &stream; bool good; }; } } } #endif