C++ 字節順序

//
// ByteOrder.h
//
// Library: Engine
// Package: Core
// Module:  ByteOrder
//
//


#ifndef WISHBONE_BYTEORDER_H_
#define WISHBONE_BYTEORDER_H_


#include "Wishbone/Foundation.h"
#include "Wishbone/Types.h"
#if defined(_MSC_VER)
#include <stdlib.h> // builtins
#endif


namespace Wishbone
{

    /// This class contains a number of static methods to convert between big-endian and little-endian integers of various sizes.
    class FOUNDATION_API ByteOrder
    {
    public:
        static Int16 SwapInt16(Int16 value);
        static Wishbone::UInt16 SwapUInt16(Wishbone::UInt16 value);
        static Int32 SwapInt32(Int32 value);
        static Wishbone::UInt32 SwapUInt32(Wishbone::UInt32 value);
#if defined(WISHBONE_HAVE_INT64)
        static Int64 SwapInt64(Int64 value);
        static Wishbone::UInt64 SwapUInt64(Wishbone::UInt64 value);
#endif
    };


#if !defined(WISHBONE_NO_BYTESWAP_BUILTINS)
    #if defined(_MSC_VER)
        #if (WISHBONE_MSVC_VERSION > 71)
            #define WISHBONE_HAVE_MSC_BYTESWAP 1
        #endif
    #elif defined(__clang__) 
        #if __has_builtin(__builtin_bswap32)
            #define WISHBONE_HAVE_GCC_BYTESWAP 1
        #endif
    #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
        #define WISHBONE_HAVE_GCC_BYTESWAP 1
    #endif
#endif


    //
    // inlines
    //
    inline Wishbone::UInt16 ByteOrder::SwapUInt16(Wishbone::UInt16 value)
    {
#if defined(WISHBONE_HAVE_MSC_BYTESWAP)
        return _byteswap_ushort(value);
#elif defined(__i386__) && defined(__GNUC__) 
        __asm__("xchgb %b0, %h0" : "+q" (value));
        return value;
#elif defined(__ppc__) && defined(__GNUC__) 
        Wishbone::UInt16 result;
        __asm__("lhbrx %0,0,%1" : "=r" (result) : "r" (&value), "m" (value));
        return result;
#else 
        // swap bytes 
        Wishbone::UInt16 result;
        result = ((value << 8) & 0xFF00) | ((value >> 8) & 0x00FF);
        return result;
#endif 
    }


    inline Int16 ByteOrder::SwapInt16(Int16 value)
    {
        return Int16(SwapUInt16(Wishbone::UInt16(value)));
    }


    inline Wishbone::UInt32 ByteOrder::SwapUInt32(Wishbone::UInt32 value)
    {
#if defined(WISHBONE_HAVE_MSC_BYTESWAP)
        return _byteswap_ulong(value);
#elif defined(WISHBONE_HAVE_GCC_BYTESWAP)
        return __builtin_bswap32(value);
#elif defined(__i386__) && defined(__GNUC__) 
        __asm__("bswap %0" : "+r" (value));
        return value;
#elif defined(__ppc__) && defined(__GNUC__) 
        Wishbone::UInt32 result;
        __asm__("lwbrx %0,0,%1" : "=r" (result) : "r" (&value), "m" (value));
        return result;
#else 
        // swap words then bytes
        Wishbone::UInt32 result;
        result = ((value & 0x000000FF) << 24) | ((value & 0x0000FF00) << 8) | ((value >> 8) & 0x0000FF00) | ((value >> 24) & 0x000000FF);
        return result;
#endif 
    }


    inline Int32 ByteOrder::SwapInt32(Int32 value)
    {
        return Int32(SwapUInt32(Wishbone::UInt32(value)));
    }


#if defined(WISHBONE_HAVE_INT64)

    inline Wishbone::UInt64 ByteOrder::SwapUInt64(Wishbone::UInt64 value)
    {
#if defined(WISHBONE_HAVE_MSC_BYTESWAP)
        return _byteswap_uint64(value);
#elif defined(WISHBONE_HAVE_GCC_BYTESWAP)
        return __builtin_bswap64(value);
#else
        union Swap {
            Wishbone::UInt64 sv;
            Wishbone::UInt32 ul[2];
        } tmp, result;
        tmp.sv = value;
        result.ul[0] = SwapInt32(tmp.ul[1]);
        result.ul[1] = SwapInt32(tmp.ul[0]);
        return result.sv;
#endif
    }


    inline Int64 ByteOrder::SwapInt64(Int64 value)
    {
        return Int64(SwapUInt64(Wishbone::UInt64(value)));
    }
#endif // WISHBONE_HAVE_INT64


} // namespace Wishbone


#endif // WISHBONE_BYTEORDER_H_
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章