extzstd 0.1.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/HISTORY.ja.md +18 -0
- data/README.md +15 -50
- data/contrib/zstd/CONTRIBUTING.md +1 -1
- data/contrib/zstd/COPYING +339 -0
- data/contrib/zstd/Makefile +82 -51
- data/contrib/zstd/NEWS +92 -5
- data/contrib/zstd/README.md +50 -41
- data/contrib/zstd/appveyor.yml +164 -102
- data/contrib/zstd/circle.yml +10 -22
- data/contrib/zstd/lib/BUCK +31 -10
- data/contrib/zstd/lib/Makefile +57 -31
- data/contrib/zstd/lib/README.md +68 -37
- data/contrib/zstd/lib/common/bitstream.h +130 -76
- data/contrib/zstd/lib/common/compiler.h +86 -0
- data/contrib/zstd/lib/common/error_private.c +15 -11
- data/contrib/zstd/lib/common/error_private.h +8 -8
- data/contrib/zstd/lib/common/fse.h +19 -9
- data/contrib/zstd/lib/common/fse_decompress.c +3 -22
- data/contrib/zstd/lib/common/huf.h +68 -26
- data/contrib/zstd/lib/common/mem.h +23 -35
- data/contrib/zstd/lib/common/pool.c +123 -63
- data/contrib/zstd/lib/common/pool.h +19 -10
- data/contrib/zstd/lib/common/threading.c +11 -16
- data/contrib/zstd/lib/common/threading.h +52 -33
- data/contrib/zstd/lib/common/xxhash.c +28 -22
- data/contrib/zstd/lib/common/zstd_common.c +40 -27
- data/contrib/zstd/lib/common/zstd_errors.h +43 -34
- data/contrib/zstd/lib/common/zstd_internal.h +131 -123
- data/contrib/zstd/lib/compress/fse_compress.c +17 -33
- data/contrib/zstd/lib/compress/huf_compress.c +15 -9
- data/contrib/zstd/lib/compress/zstd_compress.c +2096 -2363
- data/contrib/zstd/lib/compress/zstd_compress_internal.h +462 -0
- data/contrib/zstd/lib/compress/zstd_double_fast.c +309 -0
- data/contrib/zstd/lib/compress/zstd_double_fast.h +29 -0
- data/contrib/zstd/lib/compress/zstd_fast.c +243 -0
- data/contrib/zstd/lib/compress/zstd_fast.h +31 -0
- data/contrib/zstd/lib/compress/zstd_lazy.c +765 -0
- data/contrib/zstd/lib/compress/zstd_lazy.h +39 -0
- data/contrib/zstd/lib/compress/zstd_ldm.c +707 -0
- data/contrib/zstd/lib/compress/zstd_ldm.h +68 -0
- data/contrib/zstd/lib/compress/zstd_opt.c +785 -0
- data/contrib/zstd/lib/compress/zstd_opt.h +19 -908
- data/contrib/zstd/lib/compress/zstdmt_compress.c +737 -327
- data/contrib/zstd/lib/compress/zstdmt_compress.h +88 -26
- data/contrib/zstd/lib/decompress/huf_decompress.c +158 -50
- data/contrib/zstd/lib/decompress/zstd_decompress.c +884 -699
- data/contrib/zstd/lib/deprecated/zbuff.h +5 -4
- data/contrib/zstd/lib/deprecated/zbuff_common.c +5 -5
- data/contrib/zstd/lib/deprecated/zbuff_compress.c +6 -4
- data/contrib/zstd/lib/deprecated/zbuff_decompress.c +5 -4
- data/contrib/zstd/lib/dictBuilder/cover.c +93 -77
- data/contrib/zstd/lib/dictBuilder/zdict.c +107 -92
- data/contrib/zstd/lib/dictBuilder/zdict.h +112 -102
- data/contrib/zstd/lib/legacy/zstd_legacy.h +9 -4
- data/contrib/zstd/lib/legacy/zstd_v01.c +7 -6
- data/contrib/zstd/lib/legacy/zstd_v01.h +5 -4
- data/contrib/zstd/lib/legacy/zstd_v02.c +27 -99
- data/contrib/zstd/lib/legacy/zstd_v02.h +5 -4
- data/contrib/zstd/lib/legacy/zstd_v03.c +26 -98
- data/contrib/zstd/lib/legacy/zstd_v03.h +5 -4
- data/contrib/zstd/lib/legacy/zstd_v04.c +22 -91
- data/contrib/zstd/lib/legacy/zstd_v04.h +5 -4
- data/contrib/zstd/lib/legacy/zstd_v05.c +23 -99
- data/contrib/zstd/lib/legacy/zstd_v05.h +5 -4
- data/contrib/zstd/lib/legacy/zstd_v06.c +22 -96
- data/contrib/zstd/lib/legacy/zstd_v06.h +5 -4
- data/contrib/zstd/lib/legacy/zstd_v07.c +19 -95
- data/contrib/zstd/lib/legacy/zstd_v07.h +5 -4
- data/contrib/zstd/lib/zstd.h +895 -271
- data/ext/extconf.rb +11 -2
- data/ext/extzstd.c +45 -128
- data/ext/extzstd.h +74 -31
- data/ext/extzstd_stream.c +401 -142
- data/ext/zstd_common.c +5 -0
- data/ext/zstd_compress.c +8 -0
- data/ext/zstd_decompress.c +1 -0
- data/ext/zstd_dictbuilder.c +2 -0
- data/lib/extzstd/version.rb +1 -1
- data/lib/extzstd.rb +48 -1
- data/test/test_basic.rb +9 -1
- metadata +17 -7
- data/HISTORY.ja +0 -10
- data/contrib/zstd/LICENSE-examples +0 -11
- data/contrib/zstd/PATENTS +0 -33
data/ext/extzstd_stream.c
CHANGED
@@ -2,48 +2,97 @@
|
|
2
2
|
#include "extzstd_nogvls.h"
|
3
3
|
#include <errno.h>
|
4
4
|
|
5
|
+
enum {
|
6
|
+
EXT_PARTIAL_READ_SIZE = 256 * 1024, /* 256 KiB */
|
7
|
+
EXT_READ_GROWUP_SIZE = 256 * 1024, /* 256 KiB */
|
8
|
+
EXT_READ_DOUBLE_GROWUP_LIMIT_SIZE = 4 * 1024 * 1024, /* 4 MiB */
|
9
|
+
};
|
10
|
+
|
11
|
+
static inline VALUE
|
12
|
+
aux_str_buf_recycle(VALUE str, size_t capacity)
|
13
|
+
{
|
14
|
+
if (!RTEST(str) || rb_obj_frozen_p(str) || !rb_type_p(str, RUBY_T_STRING)) {
|
15
|
+
return rb_str_buf_new(capacity);
|
16
|
+
} else {
|
17
|
+
return aux_str_modify_expand(str, capacity);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
static ID id_op_lsh, id_read;
|
22
|
+
|
5
23
|
/*
|
6
|
-
* class Zstd::
|
24
|
+
* class Zstd::Encoder
|
7
25
|
*/
|
8
26
|
|
9
27
|
static VALUE cStreamEncoder;
|
10
28
|
|
29
|
+
struct encoder
|
30
|
+
{
|
31
|
+
ZSTD_CStream *context;
|
32
|
+
VALUE outport;
|
33
|
+
VALUE predict;
|
34
|
+
VALUE destbuf;
|
35
|
+
int reached_eof;
|
36
|
+
};
|
37
|
+
|
11
38
|
static void
|
12
|
-
|
39
|
+
enc_gc_mark(void *pp)
|
13
40
|
{
|
14
|
-
|
41
|
+
if (pp) {
|
42
|
+
struct encoder *p = (struct encoder *)pp;
|
43
|
+
rb_gc_mark(p->outport);
|
44
|
+
rb_gc_mark(p->predict);
|
45
|
+
rb_gc_mark(p->destbuf);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
static void
|
50
|
+
enc_free(void *pp)
|
51
|
+
{
|
52
|
+
if (pp) {
|
53
|
+
struct encoder *p = (struct encoder *)pp;
|
54
|
+
if (p->context) {
|
55
|
+
ZSTD_freeCStream(p->context);
|
56
|
+
p->context = NULL;
|
57
|
+
}
|
58
|
+
xfree(p);
|
59
|
+
}
|
15
60
|
}
|
16
61
|
|
17
62
|
AUX_IMPLEMENT_CONTEXT(
|
18
|
-
|
19
|
-
encoder_alloc_dummy,
|
63
|
+
struct encoder, encoder_type, "extzstd.Zstd::Encoder",
|
64
|
+
encoder_alloc_dummy, enc_gc_mark, enc_free, NULL,
|
20
65
|
getencoderp, getencoder, encoder_p);
|
21
66
|
|
22
67
|
static VALUE
|
23
68
|
enc_alloc(VALUE mod)
|
24
69
|
{
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
p = ZSTD_createCStream();
|
31
|
-
if (!p) {
|
32
|
-
errno = ENOMEM;
|
33
|
-
rb_sys_fail("failed ZSTD_createCStream()");
|
34
|
-
}
|
35
|
-
}
|
36
|
-
DATA_PTR(obj) = p;
|
37
|
-
|
70
|
+
struct encoder *p;
|
71
|
+
VALUE obj = TypedData_Make_Struct(mod, struct encoder, &encoder_type, p);
|
72
|
+
p->outport = Qnil;
|
73
|
+
p->predict = Qnil;
|
74
|
+
p->destbuf = Qnil;
|
38
75
|
return obj;
|
39
76
|
}
|
40
77
|
|
78
|
+
static struct encoder *
|
79
|
+
encoder_context(VALUE self)
|
80
|
+
{
|
81
|
+
struct encoder *p = getencoder(self);
|
82
|
+
if (!p->context) {
|
83
|
+
rb_raise(rb_eTypeError,
|
84
|
+
"wrong initialized context - #<%s:%p>",
|
85
|
+
rb_obj_classname(self), (void *)self);
|
86
|
+
}
|
87
|
+
return p;
|
88
|
+
}
|
89
|
+
|
41
90
|
/*
|
42
91
|
* call-seq:
|
43
|
-
* initialize(compression_parameters, predict)
|
92
|
+
* initialize(outport, compression_parameters = nil, predict = nil)
|
44
93
|
*/
|
45
94
|
static VALUE
|
46
|
-
enc_init(
|
95
|
+
enc_init(int argc, VALUE argv[], VALUE self)
|
47
96
|
{
|
48
97
|
/*
|
49
98
|
* ZSTDLIB_API size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
|
@@ -52,7 +101,37 @@ enc_init(VALUE self, VALUE params, VALUE predict)
|
|
52
101
|
* ZSTD_parameters params, unsigned long long pledgedSrcSize);
|
53
102
|
*/
|
54
103
|
|
55
|
-
|
104
|
+
VALUE outport, params, predict;
|
105
|
+
switch (argc) {
|
106
|
+
case 1:
|
107
|
+
outport = argv[0];
|
108
|
+
params = predict = Qnil;
|
109
|
+
break;
|
110
|
+
case 2:
|
111
|
+
outport = argv[0];
|
112
|
+
params = argv[1];
|
113
|
+
predict = Qnil;
|
114
|
+
break;
|
115
|
+
case 3:
|
116
|
+
outport = argv[0];
|
117
|
+
params = argv[1];
|
118
|
+
predict = argv[2];
|
119
|
+
break;
|
120
|
+
default:
|
121
|
+
rb_error_arity(argc, 1, 3);
|
122
|
+
}
|
123
|
+
|
124
|
+
struct encoder *p = getencoder(self);
|
125
|
+
if (p->context) {
|
126
|
+
rb_raise(rb_eTypeError,
|
127
|
+
"initialized already - #<%s:%p>",
|
128
|
+
rb_obj_classname(self), (void *)self);
|
129
|
+
}
|
130
|
+
|
131
|
+
AUX_TRY_WITH_GC(
|
132
|
+
p->context = ZSTD_createCStream(),
|
133
|
+
"failed ZSTD_createCStream()");
|
134
|
+
|
56
135
|
const void *predictp;
|
57
136
|
size_t predictsize;
|
58
137
|
if (NIL_P(predict)) {
|
@@ -60,107 +139,102 @@ enc_init(VALUE self, VALUE params, VALUE predict)
|
|
60
139
|
predictsize = 0;
|
61
140
|
} else {
|
62
141
|
rb_check_type(predict, RUBY_T_STRING);
|
142
|
+
predict = rb_str_new_frozen(predict);
|
63
143
|
RSTRING_GETMEM(predict, predictp, predictsize);
|
64
144
|
}
|
65
145
|
|
66
146
|
if (extzstd_params_p(params)) {
|
67
147
|
ZSTD_parameters *paramsp = extzstd_getparams(params);
|
68
|
-
size_t s = ZSTD_initCStream_advanced(p, predictp, predictsize, *paramsp, 0);
|
148
|
+
size_t s = ZSTD_initCStream_advanced(p->context, predictp, predictsize, *paramsp, 0);
|
69
149
|
extzstd_check_error(s);
|
70
150
|
} else {
|
71
|
-
size_t s = ZSTD_initCStream_usingDict(p, predictp, predictsize, aux_num2int(params, 1));
|
151
|
+
size_t s = ZSTD_initCStream_usingDict(p->context, predictp, predictsize, aux_num2int(params, 1));
|
72
152
|
extzstd_check_error(s);
|
73
153
|
}
|
154
|
+
|
155
|
+
p->predict = predict;
|
156
|
+
p->outport = outport;
|
157
|
+
|
74
158
|
return self;
|
75
159
|
}
|
76
160
|
|
77
161
|
static VALUE
|
78
|
-
|
162
|
+
enc_write(VALUE self, VALUE src)
|
79
163
|
{
|
80
164
|
/*
|
81
165
|
* ZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
|
82
166
|
*/
|
83
167
|
|
84
|
-
|
85
|
-
|
168
|
+
struct encoder *p = encoder_context(self);
|
86
169
|
rb_check_type(src, RUBY_T_STRING);
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
170
|
+
ZSTD_inBuffer input = { RSTRING_PTR(src), RSTRING_LEN(src), 0 };
|
171
|
+
|
172
|
+
while (input.pos < input.size) {
|
173
|
+
p->destbuf = aux_str_buf_recycle(p->destbuf, ZSTD_CStreamOutSize() * 2);
|
174
|
+
rb_str_set_len(p->destbuf, 0);
|
175
|
+
rb_obj_infect(self, src);
|
176
|
+
rb_obj_infect(p->destbuf, self);
|
177
|
+
ZSTD_outBuffer output = { RSTRING_PTR(p->destbuf), rb_str_capacity(p->destbuf), 0 };
|
178
|
+
size_t s = ZSTD_compressStream(p->context, &output, &input);
|
179
|
+
extzstd_check_error(s);
|
180
|
+
rb_str_set_len(p->destbuf, output.pos);
|
95
181
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
rb_str_modify_expand(dest, NUM2SIZET(maxdest));
|
100
|
-
rb_obj_infect(self, src);
|
101
|
-
rb_obj_infect(dest, self);
|
102
|
-
char *r = RSTRING_PTR(dest);
|
103
|
-
const char *rr = r + rb_str_capacity(dest);
|
104
|
-
|
105
|
-
ZSTD_inBuffer input = { q, qq - q, q1 - q };
|
106
|
-
ZSTD_outBuffer output = { r, rr - r, 0 };
|
107
|
-
size_t s = ZSTD_compressStream(p, &output, &input);
|
108
|
-
extzstd_check_error(s);
|
109
|
-
rb_str_set_len(dest, output.pos);
|
110
|
-
if (input.pos == input.size) {
|
111
|
-
return Qnil;
|
112
|
-
} else {
|
113
|
-
return SIZET2NUM(input.pos);
|
182
|
+
// TODO: 例外や帯域脱出した場合の挙動は?
|
183
|
+
// TODO: src の途中経過状態を保存するべきか?
|
184
|
+
AUX_FUNCALL(p->outport, id_op_lsh, p->destbuf);
|
114
185
|
}
|
186
|
+
|
187
|
+
return self;
|
115
188
|
}
|
116
189
|
|
117
190
|
static VALUE
|
118
|
-
|
191
|
+
enc_sync(VALUE self)
|
119
192
|
{
|
120
193
|
/*
|
121
194
|
* ZSTDLIB_API size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
|
122
195
|
*/
|
123
196
|
|
124
|
-
|
197
|
+
struct encoder *p = encoder_context(self);
|
198
|
+
aux_str_buf_recycle(p->destbuf, ZSTD_CStreamOutSize());
|
199
|
+
rb_str_set_len(p->destbuf, 0);
|
200
|
+
rb_obj_infect(p->destbuf, self);
|
201
|
+
ZSTD_outBuffer output = { RSTRING_PTR(p->destbuf), rb_str_capacity(p->destbuf), 0 };
|
202
|
+
size_t s = ZSTD_flushStream(p->context, &output);
|
203
|
+
extzstd_check_error(s);
|
204
|
+
rb_str_set_len(p->destbuf, output.pos);
|
125
205
|
|
126
|
-
|
127
|
-
rb_str_modify(dest);
|
128
|
-
rb_str_set_len(dest, 0);
|
129
|
-
rb_str_modify_expand(dest, NUM2SIZET(maxdest));
|
206
|
+
AUX_FUNCALL(p->outport, id_op_lsh, p->destbuf);
|
130
207
|
|
131
|
-
|
132
|
-
size_t s = ZSTD_flushStream(p, &output);
|
133
|
-
extzstd_check_error(s);
|
134
|
-
if (output.size > 0) {
|
135
|
-
rb_str_set_len(dest, output.pos);
|
136
|
-
return dest;
|
137
|
-
} else {
|
138
|
-
return Qnil;
|
139
|
-
}
|
208
|
+
return self;
|
140
209
|
}
|
141
210
|
|
142
211
|
static VALUE
|
143
|
-
|
212
|
+
enc_close(VALUE self)
|
144
213
|
{
|
145
214
|
/*
|
146
215
|
* ZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
|
147
216
|
*/
|
148
217
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
ZSTD_outBuffer output = { RSTRING_PTR(dest), rb_str_capacity(dest), 0 };
|
156
|
-
size_t s = ZSTD_endStream(p, &output);
|
218
|
+
struct encoder *p = encoder_context(self);
|
219
|
+
aux_str_buf_recycle(p->destbuf, ZSTD_CStreamOutSize());
|
220
|
+
rb_str_set_len(p->destbuf, 0);
|
221
|
+
rb_obj_infect(p->destbuf, self);
|
222
|
+
ZSTD_outBuffer output = { RSTRING_PTR(p->destbuf), rb_str_capacity(p->destbuf), 0 };
|
223
|
+
size_t s = ZSTD_endStream(p->context, &output);
|
157
224
|
extzstd_check_error(s);
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
225
|
+
rb_str_set_len(p->destbuf, output.pos);
|
226
|
+
|
227
|
+
AUX_FUNCALL(p->outport, id_op_lsh, p->destbuf);
|
228
|
+
|
229
|
+
p->reached_eof = 1;
|
230
|
+
|
231
|
+
return Qnil;
|
232
|
+
}
|
233
|
+
|
234
|
+
static VALUE
|
235
|
+
enc_eof(VALUE self)
|
236
|
+
{
|
237
|
+
return (encoder_context(self)->reached_eof == 0 ? Qfalse : Qtrue);
|
164
238
|
}
|
165
239
|
|
166
240
|
static VALUE
|
@@ -170,7 +244,7 @@ enc_reset(VALUE self, VALUE pledged_srcsize)
|
|
170
244
|
* ZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
|
171
245
|
*/
|
172
246
|
|
173
|
-
size_t s = ZSTD_resetCStream(
|
247
|
+
size_t s = ZSTD_resetCStream(encoder_context(self)->context, NUM2ULL(pledged_srcsize));
|
174
248
|
extzstd_check_error(s);
|
175
249
|
return self;
|
176
250
|
}
|
@@ -182,7 +256,7 @@ enc_sizeof(VALUE self)
|
|
182
256
|
* ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
|
183
257
|
*/
|
184
258
|
|
185
|
-
size_t s = ZSTD_sizeof_CStream(
|
259
|
+
size_t s = ZSTD_sizeof_CStream(encoder_context(self)->context);
|
186
260
|
extzstd_check_error(s);
|
187
261
|
return SIZET2NUM(s);
|
188
262
|
}
|
@@ -190,113 +264,293 @@ enc_sizeof(VALUE self)
|
|
190
264
|
static void
|
191
265
|
init_encoder(void)
|
192
266
|
{
|
193
|
-
cStreamEncoder = rb_define_class_under(extzstd_mZstd, "
|
267
|
+
cStreamEncoder = rb_define_class_under(extzstd_mZstd, "Encoder", rb_cObject);
|
194
268
|
rb_define_alloc_func(cStreamEncoder, enc_alloc);
|
195
269
|
rb_define_const(cStreamEncoder, "INSIZE", SIZET2NUM(ZSTD_CStreamInSize()));
|
196
270
|
rb_define_const(cStreamEncoder, "OUTSIZE", SIZET2NUM(ZSTD_CStreamOutSize()));
|
197
|
-
rb_define_method(cStreamEncoder, "initialize", enc_init,
|
198
|
-
rb_define_method(cStreamEncoder, "
|
199
|
-
rb_define_method(cStreamEncoder, "
|
200
|
-
rb_define_method(cStreamEncoder, "
|
271
|
+
rb_define_method(cStreamEncoder, "initialize", enc_init, -1);
|
272
|
+
rb_define_method(cStreamEncoder, "write", enc_write, 1);
|
273
|
+
rb_define_method(cStreamEncoder, "sync", enc_sync, 0);
|
274
|
+
rb_define_method(cStreamEncoder, "close", enc_close, 0);
|
275
|
+
rb_define_method(cStreamEncoder, "eof", enc_eof, 0);
|
276
|
+
rb_define_alias(cStreamEncoder, "eof?", "eof");
|
201
277
|
rb_define_method(cStreamEncoder, "reset", enc_reset, 1);
|
202
278
|
rb_define_method(cStreamEncoder, "sizeof", enc_sizeof, 0);
|
279
|
+
rb_define_alias(cStreamEncoder, "<<", "write");
|
280
|
+
rb_define_alias(cStreamEncoder, "update", "write");
|
281
|
+
rb_define_alias(cStreamEncoder, "flush", "sync");
|
282
|
+
rb_define_alias(cStreamEncoder, "end", "close");
|
283
|
+
rb_define_alias(cStreamEncoder, "finish", "close");
|
203
284
|
}
|
204
285
|
|
205
286
|
/*
|
206
|
-
* class Zstd::
|
287
|
+
* class Zstd::Decoder
|
207
288
|
*/
|
208
289
|
|
209
290
|
static VALUE cStreamDecoder;
|
210
291
|
|
292
|
+
struct decoder
|
293
|
+
{
|
294
|
+
ZSTD_DStream *context;
|
295
|
+
VALUE inport;
|
296
|
+
VALUE readbuf;
|
297
|
+
VALUE predict;
|
298
|
+
ZSTD_inBuffer inbuf;
|
299
|
+
int reached_eof;
|
300
|
+
};
|
301
|
+
|
302
|
+
static void
|
303
|
+
dec_mark(void *pp)
|
304
|
+
{
|
305
|
+
struct decoder *p = (struct decoder *)pp;
|
306
|
+
rb_gc_mark(p->inport);
|
307
|
+
rb_gc_mark(p->readbuf);
|
308
|
+
rb_gc_mark(p->predict);
|
309
|
+
}
|
310
|
+
|
211
311
|
static void
|
212
|
-
dec_free(void *
|
312
|
+
dec_free(void *pp)
|
213
313
|
{
|
214
|
-
|
314
|
+
struct decoder *p = (struct decoder *)pp;
|
315
|
+
if (p->context) {
|
316
|
+
ZSTD_freeDStream(p->context);
|
317
|
+
p->context = NULL;
|
318
|
+
}
|
319
|
+
xfree(p);
|
215
320
|
}
|
216
321
|
|
217
322
|
AUX_IMPLEMENT_CONTEXT(
|
218
|
-
|
219
|
-
decoder_alloc_dummy,
|
323
|
+
struct decoder, decoder_type, "extzstd.Zstd::Decoder",
|
324
|
+
decoder_alloc_dummy, dec_mark, dec_free, NULL,
|
220
325
|
getdecoderp, getdecoder, decoder_p);
|
221
326
|
|
222
|
-
static
|
223
|
-
|
327
|
+
static struct decoder *
|
328
|
+
decoder_context(VALUE self)
|
224
329
|
{
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
p = ZSTD_createDStream();
|
231
|
-
if (!p) {
|
232
|
-
errno = ENOMEM;
|
233
|
-
rb_sys_fail("failed ZSTD_createDStream()");
|
234
|
-
}
|
330
|
+
struct decoder *p = getdecoder(self);
|
331
|
+
if (!p->context) {
|
332
|
+
rb_raise(rb_eTypeError,
|
333
|
+
"uninitialized context - #<%s:%p>",
|
334
|
+
rb_obj_classname(self), (void *)self);
|
235
335
|
}
|
236
|
-
|
336
|
+
return p;
|
337
|
+
}
|
237
338
|
|
339
|
+
static VALUE
|
340
|
+
dec_alloc(VALUE mod)
|
341
|
+
{
|
342
|
+
struct decoder *p;
|
343
|
+
VALUE obj = TypedData_Make_Struct(mod, struct decoder, &decoder_type, p);
|
238
344
|
return obj;
|
239
345
|
}
|
240
346
|
|
241
347
|
/*
|
242
348
|
* call-seq:
|
243
|
-
* initialize(predict)
|
349
|
+
* initialize(inport, predict = Qnil)
|
244
350
|
*/
|
245
351
|
static VALUE
|
246
|
-
dec_init(VALUE
|
352
|
+
dec_init(int argc, VALUE argv[], VALUE self)
|
247
353
|
{
|
248
354
|
/*
|
249
355
|
* ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream* zds);
|
250
356
|
* ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
|
251
357
|
*/
|
252
358
|
|
253
|
-
|
359
|
+
VALUE inport, predict;
|
360
|
+
|
361
|
+
switch (argc) {
|
362
|
+
case 1:
|
363
|
+
inport = argv[0];
|
364
|
+
predict = Qnil;
|
365
|
+
break;
|
366
|
+
case 2:
|
367
|
+
inport = argv[0];
|
368
|
+
predict = argv[1];
|
369
|
+
break;
|
370
|
+
default:
|
371
|
+
rb_error_arity(argc, 1, 2);
|
372
|
+
}
|
373
|
+
|
374
|
+
struct decoder *p = getdecoder(self);
|
375
|
+
if (p->context) {
|
376
|
+
rb_raise(rb_eTypeError,
|
377
|
+
"initialized context already - #<%s:%p>",
|
378
|
+
rb_obj_classname(self), (void *)self);
|
379
|
+
}
|
380
|
+
|
381
|
+
AUX_TRY_WITH_GC(
|
382
|
+
p->context = ZSTD_createDStream(),
|
383
|
+
"failed ZSTD_createDStream()");
|
254
384
|
|
255
385
|
if (NIL_P(predict)) {
|
256
|
-
size_t s = ZSTD_initDStream(p);
|
386
|
+
size_t s = ZSTD_initDStream(p->context);
|
257
387
|
extzstd_check_error(s);
|
258
388
|
} else {
|
259
389
|
rb_check_type(predict, RUBY_T_STRING);
|
260
|
-
|
390
|
+
predict = rb_str_new_frozen(predict);
|
391
|
+
size_t s = ZSTD_initDStream_usingDict(p->context, RSTRING_PTR(predict), RSTRING_LEN(predict));
|
261
392
|
extzstd_check_error(s);
|
262
393
|
}
|
394
|
+
|
395
|
+
p->inport = inport;
|
396
|
+
p->predict = predict;
|
397
|
+
|
263
398
|
return self;
|
264
399
|
}
|
265
400
|
|
401
|
+
static int
|
402
|
+
dec_read_fetch(VALUE o, struct decoder *p)
|
403
|
+
{
|
404
|
+
if (!p->inbuf.src || NIL_P(p->readbuf) || p->inbuf.pos >= RSTRING_LEN(p->readbuf)) {
|
405
|
+
p->readbuf = aux_str_buf_recycle(p->readbuf, EXT_PARTIAL_READ_SIZE);
|
406
|
+
VALUE st = AUX_FUNCALL(p->inport, id_read, INT2FIX(EXT_PARTIAL_READ_SIZE), p->readbuf);
|
407
|
+
if (NIL_P(st)) { return -1; }
|
408
|
+
rb_check_type(st, RUBY_T_STRING);
|
409
|
+
p->readbuf = st;
|
410
|
+
rb_obj_infect(o, p->readbuf);
|
411
|
+
p->inbuf.size = RSTRING_LEN(p->readbuf);
|
412
|
+
p->inbuf.pos = 0;
|
413
|
+
}
|
414
|
+
|
415
|
+
p->inbuf.src = RSTRING_PTR(p->readbuf);
|
416
|
+
|
417
|
+
return 0;
|
418
|
+
}
|
419
|
+
|
420
|
+
static size_t
|
421
|
+
dec_read_decode(VALUE o, struct decoder *p, char *buf, ssize_t size)
|
422
|
+
{
|
423
|
+
if (p->reached_eof != 0) {
|
424
|
+
return 0;
|
425
|
+
}
|
426
|
+
|
427
|
+
ZSTD_outBuffer output = { buf, size, 0 };
|
428
|
+
|
429
|
+
while (size < 0 || output.pos < size) {
|
430
|
+
if (dec_read_fetch(o, p) != 0) {
|
431
|
+
if (p->reached_eof == 0) {
|
432
|
+
rb_raise(rb_eRuntimeError,
|
433
|
+
"unexpected EOF - #<%s:%p>",
|
434
|
+
rb_obj_classname(p->inport), (void *)p->inport);
|
435
|
+
}
|
436
|
+
|
437
|
+
break;
|
438
|
+
}
|
439
|
+
|
440
|
+
rb_thread_check_ints();
|
441
|
+
size_t s = ZSTD_decompressStream(p->context, &output, &p->inbuf);
|
442
|
+
extzstd_check_error(s);
|
443
|
+
if (s == 0) {
|
444
|
+
p->reached_eof = 1;
|
445
|
+
break;
|
446
|
+
}
|
447
|
+
}
|
448
|
+
|
449
|
+
return output.pos;
|
450
|
+
}
|
451
|
+
|
452
|
+
static void
|
453
|
+
dec_read_args(int argc, VALUE argv[], VALUE self, VALUE *buf, ssize_t *size)
|
454
|
+
{
|
455
|
+
switch (argc) {
|
456
|
+
case 0:
|
457
|
+
*size = -1;
|
458
|
+
*buf = rb_str_buf_new(EXT_READ_GROWUP_SIZE);
|
459
|
+
break;
|
460
|
+
case 1:
|
461
|
+
case 2:
|
462
|
+
{
|
463
|
+
if (NIL_P(argv[0])) {
|
464
|
+
*size = -1;
|
465
|
+
|
466
|
+
if (argc == 1) {
|
467
|
+
*buf = rb_str_buf_new(EXT_READ_GROWUP_SIZE);
|
468
|
+
} else {
|
469
|
+
rb_check_type(argv[1], RUBY_T_STRING);
|
470
|
+
*buf = aux_str_modify_expand(argv[1], EXT_READ_GROWUP_SIZE);
|
471
|
+
rb_str_set_len(*buf, 0);
|
472
|
+
}
|
473
|
+
} else {
|
474
|
+
*size = NUM2SIZET(argv[0]);
|
475
|
+
|
476
|
+
if (*size < 0) {
|
477
|
+
rb_raise(rb_eArgError,
|
478
|
+
"``size'' is negative or too large (%"PRIdPTR")",
|
479
|
+
(intptr_t)*size);
|
480
|
+
}
|
481
|
+
|
482
|
+
if (argc == 1) {
|
483
|
+
*buf = rb_str_buf_new(*size);
|
484
|
+
} else {
|
485
|
+
rb_check_type(argv[1], RUBY_T_STRING);
|
486
|
+
*buf = aux_str_modify_expand(argv[1], *size);
|
487
|
+
rb_str_set_len(*buf, 0);
|
488
|
+
}
|
489
|
+
}
|
490
|
+
}
|
491
|
+
break;
|
492
|
+
default:
|
493
|
+
rb_error_arity(argc, 0, 2);
|
494
|
+
}
|
495
|
+
}
|
496
|
+
|
497
|
+
/*
|
498
|
+
* call-seq:
|
499
|
+
* read -> read_data
|
500
|
+
* read(readsize, buf = "".b) -> buf
|
501
|
+
*/
|
266
502
|
static VALUE
|
267
|
-
|
503
|
+
dec_read(int argc, VALUE argv[], VALUE self)
|
268
504
|
{
|
269
505
|
/*
|
270
506
|
* ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
|
271
507
|
*/
|
272
508
|
|
273
|
-
|
509
|
+
ssize_t size;
|
510
|
+
VALUE buf;
|
511
|
+
dec_read_args(argc, argv, self, &buf, &size);
|
274
512
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
513
|
+
struct decoder *p = decoder_context(self);
|
514
|
+
|
515
|
+
if (size == 0) {
|
516
|
+
rb_str_set_len(buf, 0);
|
517
|
+
return buf;
|
518
|
+
} else if (size > 0) {
|
519
|
+
size = dec_read_decode(self, p, RSTRING_PTR(buf), size);
|
520
|
+
rb_str_set_len(buf, size);
|
521
|
+
} else {
|
522
|
+
/* if (size < 0) */
|
523
|
+
|
524
|
+
size_t capa = EXT_READ_GROWUP_SIZE;
|
525
|
+
|
526
|
+
for (;;) {
|
527
|
+
aux_str_modify_expand(buf, capa);
|
528
|
+
size = dec_read_decode(self, p, RSTRING_PTR(buf) + RSTRING_LEN(buf), capa - RSTRING_LEN(buf));
|
529
|
+
rb_str_set_len(buf, RSTRING_LEN(buf) + size);
|
530
|
+
if (size == 0) { break; }
|
531
|
+
size = rb_str_capacity(buf);
|
532
|
+
if (size > RSTRING_LEN(buf)) { break; }
|
533
|
+
if (size > EXT_READ_DOUBLE_GROWUP_LIMIT_SIZE) {
|
534
|
+
capa += EXT_READ_DOUBLE_GROWUP_LIMIT_SIZE;
|
535
|
+
} else {
|
536
|
+
capa *= 2;
|
537
|
+
}
|
538
|
+
}
|
283
539
|
}
|
284
540
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
rb_str_set_len(dest, output.pos);
|
299
|
-
return SIZET2NUM(input.pos);
|
541
|
+
rb_obj_infect(buf, self);
|
542
|
+
|
543
|
+
if (RSTRING_LEN(buf) == 0) {
|
544
|
+
return Qnil;
|
545
|
+
} else {
|
546
|
+
return buf;
|
547
|
+
}
|
548
|
+
}
|
549
|
+
|
550
|
+
static VALUE
|
551
|
+
dec_eof(VALUE self)
|
552
|
+
{
|
553
|
+
return (decoder_context(self)->reached_eof == 0 ? Qfalse : Qtrue);
|
300
554
|
}
|
301
555
|
|
302
556
|
static VALUE
|
@@ -305,7 +559,7 @@ dec_reset(VALUE self)
|
|
305
559
|
/*
|
306
560
|
* ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);
|
307
561
|
*/
|
308
|
-
size_t s = ZSTD_resetDStream(
|
562
|
+
size_t s = ZSTD_resetDStream(decoder_context(self)->context);
|
309
563
|
extzstd_check_error(s);
|
310
564
|
return self;
|
311
565
|
}
|
@@ -317,7 +571,7 @@ dec_sizeof(VALUE self)
|
|
317
571
|
* ZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
|
318
572
|
*/
|
319
573
|
|
320
|
-
size_t s = ZSTD_sizeof_DStream(
|
574
|
+
size_t s = ZSTD_sizeof_DStream(decoder_context(self)->context);
|
321
575
|
extzstd_check_error(s);
|
322
576
|
return SIZET2NUM(s);
|
323
577
|
}
|
@@ -325,12 +579,14 @@ dec_sizeof(VALUE self)
|
|
325
579
|
static void
|
326
580
|
init_decoder(void)
|
327
581
|
{
|
328
|
-
cStreamDecoder = rb_define_class_under(extzstd_mZstd, "
|
582
|
+
cStreamDecoder = rb_define_class_under(extzstd_mZstd, "Decoder", rb_cObject);
|
329
583
|
rb_define_alloc_func(cStreamDecoder, dec_alloc);
|
330
584
|
rb_define_const(cStreamDecoder, "INSIZE", SIZET2NUM(ZSTD_DStreamInSize()));
|
331
585
|
rb_define_const(cStreamDecoder, "OUTSIZE", SIZET2NUM(ZSTD_DStreamOutSize()));
|
332
|
-
rb_define_method(cStreamDecoder, "initialize", dec_init, 1);
|
333
|
-
rb_define_method(cStreamDecoder, "
|
586
|
+
rb_define_method(cStreamDecoder, "initialize", dec_init, -1);
|
587
|
+
rb_define_method(cStreamDecoder, "read", dec_read, -1);
|
588
|
+
rb_define_method(cStreamDecoder, "eof", dec_eof, 0);
|
589
|
+
rb_define_alias(cStreamDecoder, "eof?", "eof");
|
334
590
|
rb_define_method(cStreamDecoder, "reset", dec_reset, 0);
|
335
591
|
rb_define_method(cStreamDecoder, "sizeof", dec_sizeof, 0);
|
336
592
|
}
|
@@ -342,6 +598,9 @@ init_decoder(void)
|
|
342
598
|
void
|
343
599
|
extzstd_init_stream(void)
|
344
600
|
{
|
601
|
+
id_op_lsh = rb_intern("<<");
|
602
|
+
id_read = rb_intern("read");
|
603
|
+
|
345
604
|
init_encoder();
|
346
605
|
init_decoder();
|
347
606
|
}
|