CaVM/include/BigEndian.h
2024-08-24 23:34:33 -04:00

69 lines
1.3 KiB
C++

#ifndef __JAVA_PARSER_BIG_ENDIAN_H
#define __JAVA_PARSER_BIG_ENDIAN_H
#include <Types.h>
#include <cstddef>
#ifdef _MSC_VER
#include <intrin.h>
#define __builtin_bswap16 _byteswap_ushort
#define __builtin_bswap32 _byteswap_ulong
#define __builtin_bswap64 _byteswap_uint64
#endif
template <typename T>
class BigEndian
{
public:
ALWAYS_INLINE BigEndian(T val)
{
_val = val;
}
ALWAYS_INLINE BigEndian()
{
}
ALWAYS_INLINE T ToHostFormat()
{
return ToHostFormat(_val);
}
ALWAYS_INLINE T ToHostFormat(T val)
{
switch (sizeof(T))
{
case 1:
return val;
case 2:
return __builtin_bswap16(val);
case 4:
return __builtin_bswap32(val);
case 8:
return __builtin_bswap64(val);
// Only gcc has a 128-bit byte-order swap builtin, so we fall back to a generic byte-order swap implementation for clang and for msvc
#if not defined(__clang__) && not defined(_MSC_VER)
case 16:
return __builtin_bswap128(val);
#endif
default:
char *p = reinterpret_cast<char*>(val);
size_t lo, hi;
for(lo = 0, hi = sizeof(T) - 1; hi > lo; lo++, hi--)
{
char tmp = p[lo];
p[lo] = p[hi];
p[hi] = tmp;
}
return (T)(*p);
}
}
private:
T _val;
};
#endif