2024-08-13 12:12:22 +00:00
|
|
|
#ifndef __JAVA_PARSER_BIG_ENDIAN_H
|
|
|
|
#define __JAVA_PARSER_BIG_ENDIAN_H
|
|
|
|
|
|
|
|
#include <Types.h>
|
|
|
|
#include <cstddef>
|
|
|
|
|
2024-08-25 03:34:33 +00:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
|
|
|
#include <intrin.h>
|
|
|
|
|
|
|
|
#define __builtin_bswap16 _byteswap_ushort
|
|
|
|
#define __builtin_bswap32 _byteswap_ulong
|
|
|
|
#define __builtin_bswap64 _byteswap_uint64
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2024-08-13 12:12:22 +00:00
|
|
|
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);
|
2024-08-25 03:34:33 +00:00
|
|
|
// 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)
|
2024-08-13 12:12:22 +00:00
|
|
|
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
|