#pragma once #include namespace NCompProto { struct TEmpty { }; struct TTable { TTable() { for (size_t i = 0; i < 64; ++i) { CodeBase[i] = 0; CodeMask[i] = 0; Length[i] = 0; PrefLength[i] = 0; Id[i] = 0; } } ui32 CodeBase[64]; ui32 CodeMask[64]; ui8 Length[64]; ui8 PrefLength[64]; ui8 Id[64]; enum { PAGE_BOUND = 4096, #ifdef WITH_VALGRIND SAFE_MODE = 1, #else #if defined(__has_feature) #if __has_feature(address_sanitizer) SAFE_MODE = 1, #else SAFE_MODE = 0, #endif #else SAFE_MODE = 0, #endif #endif }; ui32 inline Decompress(const ui8* codes, ui64& offset) const { codes += (offset >> 3); size_t pageOff = size_t(codes) % PAGE_BOUND; size_t readOff = offset & 7; if (pageOff > PAGE_BOUND - 8 || SAFE_MODE) { size_t off = 8; ui64 res = codes[0]; ++codes; ui64 indexCur = ((res + 0x0000) >> readOff) & 63; ui64 indexAlt = ((res + 0xff00) >> readOff) & 63; if (Id[indexCur] != Id[indexAlt]) { res += (ui64(codes[0]) << off); ++codes; off += 8; indexCur = (res >> readOff) & 63; } ui64 index = indexCur; ui64 length = Length[index]; while (off < readOff + length) { res += (ui64(codes[0]) << off); ++codes; off += 8; } offset += length; ui64 code = res >> readOff; return (((ui32)(code >> PrefLength[index])) & CodeMask[index]) + CodeBase[index]; } ui64 code = ((const ui64*)(codes))[0] >> readOff; ui64 index = code & 63; offset += Length[index]; return (((ui32)(code >> PrefLength[index])) & CodeMask[index]) + CodeBase[index]; } }; }