123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- #pragma once
- #include <util/system/defaults.h> // _BIDSCLASS _EXPCLASS
- #include <util/system/yassert.h>
- #include <util/system/unaligned_mem.h>
- #define PUT_8(x, buf, shift) WriteUnaligned<ui8>((buf)++, (x) >> (shift))
- #define GET_8_OR(x, buf, type, shift) (x) |= (type) * (buf)++ << (shift)
- #if defined(_big_endian_)
- #define LO_SHIFT 1
- #define HI_SHIFT 0
- #elif defined(_little_endian_)
- #define LO_SHIFT 0
- #define HI_SHIFT 1
- #endif
- #if !defined(_must_align2_)
- #define PUT_16(x, buf, shift) WriteUnaligned<ui16>(buf, (x) >> (shift)), (buf) += 2
- #define GET_16_OR(x, buf, type, shift) (x) |= (type)ReadUnaligned<ui16>(buf) << (shift), (buf) += 2
- #else
- #define PUT_16(x, buf, shift) PUT_8(x, buf, shift + 8 * LO_SHIFT), PUT_8(x, buf, shift + 8 * HI_SHIFT)
- #define GET_16_OR(x, buf, type, shift) GET_8_OR(x, buf, type, shift + 8 * LO_SHIFT), GET_8_OR(x, buf, type, shift + 8 * HI_SHIFT)
- #endif
- #if !defined(_must_align4_)
- #define PUT_32(x, buf, shift) WriteUnaligned<ui32>(buf, (x) >> (shift)), (buf) += 4
- #define GET_32_OR(x, buf, type, shift) (x) |= (type)ReadUnaligned<ui32>(buf) << (shift), (buf) += 4
- #else
- #define PUT_32(x, buf, shift) PUT_16(x, buf, shift + 16 * LO_SHIFT), PUT_16(x, buf, shift + 16 * HI_SHIFT)
- #define GET_32_OR(x, buf, type, shift) GET_16_OR(x, buf, type, shift + 16 * LO_SHIFT), GET_16_OR(x, buf, type, shift + 16 * HI_SHIFT)
- #endif
- #if !defined(_must_align8_)
- #define PUT_64(x, buf, shift) WriteUnaligned<ui64>(buf, (x) >> (shift)), (buf) += 8
- #define GET_64_OR(x, buf, type, shift) (x) |= (type)ReadUnaligned<ui64>(buf) << (shift), (buf) += 8
- #else
- #define PUT_64(x, buf, shift) PUT_32(x, buf, shift + 32 * LO_SHIFT), PUT_32(x, buf, shift + 32 * HI_SHIFT)
- #define GET_64_OR(x, buf, type, shift) GET_32_OR(x, buf, type, shift + 32 * LO_SHIFT), GET_32_OR(x, buf, type, shift + 32 * HI_SHIFT)
- #endif
- struct mem_traits {
- static ui8 get_8(const char*& mem) {
- ui8 x = 0;
- GET_8_OR(x, mem, ui8, 0);
- return x;
- }
- static ui16 get_16(const char*& mem) {
- ui16 x = 0;
- GET_16_OR(x, mem, ui16, 0);
- return x;
- }
- static ui32 get_32(const char*& mem) {
- ui32 x = 0;
- GET_32_OR(x, mem, ui32, 0);
- return x;
- }
- static void put_8(ui8 x, char*& mem) {
- PUT_8(x, mem, 0);
- }
- static void put_16(ui16 x, char*& mem) {
- PUT_16(x, mem, 0);
- }
- static void put_32(ui32 x, char*& mem) {
- PUT_32(x, mem, 0);
- }
- static int is_good(char*&) {
- return 1;
- }
- };
- /*
- |____|____|____|____|____|____|____|____|____|____|____|____|____|____|8***|****
- |____|____|____|____|____|____|____|____|____|____|____|____|i4**|****|****|****
- |____|____|____|____|____|____|____|____|____|____|ii2*|****|****|****|****|****
- |____|____|____|____|____|____|____|____|iii1|****|****|****|****|****|****|****
- |____|____|____|____|____|____|iiii|8***|****|****|****|****|****|****|****|****
- |____|____|____|____|iiii|i4**|****|****|****|****|****|****|****|****|****|****
- |____|____|iiii|ii2*|****|****|****|****|****|****|****|****|****|****|****|****
- |iiii|iii1|****|****|****|****|****|****|****|****|****|****|****|****|****|****
- */
- #define PACK1LIM 0x80u
- #define PACK2LIM 0x4000u
- #define PACK3LIM 0x200000u
- #define PACK4LIM 0x10000000u
- #define PACK5LIM 0x800000000ull
- #define PACK6LIM 0x40000000000ull
- #define PACK7LIM 0x2000000000000ull
- #define PACK8LIM 0x100000000000000ull
- #define MY_14(x) ((ui16)(x) < PACK1LIM ? 1 : 2)
- #define MY_28(x) ((ui32)(x) < PACK2LIM ? MY_14(x) : ((ui32)(x) < PACK3LIM ? 3 : 4))
- #define MY_32(x) ((ui32)(x) < PACK4LIM ? MY_28(x) : 5)
- #define MY_64(x) ((ui64)(x) < PACK4LIM ? MY_28(x) : ((ui64)(x) < PACK6LIM ? ((ui64)(x) < PACK5LIM ? 5 : 6) : ((ui64)(x) < PACK7LIM ? 7 : ((ui64)(x) < PACK8LIM ? 8 : 9))))
- #if !defined(MACRO_BEGIN)
- #define MACRO_BEGIN do {
- #define MACRO_END \
- } \
- while (0)
- #endif
- #define PACK_14(x, buf, how, ret) \
- MACRO_BEGIN \
- if ((ui16)(x) < PACK1LIM) { \
- how::put_8((ui8)(x), (buf)); \
- (ret) = 1; \
- } else { \
- how::put_8((ui8)(0x80 | (x) >> 8), (buf)); \
- how::put_8((ui8)(x), (buf)); \
- (ret) = 2; \
- } \
- MACRO_END
- #define PACK_28(x, buf, how, ret) \
- MACRO_BEGIN \
- if ((ui32)(x) < PACK2LIM) { \
- PACK_14(x, buf, how, ret); \
- } else { \
- if ((ui32)(x) < PACK3LIM) { \
- how::put_8((ui8)(0xC0 | (x) >> 16), buf); \
- (ret) = 3; \
- } else { \
- how::put_8((ui8)(0xE0 | (x) >> 24), buf); \
- how::put_8((ui8)((x) >> 16), buf); \
- (ret) = 4; \
- } \
- how::put_16((ui16)(x), (buf)); \
- } \
- MACRO_END
- #define PACK_32(x, buf, how, ret) \
- MACRO_BEGIN \
- if ((ui32)(x) < PACK4LIM) { \
- PACK_28(x, buf, how, ret); \
- } else { \
- how::put_8((ui8)(0xF0), buf); \
- how::put_32((ui32)(x), buf); \
- (ret) = 5; \
- } \
- MACRO_END
- #define PACK_64(x, buf, how, ret) \
- MACRO_BEGIN \
- if ((ui64)(x) < PACK4LIM) { \
- PACK_28((ui32)(x), buf, how, ret); \
- } else { \
- if ((ui64)(x) < PACK6LIM) { \
- if ((ui64)(x) < PACK5LIM) { \
- how::put_8((ui8)(0xF0 | (x) >> 32), buf); \
- (ret) = 5; \
- } else { \
- how::put_8((ui8)(0xF8 | (x) >> 40), buf); \
- how::put_8((ui8)((x) >> 32), buf); \
- (ret) = 6; \
- } \
- } else { \
- if ((ui64)(x) < PACK7LIM) { \
- how::put_8((ui8)(0xFC | (x) >> 48), buf); \
- (ret) = 7; \
- } else { \
- if ((ui64)(x) < PACK8LIM) { \
- how::put_8((ui8)(0xFE | (x) >> 56), buf); \
- how::put_8((ui8)((x) >> 48), buf); \
- (ret) = 8; \
- } else { \
- how::put_8((ui8)(0xFF), buf); \
- how::put_16((ui16)((x) >> 48), buf); \
- (ret) = 9; \
- } \
- } \
- how::put_16((ui16)((x) >> 32), buf); \
- } \
- how::put_32((ui32)(x), buf); \
- } \
- MACRO_END
- #define DO_UNPACK_14(firstByte, x, buf, how, ret) \
- MACRO_BEGIN \
- if (firstByte < 0x80) { \
- (x) = (firstByte); \
- (ret) = 1; \
- } else { \
- (x) = (firstByte & 0x7F) << 8; \
- (x) |= how::get_8(buf); \
- (ret) = 2; \
- } \
- MACRO_END
- #define UNPACK_14(x, buf, how, ret) \
- MACRO_BEGIN \
- ui8 firstByte = how::get_8(buf); \
- DO_UNPACK_14(firstByte, x, buf, how, ret); \
- MACRO_END
- #define DO_UNPACK_28(firstByte, x, buf, how, ret) \
- MACRO_BEGIN \
- if (firstByte < 0xC0) { \
- DO_UNPACK_14(firstByte, x, buf, how, ret); \
- } else { \
- if (firstByte < 0xE0) { \
- (x) = (firstByte & 0x3F) << 16; \
- (ret) = 3; \
- } else { \
- (x) = (firstByte & 0x1F) << 24; \
- (x) |= how::get_8(buf) << 16; \
- (ret) = 4; \
- } \
- (x) |= how::get_16(buf); \
- } \
- MACRO_END
- #define UNPACK_28(x, buf, how, ret) \
- MACRO_BEGIN \
- ui8 firstByte = how::get_8(buf); \
- DO_UNPACK_28(firstByte, x, buf, how, ret); \
- MACRO_END
- #define DO_UNPACK_32(firstByte, x, buf, how, ret) \
- MACRO_BEGIN \
- if (firstByte < 0xF0) { \
- DO_UNPACK_28(firstByte, x, buf, how, ret); \
- } else { \
- (x) = how::get_32(buf); \
- (ret) = 5; \
- } \
- MACRO_END
- #define UNPACK_32(x, buf, how, ret) \
- MACRO_BEGIN \
- ui8 firstByte = how::get_8(buf); \
- DO_UNPACK_32(firstByte, x, buf, how, ret); \
- MACRO_END
- #define DO_UNPACK_64(firstByte, x, buf, how, ret) \
- MACRO_BEGIN \
- if (firstByte < 0xF0) { \
- DO_UNPACK_28(firstByte, x, buf, how, ret); \
- } else { \
- if (firstByte < 0xFC) { \
- if (firstByte < 0xF8) { \
- (x) = (ui64)(firstByte & 0x0F) << 32; \
- (ret) = 5; \
- } else { \
- (x) = (ui64)(firstByte & 0x07) << 40; \
- (x) |= (ui64)how::get_8(buf) << 32; \
- (ret) = 6; \
- } \
- } else { \
- if (firstByte < 0xFE) { \
- (x) = (ui64)(firstByte & 0x03) << 48; \
- (ret) = 7; \
- } else { \
- if (firstByte < 0xFF) { \
- (x) = (ui64)(firstByte & 0x01) << 56; \
- (x) |= (ui64)how::get_8(buf) << 48; \
- (ret) = 8; \
- } else { \
- (x) = (ui64)how::get_16(buf) << 48; \
- (ret) = 9; \
- } \
- } \
- (x) |= (ui64)how::get_16(buf) << 32; \
- } \
- (x) |= how::get_32(buf); \
- } \
- MACRO_END
- #define UNPACK_64(x, buf, how, ret) \
- MACRO_BEGIN \
- ui8 firstByte = how::get_8(buf); \
- DO_UNPACK_64(firstByte, x, buf, how, ret); \
- MACRO_END
- inline int in_long(i64& longVal, const char* ptrBuf) {
- int ret = 0;
- UNPACK_64(longVal, ptrBuf, mem_traits, ret);
- return ret;
- }
- inline int out_long(const i64& longVal, char* ptrBuf) {
- int ret = 0;
- PACK_64(longVal, ptrBuf, mem_traits, ret); /*7*/
- return ret;
- }
- inline int len_long(const i64& longVal) {
- return MY_64(longVal);
- }
- inline int in_long(i32& longVal, const char* ptrBuf) {
- int ret = 0;
- UNPACK_32(longVal, ptrBuf, mem_traits, ret);
- return ret;
- }
- inline int out_long(const i32& longVal, char* ptrBuf) {
- int ret = 0;
- PACK_32(longVal, ptrBuf, mem_traits, ret);
- return ret;
- }
- inline int len_long(const i32& longVal) {
- return MY_32(longVal);
- }
- template <typename T, typename C>
- inline const C* Unpack32(T& x, const C* src) {
- int pkLen = 0;
- const char* c = reinterpret_cast<const char*>(src);
- Y_UNUSED(pkLen);
- UNPACK_32(x, c, mem_traits, pkLen);
- Y_ASSERT(pkLen);
- return reinterpret_cast<const C*>(c);
- }
- template <typename T, typename C>
- inline const C* Unpack64(T& x, const C* src) {
- int pkLen = 0;
- const char* c = reinterpret_cast<const char*>(src);
- Y_UNUSED(pkLen);
- UNPACK_64(x, c, mem_traits, pkLen);
- Y_ASSERT(pkLen);
- return reinterpret_cast<const C*>(c);
- }
- template <typename T, typename C>
- inline C* Pack32(const T& x, C* dest) {
- int pkLen = 0;
- Y_UNUSED(pkLen);
- char* c = reinterpret_cast<char*>(dest);
- PACK_32(x, c, mem_traits, pkLen);
- Y_ASSERT(pkLen);
- return reinterpret_cast<C*>(c);
- }
- template <typename T, typename C>
- inline C* Pack64(const T& x, C* dest) {
- int pkLen = 0;
- Y_UNUSED(pkLen);
- char* c = reinterpret_cast<char*>(dest);
- PACK_64(x, c, mem_traits, pkLen);
- Y_ASSERT(pkLen);
- return reinterpret_cast<C*>(c);
- }
|