extzstd 0.1 → 0.3.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 +39 -0
- data/README.md +38 -56
- data/contrib/zstd/CHANGELOG +613 -0
- data/contrib/zstd/CODE_OF_CONDUCT.md +5 -0
- data/contrib/zstd/CONTRIBUTING.md +406 -0
- data/contrib/zstd/COPYING +339 -0
- data/contrib/zstd/Makefile +420 -0
- data/contrib/zstd/README.md +179 -41
- data/contrib/zstd/TESTING.md +44 -0
- data/contrib/zstd/appveyor.yml +292 -0
- data/contrib/zstd/lib/BUCK +234 -0
- data/contrib/zstd/lib/Makefile +451 -0
- data/contrib/zstd/lib/README.md +207 -0
- data/contrib/zstd/{common → lib/common}/bitstream.h +187 -138
- data/contrib/zstd/lib/common/compiler.h +288 -0
- data/contrib/zstd/lib/common/cpu.h +213 -0
- data/contrib/zstd/lib/common/debug.c +24 -0
- data/contrib/zstd/lib/common/debug.h +107 -0
- data/contrib/zstd/lib/common/entropy_common.c +362 -0
- data/contrib/zstd/{common → lib/common}/error_private.c +25 -12
- data/contrib/zstd/{common → lib/common}/error_private.h +14 -10
- data/contrib/zstd/{common → lib/common}/fse.h +173 -92
- data/contrib/zstd/{common → lib/common}/fse_decompress.c +149 -85
- data/contrib/zstd/lib/common/huf.h +361 -0
- data/contrib/zstd/{common → lib/common}/mem.h +115 -59
- data/contrib/zstd/lib/common/pool.c +350 -0
- data/contrib/zstd/lib/common/pool.h +84 -0
- data/contrib/zstd/lib/common/threading.c +122 -0
- data/contrib/zstd/lib/common/threading.h +155 -0
- data/contrib/zstd/{common → lib/common}/xxhash.c +55 -96
- data/contrib/zstd/{common → lib/common}/xxhash.h +23 -47
- data/contrib/zstd/lib/common/zstd_common.c +83 -0
- data/contrib/zstd/lib/common/zstd_deps.h +111 -0
- data/contrib/zstd/lib/common/zstd_errors.h +95 -0
- data/contrib/zstd/lib/common/zstd_internal.h +478 -0
- data/contrib/zstd/{compress → lib/compress}/fse_compress.c +214 -319
- data/contrib/zstd/lib/compress/hist.c +181 -0
- data/contrib/zstd/lib/compress/hist.h +75 -0
- data/contrib/zstd/lib/compress/huf_compress.c +913 -0
- data/contrib/zstd/lib/compress/zstd_compress.c +5208 -0
- data/contrib/zstd/lib/compress/zstd_compress_internal.h +1203 -0
- data/contrib/zstd/lib/compress/zstd_compress_literals.c +158 -0
- data/contrib/zstd/lib/compress/zstd_compress_literals.h +29 -0
- data/contrib/zstd/lib/compress/zstd_compress_sequences.c +433 -0
- data/contrib/zstd/lib/compress/zstd_compress_sequences.h +54 -0
- data/contrib/zstd/lib/compress/zstd_compress_superblock.c +849 -0
- data/contrib/zstd/lib/compress/zstd_compress_superblock.h +32 -0
- data/contrib/zstd/lib/compress/zstd_cwksp.h +561 -0
- data/contrib/zstd/lib/compress/zstd_double_fast.c +521 -0
- data/contrib/zstd/lib/compress/zstd_double_fast.h +38 -0
- data/contrib/zstd/lib/compress/zstd_fast.c +496 -0
- data/contrib/zstd/lib/compress/zstd_fast.h +37 -0
- data/contrib/zstd/lib/compress/zstd_lazy.c +1412 -0
- data/contrib/zstd/lib/compress/zstd_lazy.h +87 -0
- data/contrib/zstd/lib/compress/zstd_ldm.c +660 -0
- data/contrib/zstd/lib/compress/zstd_ldm.h +116 -0
- data/contrib/zstd/lib/compress/zstd_opt.c +1345 -0
- data/contrib/zstd/lib/compress/zstd_opt.h +56 -0
- data/contrib/zstd/lib/compress/zstdmt_compress.c +1811 -0
- data/contrib/zstd/lib/compress/zstdmt_compress.h +110 -0
- data/contrib/zstd/lib/decompress/huf_decompress.c +1350 -0
- data/contrib/zstd/lib/decompress/zstd_ddict.c +244 -0
- data/contrib/zstd/lib/decompress/zstd_ddict.h +44 -0
- data/contrib/zstd/lib/decompress/zstd_decompress.c +1930 -0
- data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1540 -0
- data/contrib/zstd/lib/decompress/zstd_decompress_block.h +62 -0
- data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +190 -0
- data/contrib/zstd/{common → lib/deprecated}/zbuff.h +68 -45
- data/contrib/zstd/lib/deprecated/zbuff_common.c +26 -0
- data/contrib/zstd/lib/deprecated/zbuff_compress.c +147 -0
- data/contrib/zstd/lib/deprecated/zbuff_decompress.c +75 -0
- data/contrib/zstd/lib/dictBuilder/cover.c +1245 -0
- data/contrib/zstd/lib/dictBuilder/cover.h +157 -0
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.c +3 -3
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.h +0 -0
- data/contrib/zstd/lib/dictBuilder/fastcover.c +758 -0
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/zdict.c +318 -194
- data/contrib/zstd/lib/dictBuilder/zdict.h +305 -0
- data/contrib/zstd/{legacy → lib/legacy}/zstd_legacy.h +171 -15
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.c +191 -124
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.h +19 -5
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.c +125 -125
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.h +19 -5
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.c +125 -124
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.h +20 -6
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.c +151 -299
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.h +19 -5
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.c +237 -243
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.h +19 -6
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.c +130 -143
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.h +18 -5
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v07.c +158 -157
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v07.h +19 -5
- data/contrib/zstd/lib/libzstd.pc.in +15 -0
- data/contrib/zstd/lib/zstd.h +2391 -0
- data/ext/depend +2 -0
- data/ext/extconf.rb +15 -6
- data/ext/extzstd.c +76 -145
- data/ext/extzstd.h +80 -31
- data/ext/extzstd_stream.c +417 -142
- data/ext/libzstd_conf.h +8 -0
- data/ext/zstd_common.c +10 -7
- data/ext/zstd_compress.c +14 -5
- data/ext/zstd_decompress.c +5 -4
- data/ext/zstd_dictbuilder.c +9 -4
- data/ext/zstd_dictbuilder_fastcover.c +3 -0
- data/ext/zstd_legacy_v01.c +3 -1
- data/ext/zstd_legacy_v02.c +3 -1
- data/ext/zstd_legacy_v03.c +3 -1
- data/ext/zstd_legacy_v04.c +3 -1
- data/ext/zstd_legacy_v05.c +3 -1
- data/ext/zstd_legacy_v06.c +3 -1
- data/ext/zstd_legacy_v07.c +3 -1
- data/gemstub.rb +10 -24
- data/lib/extzstd.rb +64 -179
- data/lib/extzstd/version.rb +6 -1
- data/test/test_basic.rb +9 -6
- metadata +113 -57
- data/HISTORY.ja +0 -5
- data/contrib/zstd/common/entropy_common.c +0 -225
- data/contrib/zstd/common/huf.h +0 -228
- data/contrib/zstd/common/zstd_common.c +0 -83
- data/contrib/zstd/common/zstd_errors.h +0 -60
- data/contrib/zstd/common/zstd_internal.h +0 -267
- data/contrib/zstd/compress/huf_compress.c +0 -533
- data/contrib/zstd/compress/zbuff_compress.c +0 -319
- data/contrib/zstd/compress/zstd_compress.c +0 -3264
- data/contrib/zstd/compress/zstd_opt.h +0 -900
- data/contrib/zstd/decompress/huf_decompress.c +0 -883
- data/contrib/zstd/decompress/zbuff_decompress.c +0 -252
- data/contrib/zstd/decompress/zstd_decompress.c +0 -1842
- data/contrib/zstd/dictBuilder/zdict.h +0 -111
- data/contrib/zstd/zstd.h +0 -640
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,
|
148
|
+
size_t s = ZSTD_initCStream_advanced(p->context, predictp, predictsize, *paramsp, -1);
|
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
|
-
|
168
|
+
struct encoder *p = encoder_context(self);
|
169
|
+
src = rb_String(src);
|
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);
|
85
181
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
const char *q1 = q + NUM2SIZET(srcoff);
|
90
|
-
if (q1 < q || q1 > qq) {
|
91
|
-
rb_raise(rb_eArgError,
|
92
|
-
"``srcoff'' is out of range (given %"PRIuSIZE", expect 0..%"PRIuSIZE")",
|
93
|
-
q1 - q, qq - q);
|
182
|
+
// TODO: 例外や帯域脱出した場合の挙動は?
|
183
|
+
// TODO: src の途中経過状態を保存するべきか?
|
184
|
+
AUX_FUNCALL(p->outport, id_op_lsh, p->destbuf);
|
94
185
|
}
|
95
186
|
|
96
|
-
|
97
|
-
rb_str_modify(dest);
|
98
|
-
rb_str_set_len(dest, 0);
|
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);
|
114
|
-
}
|
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,300 @@ 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
|
+
|
211
302
|
static void
|
212
|
-
|
303
|
+
dec_mark(void *pp)
|
213
304
|
{
|
214
|
-
|
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
|
+
|
311
|
+
static void
|
312
|
+
dec_free(void *pp)
|
313
|
+
{
|
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 || NIL_P(argv[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 || NIL_P(argv[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);
|
512
|
+
|
513
|
+
struct decoder *p = decoder_context(self);
|
274
514
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
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
|
-
|
299
|
-
|
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);
|
554
|
+
}
|
555
|
+
|
556
|
+
static VALUE
|
557
|
+
dec_close(VALUE self)
|
558
|
+
{
|
559
|
+
decoder_context(self)->reached_eof = 1;
|
560
|
+
return Qnil;
|
300
561
|
}
|
301
562
|
|
302
563
|
static VALUE
|
@@ -305,7 +566,7 @@ dec_reset(VALUE self)
|
|
305
566
|
/*
|
306
567
|
* ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);
|
307
568
|
*/
|
308
|
-
size_t s = ZSTD_resetDStream(
|
569
|
+
size_t s = ZSTD_resetDStream(decoder_context(self)->context);
|
309
570
|
extzstd_check_error(s);
|
310
571
|
return self;
|
311
572
|
}
|
@@ -317,22 +578,33 @@ dec_sizeof(VALUE self)
|
|
317
578
|
* ZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
|
318
579
|
*/
|
319
580
|
|
320
|
-
size_t s = ZSTD_sizeof_DStream(
|
581
|
+
size_t s = ZSTD_sizeof_DStream(decoder_context(self)->context);
|
321
582
|
extzstd_check_error(s);
|
322
583
|
return SIZET2NUM(s);
|
323
584
|
}
|
324
585
|
|
586
|
+
static VALUE
|
587
|
+
dec_pos(VALUE self)
|
588
|
+
{
|
589
|
+
decoder_context(self); /* check only */
|
590
|
+
return INT2FIX(0);
|
591
|
+
}
|
592
|
+
|
325
593
|
static void
|
326
594
|
init_decoder(void)
|
327
595
|
{
|
328
|
-
cStreamDecoder = rb_define_class_under(extzstd_mZstd, "
|
596
|
+
cStreamDecoder = rb_define_class_under(extzstd_mZstd, "Decoder", rb_cObject);
|
329
597
|
rb_define_alloc_func(cStreamDecoder, dec_alloc);
|
330
598
|
rb_define_const(cStreamDecoder, "INSIZE", SIZET2NUM(ZSTD_DStreamInSize()));
|
331
599
|
rb_define_const(cStreamDecoder, "OUTSIZE", SIZET2NUM(ZSTD_DStreamOutSize()));
|
332
|
-
rb_define_method(cStreamDecoder, "initialize", dec_init, 1);
|
333
|
-
rb_define_method(cStreamDecoder, "
|
600
|
+
rb_define_method(cStreamDecoder, "initialize", dec_init, -1);
|
601
|
+
rb_define_method(cStreamDecoder, "read", dec_read, -1);
|
602
|
+
rb_define_method(cStreamDecoder, "eof", dec_eof, 0);
|
603
|
+
rb_define_alias(cStreamDecoder, "eof?", "eof");
|
604
|
+
rb_define_method(cStreamDecoder, "close", dec_close, 0);
|
334
605
|
rb_define_method(cStreamDecoder, "reset", dec_reset, 0);
|
335
606
|
rb_define_method(cStreamDecoder, "sizeof", dec_sizeof, 0);
|
607
|
+
rb_define_method(cStreamDecoder, "pos", dec_pos, 0);
|
336
608
|
}
|
337
609
|
|
338
610
|
/*
|
@@ -342,6 +614,9 @@ init_decoder(void)
|
|
342
614
|
void
|
343
615
|
extzstd_init_stream(void)
|
344
616
|
{
|
617
|
+
id_op_lsh = rb_intern("<<");
|
618
|
+
id_read = rb_intern("read");
|
619
|
+
|
345
620
|
init_encoder();
|
346
621
|
init_decoder();
|
347
622
|
}
|