diff options
Diffstat (limited to 'util/cbfstool/lzma/endian.hh')
-rw-r--r-- | util/cbfstool/lzma/endian.hh | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/util/cbfstool/lzma/endian.hh b/util/cbfstool/lzma/endian.hh new file mode 100644 index 0000000000..425374d423 --- /dev/null +++ b/util/cbfstool/lzma/endian.hh @@ -0,0 +1,178 @@ +#ifndef bqtEndianHH +#define bqtEndianHH + +#ifndef __STDC_CONSTANT_MACROS +#define __STDC_CONSTANT_MACROS /* for UINT16_C etc */ +#endif + +#include <stdint.h> + +#if defined(__x86_64)||defined(__i386) +#define LITTLE_ENDIAN_AND_UNALIGNED_ACCESS_OK +#else +#undef LITTLE_ENDIAN_AND_UNALIGNED_ACCESS_OK +#endif + +#ifdef WIN32 +# define LL_FMT "I64" +#else +# define LL_FMT "ll" +#endif + + +static inline uint_fast16_t get_8(const void* p) +{ + const unsigned char* data = (const unsigned char*)p; + return data[0]; +} +static inline uint_fast16_t get_16(const void* p) +{ + #ifdef LITTLE_ENDIAN_AND_UNALIGNED_ACCESS_OK + return *(const uint_least16_t*)p; + #else + const unsigned char* data = (const unsigned char*)p; + return get_8(data) | (get_8(data+1) << UINT16_C(8)); + #endif +} +static inline uint_fast16_t R16r(const void* p) +{ + #ifdef BIG_ENDIAN_AND_UNALIGNED_ACCESS_OK + return *(const uint_least16_t*)p; + #else + const unsigned char* data = (const unsigned char*)p; + return get_8(data+1) | (get_8(data) << UINT16_C(8)); + #endif +} +static inline uint_fast32_t R24(const void* p) +{ + /* Note: This might be faster if implemented through R32 and a bitwise and, + * but we cannot do that because we don't know if the third byte is a valid + * memory location. + */ + const unsigned char* data = (const unsigned char*)p; + return get_16(data) | (get_8(data+2) << UINT32_C(16)); +} +static inline uint_fast32_t R24r(const void* p) +{ + const unsigned char* data = (const unsigned char*)p; + return get_16(data+1) | (get_8(data) << UINT32_C(16)); +} +static inline uint_fast32_t get_32(const void* p) +{ + #ifdef LITTLE_ENDIAN_AND_UNALIGNED_ACCESS_OK + return *(const uint_least32_t*)p; + #else + const unsigned char* data = (const unsigned char*)p; + return get_16(data) | (get_16(data+2) << UINT32_C(16)); + #endif +} +static inline uint_fast32_t R32r(const void* p) +{ + #ifdef BIG_ENDIAN_AND_UNALIGNED_ACCESS_OK + return *(const uint_least32_t*)p; + #else + const unsigned char* data = (const unsigned char*)p; + return get_16(data+2) | (get_16(data) << UINT32_C(16)); + #endif +} + +#define L (uint_fast64_t) + +static inline uint_fast64_t get_64(const void* p) +{ + #ifdef LITTLE_ENDIAN_AND_UNALIGNED_ACCESS_OK + return *(const uint_least64_t*)p; + #else + const unsigned char* data = (const unsigned char*)p; + return (L get_32(data)) | ((L get_32(data+4)) << UINT64_C(32)); + #endif +} +static inline uint_fast64_t R64r(const void* p) +{ + #ifdef BIG_ENDIAN_AND_UNALIGNED_ACCESS_OK + return *(const uint_least64_t*)p; + #else + const unsigned char* data = (const unsigned char*)p; + return (L get_32(data+4)) | ((L get_32(data)) << UINT64_C(32)); + #endif +} + +#undef L + +static inline uint_fast64_t get_n(const void* p, unsigned bytes) +{ + const unsigned char* data = (const unsigned char*)p; + uint_fast64_t res(0); + switch(bytes) + { + case 8: return get_64(p); + case 4: return get_32(p); + case 2: return get_16(p); + case 7: res |= ((uint_fast64_t)get_8(data+6)) << 48; + case 6: res |= ((uint_fast64_t)get_8(data+5)) << 40; + case 5: res |= ((uint_fast64_t)get_16(data+3)) << 24; + case 3: res |= ((uint_fast64_t)get_16(data+1)) << 8; + case 1: res |= get_8(data); + } + return res; +} + +static void put_8(void* p, uint_fast8_t value) +{ + unsigned char* data = (unsigned char*)p; + data[0] = value; +} +static void put_16(void* p, uint_fast16_t value) +{ + #ifdef LITTLE_ENDIAN_AND_UNALIGNED_ACCESS_OK + *(uint_least16_t*)p = value; + #else + unsigned char* data = (unsigned char*)p; + put_8(data+0, value ); + put_8(data+1, value>>8); + #endif +} +static void W24(void* p, uint_fast32_t value) +{ + unsigned char* data = (unsigned char*)p; + put_16(data+0, value); + put_8(data+2, value >> UINT32_C(16)); +} +static void put_32(void* p, uint_fast32_t value) +{ + #ifdef LITTLE_ENDIAN_AND_UNALIGNED_ACCESS_OK + *(uint_least32_t*)p = value; + #else + unsigned char* data = (unsigned char*)p; + put_16(data+0, value); + put_16(data+2, value >> UINT32_C(16)); + #endif +} +static void put_64(void* p, uint_fast64_t value) +{ + #ifdef LITTLE_ENDIAN_AND_UNALIGNED_ACCESS_OK + *(uint_least64_t*)p = value; + #else + unsigned char* data = (unsigned char*)p; + put_32(data+0, (value)); + put_32(data+4, (value >> UINT64_C(32))); + #endif +} + +static inline void put_n(void* p, uint_fast64_t value, unsigned bytes) +{ + unsigned char* data = (unsigned char*)p; + switch(bytes) + { + case 8: put_64(p, value); break; + case 7: put_8(data+6, value>>48); + case 6: put_8(data+5, value>>40); + case 5: put_8(data+4, value>>32); + case 4: put_32(p, value); break; + case 3: W24(p, value); break; + case 2: put_16(p, value); break; + case 1: put_8(p, value); break; + } +} + +#endif |