extzstd 0.1.1 → 0.2
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 +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
|
}
|