/* * --- GSMP-COPYRIGHT-NOTE-BEGIN --- * * This copyright note is auto-generated by ./scripts/Create-CopyPatch. * Please add additional copyright information _after_ the line containing * the GSMP-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by * the ./scripts/Create-CopyPatch script. Do not edit this copyright text! * * GSMP: pcm/include/Types.hh * General Sound Manipulation Program is Copyright (C) 2000 - 2010 * Valentin Ziegler and René Rebe * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2. A copy of the GNU General * Public License can be found in the file LICENSE. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANT- * ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * Alternatively, commercial licensing options are available from the * copyright holder ExactCODE GmbH Germany. * * --- GSMP-COPYRIGHT-NOTE-END --- */ /* Short Description: * Advanced templates to perform automated type convertion for * various kind of integer and floating point types. Convertions for * the same type are entirely optimized away - and integer convertions * are "normally" optimized down to a single shift instruction - of * course fully inlined. */ #ifndef LOWLEVEL__ENDIANESS_HH__ #define LOWLEVEL__ENDIANESS_HH__ #include #include #if defined(__FreeBSD__) #include #define bswap_16 bswap16 #define bswap_32 bswap32 #define bswap_64 bswap64 #elif defined(__APPLE__) #include #define bswap_16 OSSwapConstInt16 #define bswap_32 OSSwapConstInt32 #define bswap_64 OSSwapConstInt64 #elif defined (_MSC_VER) inline uint16_t bswap_16(uint16_t x) { return (x & 0xff00) >> 8 | (x & 0x00ff) << 8; } inline uint32_t bswap_32(uint32_t x) { return (x & 0xff000000) >> 24 | (x & 0x00ff0000) >> 8 | (x & 0x0000ff00) << 8 | (x & 0x000000ff) << 24; } #undef __BIG_ENDIAN__ #undef BYTE_ORDER #else #include #include #endif namespace Exact { class EndianTraits { public: static const bool IsSpecialized = false; static const bool HasEndianess = false; static const bool IsBigendian = false; }; class LittleEndianTraits : public EndianTraits { public: static const bool IsSpecialized = true; static const bool HasEndianess = true; static const bool IsBigendian = false; }; class BigEndianTraits : public EndianTraits { public: static const bool IsSpecialized = true; static const bool HasEndianess = true; static const bool IsBigendian = true; }; #if defined(__BIG_ENDIAN__) || (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) typedef BigEndianTraits NativeEndianTraits; #else typedef LittleEndianTraits NativeEndianTraits; #endif typedef BigEndianTraits NetworkEndianTraits; template class ByteSwap { }; template class ByteSwap { public: inline static const int8_t Swap (const int8_t& source) { return source; }; }; template class ByteSwap { public: inline static const int16_t Swap (const int16_t& source) { if (E_SRC::IsBigendian == E_DEST::IsBigendian) return source; else return bswap_16 (source); }; }; template class ByteSwap { public: inline static const uint16_t Swap (const uint16_t& source) { if (E_SRC::IsBigendian == E_DEST::IsBigendian) return source; else return bswap_16 (source); }; }; template class ByteSwap { public: inline static const int32_t Swap (const int32_t& source) { if (E_SRC::IsBigendian == E_DEST::IsBigendian) return source; else return bswap_32 (source); }; }; template class ByteSwap { public: inline static const uint32_t Swap (const uint32_t& source) { if (E_SRC::IsBigendian == E_DEST::IsBigendian) return source; else return bswap_32 (source); }; }; template class ByteSwap { public: inline static const int64_t Swap (const int64_t& source) { if (E_SRC::IsBigendian == E_DEST::IsBigendian) return source; else return bswap_64 (source); }; }; template class ByteSwap { public: inline static const uint64_t Swap (const uint64_t& source) { if (E_SRC::IsBigendian == E_DEST::IsBigendian) return source; else return bswap_64 (source); }; }; template class ByteSwap { public: inline static const float Swap (const float& source) { uint32_t* t = (uint32_t*)&source; if (E_SRC::IsBigendian != E_DEST::IsBigendian) *t = bswap_32(*t); return *(float*)t; }; }; template class ByteSwap { public: inline static const double Swap (const double& source) { uint64_t* t = (uint64_t*)&source; if (E_SRC::IsBigendian != E_DEST::IsBigendian) *t = bswap_64(*t); return *(double*)t; }; }; // --- // must be Plain Old Data (for 0-overhead and packing) template struct EndianessConverter { T value; // access wrappers inline void operator= (T v) { value = ByteSwap::Swap (v); } inline T operator* () const { return ByteSwap::Swap (value); } inline operator T () const { return ByteSwap::Swap (value); } }; } #endif // LOWLEVEL__ENDIANESS_HH__