zstd-ruby 1.5.6.6 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +66 -1
- data/ext/zstdruby/common.h +38 -15
- data/ext/zstdruby/exports.txt +1 -0
- data/ext/zstdruby/extconf.rb +6 -1
- data/ext/zstdruby/libzstd/common/bits.h +92 -87
- data/ext/zstdruby/libzstd/common/bitstream.h +26 -29
- data/ext/zstdruby/libzstd/common/compiler.h +36 -22
- data/ext/zstdruby/libzstd/common/cpu.h +1 -1
- data/ext/zstdruby/libzstd/common/debug.h +0 -9
- data/ext/zstdruby/libzstd/common/error_private.c +1 -0
- data/ext/zstdruby/libzstd/common/error_private.h +0 -10
- data/ext/zstdruby/libzstd/common/fse.h +2 -17
- data/ext/zstdruby/libzstd/common/fse_decompress.c +2 -0
- data/ext/zstdruby/libzstd/common/huf.h +0 -9
- data/ext/zstdruby/libzstd/common/mem.h +7 -11
- data/ext/zstdruby/libzstd/common/pool.h +0 -9
- data/ext/zstdruby/libzstd/common/portability_macros.h +22 -9
- data/ext/zstdruby/libzstd/common/threading.h +0 -8
- data/ext/zstdruby/libzstd/common/xxhash.h +93 -19
- data/ext/zstdruby/libzstd/common/zstd_deps.h +12 -0
- data/ext/zstdruby/libzstd/common/zstd_internal.h +1 -69
- data/ext/zstdruby/libzstd/common/zstd_trace.h +5 -12
- data/ext/zstdruby/libzstd/compress/hist.c +10 -0
- data/ext/zstdruby/libzstd/compress/hist.h +7 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +1057 -367
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +227 -125
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +7 -7
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +7 -6
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +17 -17
- data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +41 -24
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +58 -50
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +4 -12
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +91 -74
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +4 -12
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +64 -64
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +30 -39
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +48 -33
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +6 -14
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +55 -51
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +8 -16
- data/ext/zstdruby/libzstd/compress/zstd_preSplit.c +238 -0
- data/ext/zstdruby/libzstd/compress/zstd_preSplit.h +33 -0
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +134 -93
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +4 -15
- data/ext/zstdruby/libzstd/decompress/huf_decompress_amd64.S +10 -3
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +14 -11
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +6 -12
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +5 -5
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +60 -19
- data/ext/zstdruby/libzstd/dictBuilder/divsufsort.h +0 -10
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +2 -2
- data/ext/zstdruby/libzstd/zdict.h +15 -8
- data/ext/zstdruby/libzstd/zstd.h +241 -132
- data/ext/zstdruby/libzstd/zstd_errors.h +1 -8
- data/ext/zstdruby/main.c +5 -1
- data/ext/zstdruby/streaming_compress.c +28 -13
- data/ext/zstdruby/streaming_decompress.c +31 -2
- data/ext/zstdruby/zstdruby.c +146 -125
- data/lib/zstd-ruby/stream_writer.rb +1 -1
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +6 -6
|
@@ -15,10 +15,6 @@
|
|
|
15
15
|
extern "C" {
|
|
16
16
|
#endif
|
|
17
17
|
|
|
18
|
-
/*===== dependency =====*/
|
|
19
|
-
#include <stddef.h> /* size_t */
|
|
20
|
-
|
|
21
|
-
|
|
22
18
|
/* ===== ZSTDERRORLIB_API : control library symbols visibility ===== */
|
|
23
19
|
#ifndef ZSTDERRORLIB_VISIBLE
|
|
24
20
|
/* Backwards compatibility with old macro name */
|
|
@@ -80,6 +76,7 @@ typedef enum {
|
|
|
80
76
|
ZSTD_error_tableLog_tooLarge = 44,
|
|
81
77
|
ZSTD_error_maxSymbolValue_tooLarge = 46,
|
|
82
78
|
ZSTD_error_maxSymbolValue_tooSmall = 48,
|
|
79
|
+
ZSTD_error_cannotProduce_uncompressedBlock = 49,
|
|
83
80
|
ZSTD_error_stabilityCondition_notRespected = 50,
|
|
84
81
|
ZSTD_error_stage_wrong = 60,
|
|
85
82
|
ZSTD_error_init_missing = 62,
|
|
@@ -100,10 +97,6 @@ typedef enum {
|
|
|
100
97
|
ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */
|
|
101
98
|
} ZSTD_ErrorCode;
|
|
102
99
|
|
|
103
|
-
/*! ZSTD_getErrorCode() :
|
|
104
|
-
convert a `size_t` function result into a `ZSTD_ErrorCode` enum type,
|
|
105
|
-
which can be used to compare with enum list published above */
|
|
106
|
-
ZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult);
|
|
107
100
|
ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code); /**< Same as ZSTD_getErrorName, but using a `ZSTD_ErrorCode` enum argument */
|
|
108
101
|
|
|
109
102
|
|
data/ext/zstdruby/main.c
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
#include "common.h"
|
|
2
2
|
|
|
3
3
|
VALUE rb_mZstd;
|
|
4
|
+
VALUE rb_cCDict;
|
|
5
|
+
VALUE rb_cDDict;
|
|
4
6
|
void zstd_ruby_init(void);
|
|
5
7
|
void zstd_ruby_skippable_frame_init(void);
|
|
6
8
|
void zstd_ruby_streaming_compress_init(void);
|
|
7
9
|
void zstd_ruby_streaming_decompress_init(void);
|
|
8
10
|
|
|
9
|
-
void
|
|
11
|
+
RUBY_FUNC_EXPORTED void
|
|
10
12
|
Init_zstdruby(void)
|
|
11
13
|
{
|
|
12
14
|
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
|
@@ -14,6 +16,8 @@ Init_zstdruby(void)
|
|
|
14
16
|
#endif
|
|
15
17
|
|
|
16
18
|
rb_mZstd = rb_define_module("Zstd");
|
|
19
|
+
rb_cCDict = rb_define_class_under(rb_mZstd, "CDict", rb_cObject);
|
|
20
|
+
rb_cDDict = rb_define_class_under(rb_mZstd, "DDict", rb_cObject);
|
|
17
21
|
zstd_ruby_init();
|
|
18
22
|
zstd_ruby_skippable_frame_init();
|
|
19
23
|
zstd_ruby_streaming_compress_init();
|
|
@@ -4,6 +4,7 @@ struct streaming_compress_t {
|
|
|
4
4
|
ZSTD_CCtx* ctx;
|
|
5
5
|
VALUE buf;
|
|
6
6
|
size_t buf_size;
|
|
7
|
+
VALUE pending; /* accumulate compressed bytes produced by write() */
|
|
7
8
|
};
|
|
8
9
|
|
|
9
10
|
static void
|
|
@@ -12,8 +13,10 @@ streaming_compress_mark(void *p)
|
|
|
12
13
|
struct streaming_compress_t *sc = p;
|
|
13
14
|
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
|
14
15
|
rb_gc_mark_movable(sc->buf);
|
|
16
|
+
rb_gc_mark_movable(sc->pending);
|
|
15
17
|
#else
|
|
16
18
|
rb_gc_mark(sc->buf);
|
|
19
|
+
rb_gc_mark(sc->pending);
|
|
17
20
|
#endif
|
|
18
21
|
}
|
|
19
22
|
|
|
@@ -40,6 +43,7 @@ streaming_compress_compact(void *p)
|
|
|
40
43
|
{
|
|
41
44
|
struct streaming_compress_t *sc = p;
|
|
42
45
|
sc->buf = rb_gc_location(sc->buf);
|
|
46
|
+
sc->pending = rb_gc_location(sc->pending);
|
|
43
47
|
}
|
|
44
48
|
#endif
|
|
45
49
|
|
|
@@ -64,6 +68,7 @@ rb_streaming_compress_allocate(VALUE klass)
|
|
|
64
68
|
sc->ctx = NULL;
|
|
65
69
|
sc->buf = Qnil;
|
|
66
70
|
sc->buf_size = 0;
|
|
71
|
+
sc->pending = Qnil;
|
|
67
72
|
return obj;
|
|
68
73
|
}
|
|
69
74
|
|
|
@@ -71,8 +76,7 @@ static VALUE
|
|
|
71
76
|
rb_streaming_compress_initialize(int argc, VALUE *argv, VALUE obj)
|
|
72
77
|
{
|
|
73
78
|
VALUE kwargs;
|
|
74
|
-
|
|
75
|
-
rb_scan_args(argc, argv, "01:", &compression_level_value, &kwargs);
|
|
79
|
+
rb_scan_args(argc, argv, "00:", &kwargs);
|
|
76
80
|
|
|
77
81
|
struct streaming_compress_t* sc;
|
|
78
82
|
TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
|
|
@@ -82,11 +86,12 @@ rb_streaming_compress_initialize(int argc, VALUE *argv, VALUE obj)
|
|
|
82
86
|
if (ctx == NULL) {
|
|
83
87
|
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCCtx error");
|
|
84
88
|
}
|
|
85
|
-
set_compress_params(ctx,
|
|
89
|
+
set_compress_params(ctx, kwargs);
|
|
86
90
|
|
|
87
91
|
sc->ctx = ctx;
|
|
88
92
|
sc->buf = rb_str_new(NULL, buffOutSize);
|
|
89
93
|
sc->buf_size = buffOutSize;
|
|
94
|
+
sc->pending = rb_str_new(0, 0);
|
|
90
95
|
|
|
91
96
|
return obj;
|
|
92
97
|
}
|
|
@@ -100,13 +105,13 @@ static VALUE
|
|
|
100
105
|
no_compress(struct streaming_compress_t* sc, ZSTD_EndDirective endOp)
|
|
101
106
|
{
|
|
102
107
|
ZSTD_inBuffer input = { NULL, 0, 0 };
|
|
103
|
-
const char* output_data = RSTRING_PTR(sc->buf);
|
|
104
108
|
VALUE result = rb_str_new(0, 0);
|
|
105
109
|
size_t ret;
|
|
106
110
|
do {
|
|
111
|
+
const char* output_data = RSTRING_PTR(sc->buf);
|
|
107
112
|
ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
|
|
108
113
|
|
|
109
|
-
|
|
114
|
+
ret = zstd_stream_compress(sc->ctx, &output, &input, endOp, false);
|
|
110
115
|
if (ZSTD_isError(ret)) {
|
|
111
116
|
rb_raise(rb_eRuntimeError, "flush error error code: %s", ZSTD_getErrorName(ret));
|
|
112
117
|
}
|
|
@@ -126,9 +131,9 @@ rb_streaming_compress_compress(VALUE obj, VALUE src)
|
|
|
126
131
|
struct streaming_compress_t* sc;
|
|
127
132
|
TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
|
|
128
133
|
|
|
129
|
-
const char* output_data = RSTRING_PTR(sc->buf);
|
|
130
134
|
VALUE result = rb_str_new(0, 0);
|
|
131
135
|
while (input.pos < input.size) {
|
|
136
|
+
const char* output_data = RSTRING_PTR(sc->buf);
|
|
132
137
|
ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
|
|
133
138
|
size_t const ret = zstd_stream_compress(sc->ctx, &output, &input, ZSTD_e_continue, false);
|
|
134
139
|
if (ZSTD_isError(ret)) {
|
|
@@ -143,10 +148,8 @@ static VALUE
|
|
|
143
148
|
rb_streaming_compress_write(int argc, VALUE *argv, VALUE obj)
|
|
144
149
|
{
|
|
145
150
|
size_t total = 0;
|
|
146
|
-
VALUE result = rb_str_new(0, 0);
|
|
147
151
|
struct streaming_compress_t* sc;
|
|
148
152
|
TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
|
|
149
|
-
const char* output_data = RSTRING_PTR(sc->buf);
|
|
150
153
|
|
|
151
154
|
while (argc-- > 0) {
|
|
152
155
|
VALUE str = *argv++;
|
|
@@ -156,14 +159,20 @@ rb_streaming_compress_write(int argc, VALUE *argv, VALUE obj)
|
|
|
156
159
|
ZSTD_inBuffer input = { input_data, input_size, 0 };
|
|
157
160
|
|
|
158
161
|
while (input.pos < input.size) {
|
|
162
|
+
const char* output_data = RSTRING_PTR(sc->buf);
|
|
159
163
|
ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
|
|
160
164
|
size_t const ret = zstd_stream_compress(sc->ctx, &output, &input, ZSTD_e_continue, false);
|
|
161
165
|
if (ZSTD_isError(ret)) {
|
|
162
166
|
rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(ret));
|
|
163
167
|
}
|
|
164
|
-
|
|
168
|
+
/* Directly append to the pending buffer */
|
|
169
|
+
if (output.pos > 0) {
|
|
170
|
+
rb_str_cat(sc->pending, output.dst, output.pos);
|
|
171
|
+
}
|
|
165
172
|
}
|
|
173
|
+
total += RSTRING_LEN(str);
|
|
166
174
|
}
|
|
175
|
+
|
|
167
176
|
return SIZET2NUM(total);
|
|
168
177
|
}
|
|
169
178
|
|
|
@@ -193,8 +202,11 @@ rb_streaming_compress_flush(VALUE obj)
|
|
|
193
202
|
{
|
|
194
203
|
struct streaming_compress_t* sc;
|
|
195
204
|
TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
|
|
196
|
-
VALUE
|
|
197
|
-
|
|
205
|
+
VALUE drained = no_compress(sc, ZSTD_e_flush);
|
|
206
|
+
VALUE out = rb_str_dup(sc->pending);
|
|
207
|
+
rb_str_cat(out, RSTRING_PTR(drained), RSTRING_LEN(drained));
|
|
208
|
+
rb_str_resize(sc->pending, 0);
|
|
209
|
+
return out;
|
|
198
210
|
}
|
|
199
211
|
|
|
200
212
|
static VALUE
|
|
@@ -202,8 +214,11 @@ rb_streaming_compress_finish(VALUE obj)
|
|
|
202
214
|
{
|
|
203
215
|
struct streaming_compress_t* sc;
|
|
204
216
|
TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
|
|
205
|
-
VALUE
|
|
206
|
-
|
|
217
|
+
VALUE drained = no_compress(sc, ZSTD_e_end);
|
|
218
|
+
VALUE out = rb_str_dup(sc->pending);
|
|
219
|
+
rb_str_cat(out, RSTRING_PTR(drained), RSTRING_LEN(drained));
|
|
220
|
+
rb_str_resize(sc->pending, 0);
|
|
221
|
+
return out;
|
|
207
222
|
}
|
|
208
223
|
|
|
209
224
|
extern VALUE rb_mZstd, cStreamingCompress;
|
|
@@ -100,19 +100,47 @@ rb_streaming_decompress_decompress(VALUE obj, VALUE src)
|
|
|
100
100
|
|
|
101
101
|
struct streaming_decompress_t* sd;
|
|
102
102
|
TypedData_Get_Struct(obj, struct streaming_decompress_t, &streaming_decompress_type, sd);
|
|
103
|
-
const char* output_data = RSTRING_PTR(sd->buf);
|
|
104
103
|
VALUE result = rb_str_new(0, 0);
|
|
104
|
+
|
|
105
105
|
while (input.pos < input.size) {
|
|
106
|
+
const char* output_data = RSTRING_PTR(sd->buf);
|
|
106
107
|
ZSTD_outBuffer output = { (void*)output_data, sd->buf_size, 0 };
|
|
107
108
|
size_t const ret = zstd_stream_decompress(sd->dctx, &output, &input, false);
|
|
109
|
+
|
|
108
110
|
if (ZSTD_isError(ret)) {
|
|
109
111
|
rb_raise(rb_eRuntimeError, "decompress error error code: %s", ZSTD_getErrorName(ret));
|
|
110
112
|
}
|
|
111
|
-
|
|
113
|
+
if (output.pos > 0) {
|
|
114
|
+
rb_str_cat(result, output.dst, output.pos);
|
|
115
|
+
}
|
|
116
|
+
if (ret == 0 && output.pos == 0) {
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
112
119
|
}
|
|
113
120
|
return result;
|
|
114
121
|
}
|
|
115
122
|
|
|
123
|
+
static VALUE
|
|
124
|
+
rb_streaming_decompress_decompress_with_pos(VALUE obj, VALUE src)
|
|
125
|
+
{
|
|
126
|
+
StringValue(src);
|
|
127
|
+
const char* input_data = RSTRING_PTR(src);
|
|
128
|
+
size_t input_size = RSTRING_LEN(src);
|
|
129
|
+
ZSTD_inBuffer input = { input_data, input_size, 0 };
|
|
130
|
+
|
|
131
|
+
struct streaming_decompress_t* sd;
|
|
132
|
+
TypedData_Get_Struct(obj, struct streaming_decompress_t, &streaming_decompress_type, sd);
|
|
133
|
+
const char* output_data = RSTRING_PTR(sd->buf);
|
|
134
|
+
VALUE result = rb_str_new(0, 0);
|
|
135
|
+
ZSTD_outBuffer output = { (void*)output_data, sd->buf_size, 0 };
|
|
136
|
+
size_t const ret = zstd_stream_decompress(sd->dctx, &output, &input, false);
|
|
137
|
+
if (ZSTD_isError(ret)) {
|
|
138
|
+
rb_raise(rb_eRuntimeError, "decompress error error code: %s", ZSTD_getErrorName(ret));
|
|
139
|
+
}
|
|
140
|
+
rb_str_cat(result, output.dst, output.pos);
|
|
141
|
+
return rb_ary_new_from_args(2, result, ULONG2NUM(input.pos));
|
|
142
|
+
}
|
|
143
|
+
|
|
116
144
|
extern VALUE rb_mZstd, cStreamingDecompress;
|
|
117
145
|
void
|
|
118
146
|
zstd_ruby_streaming_decompress_init(void)
|
|
@@ -121,4 +149,5 @@ zstd_ruby_streaming_decompress_init(void)
|
|
|
121
149
|
rb_define_alloc_func(cStreamingDecompress, rb_streaming_decompress_allocate);
|
|
122
150
|
rb_define_method(cStreamingDecompress, "initialize", rb_streaming_decompress_initialize, -1);
|
|
123
151
|
rb_define_method(cStreamingDecompress, "decompress", rb_streaming_decompress_decompress, 1);
|
|
152
|
+
rb_define_method(cStreamingDecompress, "decompress_with_pos", rb_streaming_decompress_decompress_with_pos, 1);
|
|
124
153
|
}
|
data/ext/zstdruby/zstdruby.c
CHANGED
|
@@ -11,16 +11,15 @@ static VALUE zstdVersion(VALUE self)
|
|
|
11
11
|
static VALUE rb_compress(int argc, VALUE *argv, VALUE self)
|
|
12
12
|
{
|
|
13
13
|
VALUE input_value;
|
|
14
|
-
VALUE compression_level_value;
|
|
15
14
|
VALUE kwargs;
|
|
16
|
-
rb_scan_args(argc, argv, "
|
|
15
|
+
rb_scan_args(argc, argv, "10:", &input_value, &kwargs);
|
|
17
16
|
|
|
18
17
|
ZSTD_CCtx* const ctx = ZSTD_createCCtx();
|
|
19
18
|
if (ctx == NULL) {
|
|
20
19
|
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCCtx error");
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
set_compress_params(ctx,
|
|
22
|
+
set_compress_params(ctx, kwargs);
|
|
24
23
|
|
|
25
24
|
StringValue(input_value);
|
|
26
25
|
char* input_data = RSTRING_PTR(input_value);
|
|
@@ -40,159 +39,175 @@ static VALUE rb_compress(int argc, VALUE *argv, VALUE self)
|
|
|
40
39
|
return output;
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
static VALUE
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
VALUE compression_level_value;
|
|
49
|
-
rb_scan_args(argc, argv, "21", &input_value, &dict, &compression_level_value);
|
|
50
|
-
int compression_level = convert_compression_level(compression_level_value);
|
|
42
|
+
static VALUE decode_one_frame(ZSTD_DCtx* dctx, const unsigned char* src, size_t size, VALUE kwargs) {
|
|
43
|
+
VALUE out = rb_str_buf_new(0);
|
|
44
|
+
size_t cap = ZSTD_DStreamOutSize();
|
|
45
|
+
char *buf = ALLOC_N(char, cap);
|
|
46
|
+
ZSTD_inBuffer in = (ZSTD_inBuffer){ src, size, 0 };
|
|
51
47
|
|
|
48
|
+
ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only);
|
|
49
|
+
set_decompress_params(dctx, kwargs);
|
|
50
|
+
|
|
51
|
+
for (;;) {
|
|
52
|
+
ZSTD_outBuffer o = (ZSTD_outBuffer){ buf, cap, 0 };
|
|
53
|
+
size_t ret = ZSTD_decompressStream(dctx, &o, &in);
|
|
54
|
+
if (ZSTD_isError(ret)) {
|
|
55
|
+
xfree(buf);
|
|
56
|
+
rb_raise(rb_eRuntimeError, "ZSTD_decompressStream failed: %s", ZSTD_getErrorName(ret));
|
|
57
|
+
}
|
|
58
|
+
if (o.pos) {
|
|
59
|
+
rb_str_cat(out, buf, o.pos);
|
|
60
|
+
}
|
|
61
|
+
if (ret == 0) {
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
xfree(buf);
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static VALUE decompress_buffered(ZSTD_DCtx* dctx, const char* data, size_t len) {
|
|
70
|
+
return decode_one_frame(dctx, (const unsigned char*)data, len, Qnil);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static VALUE rb_decompress(int argc, VALUE *argv, VALUE self)
|
|
74
|
+
{
|
|
75
|
+
VALUE input_value, kwargs;
|
|
76
|
+
rb_scan_args(argc, argv, "10:", &input_value, &kwargs);
|
|
52
77
|
StringValue(input_value);
|
|
53
|
-
char* input_data = RSTRING_PTR(input_value);
|
|
54
|
-
size_t input_size = RSTRING_LEN(input_value);
|
|
55
|
-
size_t max_compressed_size = ZSTD_compressBound(input_size);
|
|
56
78
|
|
|
57
|
-
|
|
58
|
-
|
|
79
|
+
size_t in_size = RSTRING_LEN(input_value);
|
|
80
|
+
const unsigned char *in_r = (const unsigned char *)RSTRING_PTR(input_value);
|
|
81
|
+
unsigned char *in = ALLOC_N(unsigned char, in_size);
|
|
82
|
+
memcpy(in, in_r, in_size);
|
|
83
|
+
|
|
84
|
+
size_t off = 0;
|
|
85
|
+
const uint32_t ZSTD_MAGIC = 0xFD2FB528U;
|
|
86
|
+
const uint32_t SKIP_LO = 0x184D2A50U; /* ...5F */
|
|
87
|
+
|
|
88
|
+
while (off + 4 <= in_size) {
|
|
89
|
+
uint32_t magic = (uint32_t)in[off]
|
|
90
|
+
| ((uint32_t)in[off+1] << 8)
|
|
91
|
+
| ((uint32_t)in[off+2] << 16)
|
|
92
|
+
| ((uint32_t)in[off+3] << 24);
|
|
93
|
+
|
|
94
|
+
if ((magic & 0xFFFFFFF0U) == (SKIP_LO & 0xFFFFFFF0U)) {
|
|
95
|
+
if (off + 8 > in_size) break;
|
|
96
|
+
uint32_t skipLen = (uint32_t)in[off+4]
|
|
97
|
+
| ((uint32_t)in[off+5] << 8)
|
|
98
|
+
| ((uint32_t)in[off+6] << 16)
|
|
99
|
+
| ((uint32_t)in[off+7] << 24);
|
|
100
|
+
size_t adv = (size_t)8 + (size_t)skipLen;
|
|
101
|
+
if (off + adv > in_size) break;
|
|
102
|
+
off += adv;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
59
105
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
ZSTD_freeCDict(cdict);
|
|
67
|
-
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCCtx failed");
|
|
68
|
-
}
|
|
106
|
+
if (magic == ZSTD_MAGIC) {
|
|
107
|
+
ZSTD_DCtx *dctx = ZSTD_createDCtx();
|
|
108
|
+
if (!dctx) {
|
|
109
|
+
xfree(in);
|
|
110
|
+
rb_raise(rb_eRuntimeError, "ZSTD_createDCtx failed");
|
|
111
|
+
}
|
|
69
112
|
|
|
70
|
-
|
|
71
|
-
char* output_data = RSTRING_PTR(output);
|
|
72
|
-
size_t const compressed_size = ZSTD_compress_usingCDict(ctx, (void*)output_data, max_compressed_size,
|
|
73
|
-
(void*)input_data, input_size, cdict);
|
|
113
|
+
VALUE out = decode_one_frame(dctx, in + off, in_size - off, kwargs);
|
|
74
114
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
115
|
+
ZSTD_freeDCtx(dctx);
|
|
116
|
+
xfree(in);
|
|
117
|
+
RB_GC_GUARD(input_value);
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
off += 1;
|
|
79
122
|
}
|
|
80
123
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return output;
|
|
124
|
+
xfree(in);
|
|
125
|
+
RB_GC_GUARD(input_value);
|
|
126
|
+
rb_raise(rb_eRuntimeError, "not a zstd frame (magic not found)");
|
|
85
127
|
}
|
|
86
128
|
|
|
87
|
-
|
|
88
|
-
static VALUE decompress_buffered(ZSTD_DCtx* dctx, const char* input_data, size_t input_size)
|
|
129
|
+
static void free_cdict(void *dict)
|
|
89
130
|
{
|
|
90
|
-
|
|
91
|
-
|
|
131
|
+
ZSTD_freeCDict(dict);
|
|
132
|
+
}
|
|
92
133
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
output.dst = RSTRING_PTR(output_string);
|
|
134
|
+
static size_t sizeof_cdict(const void *dict)
|
|
135
|
+
{
|
|
136
|
+
return ZSTD_sizeof_CDict(dict);
|
|
137
|
+
}
|
|
98
138
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
rb_raise(rb_eRuntimeError, "%s: %s", "ZSTD_decompressStream failed", ZSTD_getErrorName(ret));
|
|
103
|
-
}
|
|
104
|
-
rb_str_cat(result, output.dst, output.pos);
|
|
105
|
-
}
|
|
106
|
-
ZSTD_freeDCtx(dctx);
|
|
107
|
-
return result;
|
|
139
|
+
static void free_ddict(void *dict)
|
|
140
|
+
{
|
|
141
|
+
ZSTD_freeDDict(dict);
|
|
108
142
|
}
|
|
109
143
|
|
|
110
|
-
static
|
|
144
|
+
static size_t sizeof_ddict(const void *dict)
|
|
111
145
|
{
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
rb_scan_args(argc, argv, "10:", &input_value, &kwargs);
|
|
115
|
-
StringValue(input_value);
|
|
116
|
-
char* input_data = RSTRING_PTR(input_value);
|
|
117
|
-
size_t input_size = RSTRING_LEN(input_value);
|
|
118
|
-
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
|
|
119
|
-
if (dctx == NULL) {
|
|
120
|
-
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDCtx failed");
|
|
121
|
-
}
|
|
122
|
-
set_decompress_params(dctx, kwargs);
|
|
146
|
+
return ZSTD_sizeof_DDict(dict);
|
|
147
|
+
}
|
|
123
148
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
// Therefore, we will not standardize on ZSTD_decompressStream
|
|
130
|
-
if (uncompressed_size == ZSTD_CONTENTSIZE_UNKNOWN) {
|
|
131
|
-
return decompress_buffered(dctx, input_data, input_size);
|
|
132
|
-
}
|
|
149
|
+
static const rb_data_type_t cdict_type = {
|
|
150
|
+
"Zstd::CDict",
|
|
151
|
+
{0, free_cdict, sizeof_cdict,},
|
|
152
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
153
|
+
};
|
|
133
154
|
|
|
134
|
-
|
|
135
|
-
|
|
155
|
+
static const rb_data_type_t ddict_type = {
|
|
156
|
+
"Zstd::DDict",
|
|
157
|
+
{0, free_ddict, sizeof_ddict,},
|
|
158
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
159
|
+
};
|
|
136
160
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
ZSTD_freeDCtx(dctx);
|
|
142
|
-
return output;
|
|
161
|
+
static VALUE rb_cdict_alloc(VALUE self)
|
|
162
|
+
{
|
|
163
|
+
ZSTD_CDict* cdict = NULL;
|
|
164
|
+
return TypedData_Wrap_Struct(self, &cdict_type, cdict);
|
|
143
165
|
}
|
|
144
166
|
|
|
145
|
-
static VALUE
|
|
167
|
+
static VALUE rb_cdict_initialize(int argc, VALUE *argv, VALUE self)
|
|
146
168
|
{
|
|
147
|
-
rb_warn("Zstd.decompress_using_dict is deprecated; use Zstd.decompress with `dict:` instead.");
|
|
148
|
-
VALUE input_value;
|
|
149
169
|
VALUE dict;
|
|
150
|
-
|
|
170
|
+
VALUE compression_level_value;
|
|
171
|
+
rb_scan_args(argc, argv, "11", &dict, &compression_level_value);
|
|
172
|
+
int compression_level = convert_compression_level(compression_level_value);
|
|
151
173
|
|
|
152
|
-
StringValue(
|
|
153
|
-
char*
|
|
154
|
-
size_t
|
|
174
|
+
StringValue(dict);
|
|
175
|
+
char* dict_buffer = RSTRING_PTR(dict);
|
|
176
|
+
size_t dict_size = RSTRING_LEN(dict);
|
|
155
177
|
|
|
178
|
+
ZSTD_CDict* const cdict = ZSTD_createCDict(dict_buffer, dict_size, compression_level);
|
|
179
|
+
if (cdict == NULL) {
|
|
180
|
+
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCDict failed");
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
DATA_PTR(self) = cdict;
|
|
184
|
+
return self;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
static VALUE rb_ddict_alloc(VALUE self)
|
|
188
|
+
{
|
|
189
|
+
ZSTD_CDict* ddict = NULL;
|
|
190
|
+
return TypedData_Wrap_Struct(self, &ddict_type, ddict);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
static VALUE rb_ddict_initialize(VALUE self, VALUE dict)
|
|
194
|
+
{
|
|
195
|
+
StringValue(dict);
|
|
156
196
|
char* dict_buffer = RSTRING_PTR(dict);
|
|
157
197
|
size_t dict_size = RSTRING_LEN(dict);
|
|
198
|
+
|
|
158
199
|
ZSTD_DDict* const ddict = ZSTD_createDDict(dict_buffer, dict_size);
|
|
159
200
|
if (ddict == NULL) {
|
|
160
201
|
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDDict failed");
|
|
161
202
|
}
|
|
162
|
-
unsigned const expected_dict_id = ZSTD_getDictID_fromDDict(ddict);
|
|
163
|
-
unsigned const actual_dict_id = ZSTD_getDictID_fromFrame(input_data, input_size);
|
|
164
|
-
if (expected_dict_id != actual_dict_id) {
|
|
165
|
-
ZSTD_freeDDict(ddict);
|
|
166
|
-
rb_raise(rb_eRuntimeError, "DictID mismatch");
|
|
167
|
-
}
|
|
168
203
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDCtx failed");
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
unsigned long long const uncompressed_size = ZSTD_getFrameContentSize(input_data, input_size);
|
|
176
|
-
if (uncompressed_size == ZSTD_CONTENTSIZE_ERROR) {
|
|
177
|
-
ZSTD_freeDDict(ddict);
|
|
178
|
-
ZSTD_freeDCtx(ctx);
|
|
179
|
-
rb_raise(rb_eRuntimeError, "%s: %s", "not compressed by zstd", ZSTD_getErrorName(uncompressed_size));
|
|
180
|
-
}
|
|
181
|
-
if (uncompressed_size == ZSTD_CONTENTSIZE_UNKNOWN) {
|
|
182
|
-
return decompress_buffered(ctx, input_data, input_size);
|
|
183
|
-
}
|
|
204
|
+
DATA_PTR(self) = ddict;
|
|
205
|
+
return self;
|
|
206
|
+
}
|
|
184
207
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (ZSTD_isError(decompress_size)) {
|
|
189
|
-
ZSTD_freeDDict(ddict);
|
|
190
|
-
ZSTD_freeDCtx(ctx);
|
|
191
|
-
rb_raise(rb_eRuntimeError, "%s: %s", "decompress error", ZSTD_getErrorName(decompress_size));
|
|
192
|
-
}
|
|
193
|
-
ZSTD_freeDDict(ddict);
|
|
194
|
-
ZSTD_freeDCtx(ctx);
|
|
195
|
-
return output;
|
|
208
|
+
static VALUE rb_prohibit_copy(VALUE self, VALUE obj)
|
|
209
|
+
{
|
|
210
|
+
rb_raise(rb_eRuntimeError, "CDict cannot be duplicated");
|
|
196
211
|
}
|
|
197
212
|
|
|
198
213
|
void
|
|
@@ -200,7 +215,13 @@ zstd_ruby_init(void)
|
|
|
200
215
|
{
|
|
201
216
|
rb_define_module_function(rb_mZstd, "zstd_version", zstdVersion, 0);
|
|
202
217
|
rb_define_module_function(rb_mZstd, "compress", rb_compress, -1);
|
|
203
|
-
rb_define_module_function(rb_mZstd, "compress_using_dict", rb_compress_using_dict, -1);
|
|
204
218
|
rb_define_module_function(rb_mZstd, "decompress", rb_decompress, -1);
|
|
205
|
-
|
|
219
|
+
|
|
220
|
+
rb_define_alloc_func(rb_cCDict, rb_cdict_alloc);
|
|
221
|
+
rb_define_private_method(rb_cCDict, "initialize", rb_cdict_initialize, -1);
|
|
222
|
+
rb_define_method(rb_cCDict, "initialize_copy", rb_prohibit_copy, 1);
|
|
223
|
+
|
|
224
|
+
rb_define_alloc_func(rb_cDDict, rb_ddict_alloc);
|
|
225
|
+
rb_define_private_method(rb_cDDict, "initialize", rb_ddict_initialize, 1);
|
|
226
|
+
rb_define_method(rb_cDDict, "initialize_copy", rb_prohibit_copy, 1);
|
|
206
227
|
}
|
data/lib/zstd-ruby/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zstd-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- SpringMT
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2025-09-29 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: bundler
|
|
@@ -100,6 +99,7 @@ files:
|
|
|
100
99
|
- bin/console
|
|
101
100
|
- bin/setup
|
|
102
101
|
- ext/zstdruby/common.h
|
|
102
|
+
- ext/zstdruby/exports.txt
|
|
103
103
|
- ext/zstdruby/extconf.rb
|
|
104
104
|
- ext/zstdruby/libzstd/common/allocations.h
|
|
105
105
|
- ext/zstdruby/libzstd/common/bits.h
|
|
@@ -151,6 +151,8 @@ files:
|
|
|
151
151
|
- ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h
|
|
152
152
|
- ext/zstdruby/libzstd/compress/zstd_opt.c
|
|
153
153
|
- ext/zstdruby/libzstd/compress/zstd_opt.h
|
|
154
|
+
- ext/zstdruby/libzstd/compress/zstd_preSplit.c
|
|
155
|
+
- ext/zstdruby/libzstd/compress/zstd_preSplit.h
|
|
154
156
|
- ext/zstdruby/libzstd/compress/zstdmt_compress.c
|
|
155
157
|
- ext/zstdruby/libzstd/compress/zstdmt_compress.h
|
|
156
158
|
- ext/zstdruby/libzstd/decompress/huf_decompress.c
|
|
@@ -185,7 +187,6 @@ homepage: https://github.com/SpringMT/zstd-ruby
|
|
|
185
187
|
licenses:
|
|
186
188
|
- MIT
|
|
187
189
|
metadata: {}
|
|
188
|
-
post_install_message:
|
|
189
190
|
rdoc_options: []
|
|
190
191
|
require_paths:
|
|
191
192
|
- lib
|
|
@@ -200,8 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
200
201
|
- !ruby/object:Gem::Version
|
|
201
202
|
version: '0'
|
|
202
203
|
requirements: []
|
|
203
|
-
rubygems_version: 3.
|
|
204
|
-
signing_key:
|
|
204
|
+
rubygems_version: 3.6.2
|
|
205
205
|
specification_version: 4
|
|
206
206
|
summary: Ruby binding for zstd(Zstandard - Fast real-time compression algorithm)
|
|
207
207
|
test_files: []
|