zstdlib 0.13.0-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +6 -0
  3. data/CHANGES.md +107 -0
  4. data/Gemfile +3 -0
  5. data/README.md +107 -0
  6. data/Rakefile +59 -0
  7. data/ext/zstdlib_c/extconf.rb +59 -0
  8. data/ext/zstdlib_c/ruby/zlib-2.2/zstdlib.c +4675 -0
  9. data/ext/zstdlib_c/ruby/zlib-2.3/zstdlib.c +4702 -0
  10. data/ext/zstdlib_c/ruby/zlib-2.4/zstdlib.c +4859 -0
  11. data/ext/zstdlib_c/ruby/zlib-2.5/zstdlib.c +4864 -0
  12. data/ext/zstdlib_c/ruby/zlib-2.6/zstdlib.c +4906 -0
  13. data/ext/zstdlib_c/ruby/zlib-2.7/zstdlib.c +4895 -0
  14. data/ext/zstdlib_c/ruby/zlib-3.0/zstdlib.c +4994 -0
  15. data/ext/zstdlib_c/ruby/zlib-3.1/zstdlib.c +5076 -0
  16. data/ext/zstdlib_c/ruby/zlib-3.2/zstdlib.c +5090 -0
  17. data/ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c +5090 -0
  18. data/ext/zstdlib_c/zlib-1.3.1/adler32.c +164 -0
  19. data/ext/zstdlib_c/zlib-1.3.1/compress.c +75 -0
  20. data/ext/zstdlib_c/zlib-1.3.1/crc32.c +1049 -0
  21. data/ext/zstdlib_c/zlib-1.3.1/crc32.h +9446 -0
  22. data/ext/zstdlib_c/zlib-1.3.1/deflate.c +2139 -0
  23. data/ext/zstdlib_c/zlib-1.3.1/deflate.h +377 -0
  24. data/ext/zstdlib_c/zlib-1.3.1/gzclose.c +23 -0
  25. data/ext/zstdlib_c/zlib-1.3.1/gzguts.h +214 -0
  26. data/ext/zstdlib_c/zlib-1.3.1/gzlib.c +582 -0
  27. data/ext/zstdlib_c/zlib-1.3.1/gzread.c +602 -0
  28. data/ext/zstdlib_c/zlib-1.3.1/gzwrite.c +631 -0
  29. data/ext/zstdlib_c/zlib-1.3.1/infback.c +628 -0
  30. data/ext/zstdlib_c/zlib-1.3.1/inffast.c +320 -0
  31. data/ext/zstdlib_c/zlib-1.3.1/inffast.h +11 -0
  32. data/ext/zstdlib_c/zlib-1.3.1/inffixed.h +94 -0
  33. data/ext/zstdlib_c/zlib-1.3.1/inflate.c +1526 -0
  34. data/ext/zstdlib_c/zlib-1.3.1/inflate.h +126 -0
  35. data/ext/zstdlib_c/zlib-1.3.1/inftrees.c +299 -0
  36. data/ext/zstdlib_c/zlib-1.3.1/inftrees.h +62 -0
  37. data/ext/zstdlib_c/zlib-1.3.1/trees.c +1117 -0
  38. data/ext/zstdlib_c/zlib-1.3.1/trees.h +128 -0
  39. data/ext/zstdlib_c/zlib-1.3.1/uncompr.c +85 -0
  40. data/ext/zstdlib_c/zlib-1.3.1/zconf.h +543 -0
  41. data/ext/zstdlib_c/zlib-1.3.1/zlib.h +1938 -0
  42. data/ext/zstdlib_c/zlib-1.3.1/zutil.c +299 -0
  43. data/ext/zstdlib_c/zlib-1.3.1/zutil.h +254 -0
  44. data/ext/zstdlib_c/zlib.mk +14 -0
  45. data/ext/zstdlib_c/zlibwrapper/zlibwrapper.c +10 -0
  46. data/ext/zstdlib_c/zlibwrapper.mk +14 -0
  47. data/ext/zstdlib_c/zstd-1.5.6/lib/common/allocations.h +55 -0
  48. data/ext/zstdlib_c/zstd-1.5.6/lib/common/bits.h +200 -0
  49. data/ext/zstdlib_c/zstd-1.5.6/lib/common/bitstream.h +457 -0
  50. data/ext/zstdlib_c/zstd-1.5.6/lib/common/compiler.h +450 -0
  51. data/ext/zstdlib_c/zstd-1.5.6/lib/common/cpu.h +249 -0
  52. data/ext/zstdlib_c/zstd-1.5.6/lib/common/debug.c +30 -0
  53. data/ext/zstdlib_c/zstd-1.5.6/lib/common/debug.h +116 -0
  54. data/ext/zstdlib_c/zstd-1.5.6/lib/common/entropy_common.c +340 -0
  55. data/ext/zstdlib_c/zstd-1.5.6/lib/common/error_private.c +63 -0
  56. data/ext/zstdlib_c/zstd-1.5.6/lib/common/error_private.h +168 -0
  57. data/ext/zstdlib_c/zstd-1.5.6/lib/common/fse.h +640 -0
  58. data/ext/zstdlib_c/zstd-1.5.6/lib/common/fse_decompress.c +313 -0
  59. data/ext/zstdlib_c/zstd-1.5.6/lib/common/huf.h +286 -0
  60. data/ext/zstdlib_c/zstd-1.5.6/lib/common/mem.h +426 -0
  61. data/ext/zstdlib_c/zstd-1.5.6/lib/common/pool.c +371 -0
  62. data/ext/zstdlib_c/zstd-1.5.6/lib/common/pool.h +90 -0
  63. data/ext/zstdlib_c/zstd-1.5.6/lib/common/portability_macros.h +158 -0
  64. data/ext/zstdlib_c/zstd-1.5.6/lib/common/threading.c +182 -0
  65. data/ext/zstdlib_c/zstd-1.5.6/lib/common/threading.h +150 -0
  66. data/ext/zstdlib_c/zstd-1.5.6/lib/common/xxhash.c +18 -0
  67. data/ext/zstdlib_c/zstd-1.5.6/lib/common/xxhash.h +7020 -0
  68. data/ext/zstdlib_c/zstd-1.5.6/lib/common/zstd_common.c +48 -0
  69. data/ext/zstdlib_c/zstd-1.5.6/lib/common/zstd_deps.h +111 -0
  70. data/ext/zstdlib_c/zstd-1.5.6/lib/common/zstd_internal.h +392 -0
  71. data/ext/zstdlib_c/zstd-1.5.6/lib/common/zstd_trace.h +163 -0
  72. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/clevels.h +134 -0
  73. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/fse_compress.c +625 -0
  74. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/hist.c +181 -0
  75. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/hist.h +75 -0
  76. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/huf_compress.c +1464 -0
  77. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_compress.c +7153 -0
  78. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_compress_internal.h +1534 -0
  79. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_compress_literals.c +235 -0
  80. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_compress_literals.h +39 -0
  81. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_compress_sequences.c +442 -0
  82. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_compress_sequences.h +54 -0
  83. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_compress_superblock.c +688 -0
  84. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_compress_superblock.h +32 -0
  85. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_cwksp.h +748 -0
  86. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_double_fast.c +770 -0
  87. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_double_fast.h +50 -0
  88. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_fast.c +968 -0
  89. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_fast.h +38 -0
  90. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_lazy.c +2199 -0
  91. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_lazy.h +202 -0
  92. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_ldm.c +730 -0
  93. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_ldm.h +117 -0
  94. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_ldm_geartab.h +106 -0
  95. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_opt.c +1576 -0
  96. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstd_opt.h +80 -0
  97. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstdmt_compress.c +1882 -0
  98. data/ext/zstdlib_c/zstd-1.5.6/lib/compress/zstdmt_compress.h +113 -0
  99. data/ext/zstdlib_c/zstd-1.5.6/lib/decompress/huf_decompress.c +1944 -0
  100. data/ext/zstdlib_c/zstd-1.5.6/lib/decompress/huf_decompress_amd64.S +595 -0
  101. data/ext/zstdlib_c/zstd-1.5.6/lib/decompress/zstd_ddict.c +244 -0
  102. data/ext/zstdlib_c/zstd-1.5.6/lib/decompress/zstd_ddict.h +44 -0
  103. data/ext/zstdlib_c/zstd-1.5.6/lib/decompress/zstd_decompress.c +2407 -0
  104. data/ext/zstdlib_c/zstd-1.5.6/lib/decompress/zstd_decompress_block.c +2215 -0
  105. data/ext/zstdlib_c/zstd-1.5.6/lib/decompress/zstd_decompress_block.h +73 -0
  106. data/ext/zstdlib_c/zstd-1.5.6/lib/decompress/zstd_decompress_internal.h +240 -0
  107. data/ext/zstdlib_c/zstd-1.5.6/lib/zdict.h +474 -0
  108. data/ext/zstdlib_c/zstd-1.5.6/lib/zstd.h +3089 -0
  109. data/ext/zstdlib_c/zstd-1.5.6/lib/zstd_errors.h +114 -0
  110. data/ext/zstdlib_c/zstd-1.5.6/zlibWrapper/gzclose.c +26 -0
  111. data/ext/zstdlib_c/zstd-1.5.6/zlibWrapper/gzcompatibility.h +68 -0
  112. data/ext/zstdlib_c/zstd-1.5.6/zlibWrapper/gzguts.h +229 -0
  113. data/ext/zstdlib_c/zstd-1.5.6/zlibWrapper/gzlib.c +587 -0
  114. data/ext/zstdlib_c/zstd-1.5.6/zlibWrapper/gzread.c +637 -0
  115. data/ext/zstdlib_c/zstd-1.5.6/zlibWrapper/gzwrite.c +631 -0
  116. data/ext/zstdlib_c/zstd-1.5.6/zlibWrapper/zstd_zlibwrapper.c +1200 -0
  117. data/ext/zstdlib_c/zstd-1.5.6/zlibWrapper/zstd_zlibwrapper.h +91 -0
  118. data/ext/zstdlib_c/zstd.mk +15 -0
  119. data/lib/2.4/zstdlib_c.so +0 -0
  120. data/lib/2.5/zstdlib_c.so +0 -0
  121. data/lib/2.6/zstdlib_c.so +0 -0
  122. data/lib/2.7/zstdlib_c.so +0 -0
  123. data/lib/3.0/zstdlib_c.so +0 -0
  124. data/lib/3.1/zstdlib_c.so +0 -0
  125. data/lib/3.2/zstdlib_c.so +0 -0
  126. data/lib/3.3/zstdlib_c.so +0 -0
  127. data/lib/zstdlib.rb +6 -0
  128. data/test/zstdlib_test.rb +21 -0
  129. metadata +243 -0
