compressor.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #pragma once
  2. #include <util/system/defaults.h>
  3. namespace NCompProto {
  4. struct TEmpty {
  5. };
  6. struct TTable {
  7. TTable() {
  8. for (size_t i = 0; i < 64; ++i) {
  9. CodeBase[i] = 0;
  10. CodeMask[i] = 0;
  11. Length[i] = 0;
  12. PrefLength[i] = 0;
  13. Id[i] = 0;
  14. }
  15. }
  16. ui32 CodeBase[64];
  17. ui32 CodeMask[64];
  18. ui8 Length[64];
  19. ui8 PrefLength[64];
  20. ui8 Id[64];
  21. enum {
  22. PAGE_BOUND = 4096,
  23. #ifdef WITH_VALGRIND
  24. SAFE_MODE = 1,
  25. #else
  26. #if defined(__has_feature)
  27. #if __has_feature(address_sanitizer)
  28. SAFE_MODE = 1,
  29. #else
  30. SAFE_MODE = 0,
  31. #endif
  32. #else
  33. SAFE_MODE = 0,
  34. #endif
  35. #endif
  36. };
  37. ui32 inline Decompress(const ui8* codes, ui64& offset) const {
  38. codes += (offset >> 3);
  39. size_t pageOff = size_t(codes) % PAGE_BOUND;
  40. size_t readOff = offset & 7;
  41. if (pageOff > PAGE_BOUND - 8 || SAFE_MODE) {
  42. size_t off = 8;
  43. ui64 res = codes[0];
  44. ++codes;
  45. ui64 indexCur = ((res + 0x0000) >> readOff) & 63;
  46. ui64 indexAlt = ((res + 0xff00) >> readOff) & 63;
  47. if (Id[indexCur] != Id[indexAlt]) {
  48. res += (ui64(codes[0]) << off);
  49. ++codes;
  50. off += 8;
  51. indexCur = (res >> readOff) & 63;
  52. }
  53. ui64 index = indexCur;
  54. ui64 length = Length[index];
  55. while (off < readOff + length) {
  56. res += (ui64(codes[0]) << off);
  57. ++codes;
  58. off += 8;
  59. }
  60. offset += length;
  61. ui64 code = res >> readOff;
  62. return (((ui32)(code >> PrefLength[index])) & CodeMask[index]) + CodeBase[index];
  63. }
  64. ui64 code = ((const ui64*)(codes))[0] >> readOff;
  65. ui64 index = code & 63;
  66. offset += Length[index];
  67. return (((ui32)(code >> PrefLength[index])) & CodeMask[index]) + CodeBase[index];
  68. }
  69. };
  70. }