@@ -0,0 +1,200 @@
1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ #ifndef ZSTD_BITS_H
12
+ #define ZSTD_BITS_H
13
+
14
+ #include "mem.h"
15
+
16
+ MEM_STATIC unsigned ZSTD_countTrailingZeros32_fallback(U32 val)
17
+ {
18
+ assert(val != 0);
19
+ {
20
+ static const U32 DeBruijnBytePos[32] = {0, 1, 28, 2, 29, 14, 24, 3,
21
+ 30, 22, 20, 15, 25, 17, 4, 8,
22
+ 31, 27, 13, 23, 21, 19, 16, 7,
23
+ 26, 12, 18, 6, 11, 5, 10, 9};
24
+ return DeBruijnBytePos[((U32) ((val & -(S32) val) * 0x077CB531U)) >> 27];
25
+ }
26
+ }
27
+
28
+ MEM_STATIC unsigned ZSTD_countTrailingZeros32(U32 val)
29
+ {
30
+ assert(val != 0);
31
+ # if defined(_MSC_VER)
32
+ # if STATIC_BMI2 == 1
33
+ return (unsigned)_tzcnt_u32(val);
34
+ # else
35
+ if (val != 0) {
36
+ unsigned long r;
37
+ _BitScanForward(&r, val);
38
+ return (unsigned)r;
39
+ } else {
40
+ /* Should not reach this code path */
41
+ __assume(0);
42
+ }
43
+ # endif
44
+ # elif defined(__GNUC__) && (__GNUC__ >= 4)
45
+ return (unsigned)__builtin_ctz(val);
46
+ # else
47
+ return ZSTD_countTrailingZeros32_fallback(val);
48
+ # endif
49
+ }
50
+
51
+ MEM_STATIC unsigned ZSTD_countLeadingZeros32_fallback(U32 val) {
52
+ assert(val != 0);
53
+ {
54
+ static const U32 DeBruijnClz[32] = {0, 9, 1, 10, 13, 21, 2, 29,
55
+ 11, 14, 16, 18, 22, 25, 3, 30,
56
+ 8, 12, 20, 28, 15, 17, 24, 7,
57
+ 19, 27, 23, 6, 26, 5, 4, 31};
58
+ val |= val >> 1;
59
+ val |= val >> 2;
60
+ val |= val >> 4;
61
+ val |= val >> 8;
62
+ val |= val >> 16;
63
+ return 31 - DeBruijnClz[(val * 0x07C4ACDDU) >> 27];
64
+ }
65
+ }
66
+
67
+ MEM_STATIC unsigned ZSTD_countLeadingZeros32(U32 val)
68
+ {
69
+ assert(val != 0);
70
+ # if defined(_MSC_VER)
71
+ # if STATIC_BMI2 == 1
72
+ return (unsigned)_lzcnt_u32(val);
73
+ # else
74
+ if (val != 0) {
75
+ unsigned long r;
76
+ _BitScanReverse(&r, val);
77
+ return (unsigned)(31 - r);
78
+ } else {
79
+ /* Should not reach this code path */
80
+ __assume(0);
81
+ }
82
+ # endif
83
+ # elif defined(__GNUC__) && (__GNUC__ >= 4)
84
+ return (unsigned)__builtin_clz(val);
85
+ # else
86
+ return ZSTD_countLeadingZeros32_fallback(val);
87
+ # endif
88
+ }
89
+
90
+ MEM_STATIC unsigned ZSTD_countTrailingZeros64(U64 val)
91
+ {
92
+ assert(val != 0);
93
+ # if defined(_MSC_VER) && defined(_WIN64)
94
+ # if STATIC_BMI2 == 1
95
+ return (unsigned)_tzcnt_u64(val);
96
+ # else
97
+ if (val != 0) {
98
+ unsigned long r;
99
+ _BitScanForward64(&r, val);
100
+ return (unsigned)r;
101
+ } else {
102
+ /* Should not reach this code path */
103
+ __assume(0);
104
+ }
105
+ # endif
106
+ # elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(__LP64__)
107
+ return (unsigned)__builtin_ctzll(val);
108
+ # else
109
+ {
110
+ U32 mostSignificantWord = (U32)(val >> 32);
111
+ U32 leastSignificantWord = (U32)val;
112
+ if (leastSignificantWord == 0) {
113
+ return 32 + ZSTD_countTrailingZeros32(mostSignificantWord);
114
+ } else {
115
+ return ZSTD_countTrailingZeros32(leastSignificantWord);
116
+ }
117
+ }
118
+ # endif
119
+ }
120
+
121
+ MEM_STATIC unsigned ZSTD_countLeadingZeros64(U64 val)
122
+ {
123
+ assert(val != 0);
124
+ # if defined(_MSC_VER) && defined(_WIN64)
125
+ # if STATIC_BMI2 == 1
126
+ return (unsigned)_lzcnt_u64(val);
127
+ # else
128
+ if (val != 0) {
129
+ unsigned long r;
130
+ _BitScanReverse64(&r, val);
131
+ return (unsigned)(63 - r);
132
+ } else {
133
+ /* Should not reach this code path */
134
+ __assume(0);
135
+ }
136
+ # endif
137
+ # elif defined(__GNUC__) && (__GNUC__ >= 4)
138
+ return (unsigned)(__builtin_clzll(val));
139
+ # else
140
+ {
141
+ U32 mostSignificantWord = (U32)(val >> 32);
142
+ U32 leastSignificantWord = (U32)val;
143
+ if (mostSignificantWord == 0) {
144
+ return 32 + ZSTD_countLeadingZeros32(leastSignificantWord);
145
+ } else {
146
+ return ZSTD_countLeadingZeros32(mostSignificantWord);
147
+ }
148
+ }
149
+ # endif
150
+ }
151
+
152
+ MEM_STATIC unsigned ZSTD_NbCommonBytes(size_t val)
153
+ {
154
+ if (MEM_isLittleEndian()) {
155
+ if (MEM_64bits()) {
156
+ return ZSTD_countTrailingZeros64((U64)val) >> 3;
157
+ } else {
158
+ return ZSTD_countTrailingZeros32((U32)val) >> 3;
159
+ }
160
+ } else { /* Big Endian CPU */
161
+ if (MEM_64bits()) {
162
+ return ZSTD_countLeadingZeros64((U64)val) >> 3;
163
+ } else {
164
+ return ZSTD_countLeadingZeros32((U32)val) >> 3;
165
+ }
166
+ }
167
+ }
168
+
169
+ MEM_STATIC unsigned ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */
170
+ {
171
+ assert(val != 0);
172
+ return 31 - ZSTD_countLeadingZeros32(val);
173
+ }
174
+
175
+ /* ZSTD_rotateRight_*():
176
+ * Rotates a bitfield to the right by "count" bits.
177
+ * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts
178
+ */
179
+ MEM_STATIC
180
+ U64 ZSTD_rotateRight_U64(U64 const value, U32 count) {
181
+ assert(count < 64);
182
+ count &= 0x3F; /* for fickle pattern recognition */
183
+ return (value >> count) | (U64)(value << ((0U - count) & 0x3F));
184
+ }
185
+
186
+ MEM_STATIC
187
+ U32 ZSTD_rotateRight_U32(U32 const value, U32 count) {
188
+ assert(count < 32);
189
+ count &= 0x1F; /* for fickle pattern recognition */
190
+ return (value >> count) | (U32)(value << ((0U - count) & 0x1F));
191
+ }
192
+
193
+ MEM_STATIC
194
+ U16 ZSTD_rotateRight_U16(U16 const value, U32 count) {
195
+ assert(count < 16);
196
+ count &= 0x0F; /* for fickle pattern recognition */
197
+ return (value >> count) | (U16)(value << ((0U - count) & 0x0F));
198
+ }
199
+
200
+ #endif /* ZSTD_BITS_H */
@@ -0,0 +1,457 @@
1
+ /* ******************************************************************
2
+ * bitstream
3
+ * Part of FSE library
4
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
5
+ *
6
+ * You can contact the author at :
7
+ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
8
+ *
9
+ * This source code is licensed under both the BSD-style license (found in the
10
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11
+ * in the COPYING file in the root directory of this source tree).
12
+ * You may select, at your option, one of the above-listed licenses.
13
+ ****************************************************************** */
14
+ #ifndef BITSTREAM_H_MODULE
15
+ #define BITSTREAM_H_MODULE
16
+
17
+ #if defined (__cplusplus)
18
+ extern "C" {
19
+ #endif
20
+ /*
21
+ * This API consists of small unitary functions, which must be inlined for best performance.
22
+ * Since link-time-optimization is not available for all compilers,
23
+ * these functions are defined into a .h to be included.
24
+ */
25
+
26
+ /*-****************************************
27
+ * Dependencies
28
+ ******************************************/
29
+ #include "mem.h" /* unaligned access routines */
30
+ #include "compiler.h" /* UNLIKELY() */
31
+ #include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */
32
+ #include "error_private.h" /* error codes and messages */
33
+ #include "bits.h" /* ZSTD_highbit32 */
34
+
35
+
36
+ /*=========================================
37
+ * Target specific
38
+ =========================================*/
39
+ #ifndef ZSTD_NO_INTRINSICS
40
+ # if (defined(__BMI__) || defined(__BMI2__)) && defined(__GNUC__)
41
+ # include <immintrin.h> /* support for bextr (experimental)/bzhi */
42
+ # elif defined(__ICCARM__)
43
+ # include <intrinsics.h>
44
+ # endif
45
+ #endif
46
+
47
+ #define STREAM_ACCUMULATOR_MIN_32 25
48
+ #define STREAM_ACCUMULATOR_MIN_64 57
49
+ #define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64))
50
+
51
+
52
+ /*-******************************************
53
+ * bitStream encoding API (write forward)
54
+ ********************************************/
55
+ /* bitStream can mix input from multiple sources.
56
+ * A critical property of these streams is that they encode and decode in **reverse** direction.
57
+ * So the first bit sequence you add will be the last to be read, like a LIFO stack.
58
+ */
59
+ typedef struct {
60
+ size_t bitContainer;
61
+ unsigned bitPos;
62
+ char* startPtr;
63
+ char* ptr;
64
+ char* endPtr;
65
+ } BIT_CStream_t;
66
+
67
+ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity);
68
+ MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
69
+ MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC);
70
+ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
71
+
72
+ /* Start with initCStream, providing the size of buffer to write into.
73
+ * bitStream will never write outside of this buffer.
74
+ * `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code.
75
+ *
76
+ * bits are first added to a local register.
77
+ * Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems.
78
+ * Writing data into memory is an explicit operation, performed by the flushBits function.
79
+ * Hence keep track how many bits are potentially stored into local register to avoid register overflow.
80
+ * After a flushBits, a maximum of 7 bits might still be stored into local register.
81
+ *
82
+ * Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers.
83
+ *
84
+ * Last operation is to close the bitStream.
85
+ * The function returns the final size of CStream in bytes.
86
+ * If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable)
87
+ */
88
+
89
+
90
+ /*-********************************************
91
+ * bitStream decoding API (read backward)
92
+ **********************************************/
93
+ typedef size_t BitContainerType;
94
+ typedef struct {
95
+ BitContainerType bitContainer;
96
+ unsigned bitsConsumed;
97
+ const char* ptr;
98
+ const char* start;
99
+ const char* limitPtr;
100
+ } BIT_DStream_t;
101
+
102
+ typedef enum { BIT_DStream_unfinished = 0, /* fully refilled */
103
+ BIT_DStream_endOfBuffer = 1, /* still some bits left in bitstream */
104
+ BIT_DStream_completed = 2, /* bitstream entirely consumed, bit-exact */
105
+ BIT_DStream_overflow = 3 /* user requested more bits than present in bitstream */
106
+ } BIT_DStream_status; /* result of BIT_reloadDStream() */
107
+
108
+ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
109
+ MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
110
+ MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);
111
+ MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);
112
+
113
+
114
+ /* Start by invoking BIT_initDStream().
115
+ * A chunk of the bitStream is then stored into a local register.
116
+ * Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (BitContainerType).
117
+ * You can then retrieve bitFields stored into the local register, **in reverse order**.
118
+ * Local register is explicitly reloaded from memory by the BIT_reloadDStream() method.
119
+ * A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished.
120
+ * Otherwise, it can be less than that, so proceed accordingly.
121
+ * Checking if DStream has reached its end can be performed with BIT_endOfDStream().
122
+ */
123
+
124
+
125
+ /*-****************************************
126
+ * unsafe API
127
+ ******************************************/
128
+ MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
129
+ /* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */
130
+
131
+ MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC);
132
+ /* unsafe version; does not check buffer overflow */
133
+
134
+ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
135
+ /* faster, but works only if nbBits >= 1 */
136
+
137
+ /*===== Local Constants =====*/
138
+ static const unsigned BIT_mask[] = {
139
+ 0, 1, 3, 7, 0xF, 0x1F,
140
+ 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF,
141
+ 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF,
142
+ 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF,
143
+ 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF,
144
+ 0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */
145
+ #define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0]))
146
+
147
+ /*-**************************************************************
148
+ * bitStream encoding
149
+ ****************************************************************/
150
+ /*! BIT_initCStream() :
151
+ * `dstCapacity` must be > sizeof(size_t)
152
+ * @return : 0 if success,
153
+ * otherwise an error code (can be tested using ERR_isError()) */
154
+ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
155
+ void* startPtr, size_t dstCapacity)
156
+ {
157
+ bitC->bitContainer = 0;
158
+ bitC->bitPos = 0;
159
+ bitC->startPtr = (char*)startPtr;
160
+ bitC->ptr = bitC->startPtr;
161
+ bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer);
162
+ if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall);
163
+ return 0;
164
+ }
165
+
166
+ FORCE_INLINE_TEMPLATE size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
167
+ {
168
+ #if defined(STATIC_BMI2) && STATIC_BMI2 == 1 && !defined(ZSTD_NO_INTRINSICS)
169
+ return _bzhi_u64(bitContainer, nbBits);
170
+ #else
171
+ assert(nbBits < BIT_MASK_SIZE);
172
+ return bitContainer & BIT_mask[nbBits];
173
+ #endif
174
+ }
175
+
176
+ /*! BIT_addBits() :
177
+ * can add up to 31 bits into `bitC`.
178
+ * Note : does not check for register overflow ! */
179
+ MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
180
+ size_t value, unsigned nbBits)
181
+ {
182
+ DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32);
183
+ assert(nbBits < BIT_MASK_SIZE);
184
+ assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
185
+ bitC->bitContainer |= BIT_getLowerBits(value, nbBits) << bitC->bitPos;
186
+ bitC->bitPos += nbBits;
187
+ }
188
+
189
+ /*! BIT_addBitsFast() :
190
+ * works only if `value` is _clean_,
191
+ * meaning all high bits above nbBits are 0 */
192
+ MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC,
193
+ size_t value, unsigned nbBits)
194
+ {
195
+ assert((value>>nbBits) == 0);
196
+ assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
197
+ bitC->bitContainer |= value << bitC->bitPos;
198
+ bitC->bitPos += nbBits;
199
+ }
200
+
201
+ /*! BIT_flushBitsFast() :
202
+ * assumption : bitContainer has not overflowed
203
+ * unsafe version; does not check buffer overflow */
204
+ MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
205
+ {
206
+ size_t const nbBytes = bitC->bitPos >> 3;
207
+ assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
208
+ assert(bitC->ptr <= bitC->endPtr);
209
+ MEM_writeLEST(bitC->ptr, bitC->bitContainer);
210
+ bitC->ptr += nbBytes;
211
+ bitC->bitPos &= 7;
212
+ bitC->bitContainer >>= nbBytes*8;
213
+ }
214
+
215
+ /*! BIT_flushBits() :
216
+ * assumption : bitContainer has not overflowed
217
+ * safe version; check for buffer overflow, and prevents it.
218
+ * note : does not signal buffer overflow.
219
+ * overflow will be revealed later on using BIT_closeCStream() */
220
+ MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
221
+ {
222
+ size_t const nbBytes = bitC->bitPos >> 3;
223
+ assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
224
+ assert(bitC->ptr <= bitC->endPtr);
225
+ MEM_writeLEST(bitC->ptr, bitC->bitContainer);
226
+ bitC->ptr += nbBytes;
227
+ if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
228
+ bitC->bitPos &= 7;
229
+ bitC->bitContainer >>= nbBytes*8;
230
+ }
231
+
232
+ /*! BIT_closeCStream() :
233
+ * @return : size of CStream, in bytes,
234
+ * or 0 if it could not fit into dstBuffer */
235
+ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
236
+ {
237
+ BIT_addBitsFast(bitC, 1, 1); /* endMark */
238
+ BIT_flushBits(bitC);
239
+ if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */
240
+ return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);
241
+ }
242
+
243
+
244
+ /*-********************************************************
245
+ * bitStream decoding
246
+ **********************************************************/
247
+ /*! BIT_initDStream() :
248
+ * Initialize a BIT_DStream_t.
249
+ * `bitD` : a pointer to an already allocated BIT_DStream_t structure.
250
+ * `srcSize` must be the *exact* size of the bitStream, in bytes.
251
+ * @return : size of stream (== srcSize), or an errorCode if a problem is detected
252
+ */
253
+ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
254
+ {
255
+ if (srcSize < 1) { ZSTD_memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
256
+
257
+ bitD->start = (const char*)srcBuffer;
258
+ bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer);
259
+
260
+ if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */
261
+ bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
262
+ bitD->bitContainer = MEM_readLEST(bitD->ptr);
263
+ { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
264
+ bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
265
+ if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
266
+ } else {
267
+ bitD->ptr = bitD->start;
268
+ bitD->bitContainer = *(const BYTE*)(bitD->start);
269
+ switch(srcSize)
270
+ {
271
+ case 7: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
272
+ ZSTD_FALLTHROUGH;
273
+
274
+ case 6: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
275
+ ZSTD_FALLTHROUGH;
276
+
277
+ case 5: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
278
+ ZSTD_FALLTHROUGH;
279
+
280
+ case 4: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[3]) << 24;
281
+ ZSTD_FALLTHROUGH;
282
+
283
+ case 3: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[2]) << 16;
284
+ ZSTD_FALLTHROUGH;
285
+
286
+ case 2: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[1]) << 8;
287
+ ZSTD_FALLTHROUGH;
288
+
289
+ default: break;
290
+ }
291
+ { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
292
+ bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0;
293
+ if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */
294
+ }
295
+ bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
296
+ }
297
+
298
+ return srcSize;
299
+ }
300
+
301
+ FORCE_INLINE_TEMPLATE size_t BIT_getUpperBits(BitContainerType bitContainer, U32 const start)
302
+ {
303
+ return bitContainer >> start;
304
+ }
305
+
306
+ FORCE_INLINE_TEMPLATE size_t BIT_getMiddleBits(BitContainerType bitContainer, U32 const start, U32 const nbBits)
307
+ {
308
+ U32 const regMask = sizeof(bitContainer)*8 - 1;
309
+ /* if start > regMask, bitstream is corrupted, and result is undefined */
310
+ assert(nbBits < BIT_MASK_SIZE);
311
+ /* x86 transform & ((1 << nbBits) - 1) to bzhi instruction, it is better
312
+ * than accessing memory. When bmi2 instruction is not present, we consider
313
+ * such cpus old (pre-Haswell, 2013) and their performance is not of that
314
+ * importance.
315
+ */
316
+ #if defined(__x86_64__) || defined(_M_X86)
317
+ return (bitContainer >> (start & regMask)) & ((((U64)1) << nbBits) - 1);
318
+ #else
319
+ return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];
320
+ #endif
321
+ }
322
+
323
+ /*! BIT_lookBits() :
324
+ * Provides next n bits from local register.
325
+ * local register is not modified.
326
+ * On 32-bits, maxNbBits==24.
327
+ * On 64-bits, maxNbBits==56.
328
+ * @return : value extracted */
329
+ FORCE_INLINE_TEMPLATE size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
330
+ {
331
+ /* arbitrate between double-shift and shift+mask */
332
+ #if 1
333
+ /* if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8,
334
+ * bitstream is likely corrupted, and result is undefined */
335
+ return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits);
336
+ #else
337
+ /* this code path is slower on my os-x laptop */
338
+ U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
339
+ return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask);
340
+ #endif
341
+ }
342
+
343
+ /*! BIT_lookBitsFast() :
344
+ * unsafe version; only works if nbBits >= 1 */
345
+ MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
346
+ {
347
+ U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
348
+ assert(nbBits >= 1);
349
+ return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask);
350
+ }
351
+
352
+ FORCE_INLINE_TEMPLATE void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
353
+ {
354
+ bitD->bitsConsumed += nbBits;
355
+ }
356
+
357
+ /*! BIT_readBits() :
358
+ * Read (consume) next n bits from local register and update.
359
+ * Pay attention to not read more than nbBits contained into local register.
360
+ * @return : extracted value. */
361
+ FORCE_INLINE_TEMPLATE size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)
362
+ {
363
+ size_t const value = BIT_lookBits(bitD, nbBits);
364
+ BIT_skipBits(bitD, nbBits);
365
+ return value;
366
+ }
367
+
368
+ /*! BIT_readBitsFast() :
369
+ * unsafe version; only works if nbBits >= 1 */
370
+ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)
371
+ {
372
+ size_t const value = BIT_lookBitsFast(bitD, nbBits);
373
+ assert(nbBits >= 1);
374
+ BIT_skipBits(bitD, nbBits);
375
+ return value;
376
+ }
377
+
378
+ /*! BIT_reloadDStream_internal() :
379
+ * Simple variant of BIT_reloadDStream(), with two conditions:
380
+ * 1. bitstream is valid : bitsConsumed <= sizeof(bitD->bitContainer)*8
381
+ * 2. look window is valid after shifted down : bitD->ptr >= bitD->start
382
+ */
383
+ MEM_STATIC BIT_DStream_status BIT_reloadDStream_internal(BIT_DStream_t* bitD)
384
+ {
385
+ assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8);
386
+ bitD->ptr -= bitD->bitsConsumed >> 3;
387
+ assert(bitD->ptr >= bitD->start);
388
+ bitD->bitsConsumed &= 7;
389
+ bitD->bitContainer = MEM_readLEST(bitD->ptr);
390
+ return BIT_DStream_unfinished;
391
+ }
392
+
393
+ /*! BIT_reloadDStreamFast() :
394
+ * Similar to BIT_reloadDStream(), but with two differences:
395
+ * 1. bitsConsumed <= sizeof(bitD->bitContainer)*8 must hold!
396
+ * 2. Returns BIT_DStream_overflow when bitD->ptr < bitD->limitPtr, at this
397
+ * point you must use BIT_reloadDStream() to reload.
398
+ */
399
+ MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD)
400
+ {
401
+ if (UNLIKELY(bitD->ptr < bitD->limitPtr))
402
+ return BIT_DStream_overflow;
403
+ return BIT_reloadDStream_internal(bitD);
404
+ }
405
+
406
+ /*! BIT_reloadDStream() :
407
+ * Refill `bitD` from buffer previously set in BIT_initDStream() .
408
+ * This function is safe, it guarantees it will not never beyond src buffer.
409
+ * @return : status of `BIT_DStream_t` internal register.
410
+ * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */
411
+ FORCE_INLINE_TEMPLATE BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
412
+ {
413
+ /* note : once in overflow mode, a bitstream remains in this mode until it's reset */
414
+ if (UNLIKELY(bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))) {
415
+ static const BitContainerType zeroFilled = 0;
416
+ bitD->ptr = (const char*)&zeroFilled; /* aliasing is allowed for char */
417
+ /* overflow detected, erroneous scenario or end of stream: no update */
418
+ return BIT_DStream_overflow;
419
+ }
420
+
421
+ assert(bitD->ptr >= bitD->start);
422
+
423
+ if (bitD->ptr >= bitD->limitPtr) {
424
+ return BIT_reloadDStream_internal(bitD);
425
+ }
426
+ if (bitD->ptr == bitD->start) {
427
+ /* reached end of bitStream => no update */
428
+ if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
429
+ return BIT_DStream_completed;
430
+ }
431
+ /* start < ptr < limitPtr => cautious update */
432
+ { U32 nbBytes = bitD->bitsConsumed >> 3;
433
+ BIT_DStream_status result = BIT_DStream_unfinished;
434
+ if (bitD->ptr - nbBytes < bitD->start) {
435
+ nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */
436
+ result = BIT_DStream_endOfBuffer;
437
+ }
438
+ bitD->ptr -= nbBytes;
439
+ bitD->bitsConsumed -= nbBytes*8;
440
+ bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */
441
+ return result;
442
+ }
443
+ }
444
+
445
+ /*! BIT_endOfDStream() :
446
+ * @return : 1 if DStream has _exactly_ reached its end (all bits consumed).
447
+ */
448
+ MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
449
+ {
450
+ return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));
451
+ }
452
+
453
+ #if defined (__cplusplus)
454
+ }
455
+ #endif
456
+
457
+ #endif /* BITSTREAM_H_MODULE */