zstd-ruby 2.0.0 → 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/ext/zstdruby/streaming_compress.c +13 -12
- data/ext/zstdruby/streaming_decompress.c +9 -2
- data/ext/zstdruby/zstdruby.c +70 -40
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91a2e54ff93b0c602d6b2d064f6f8c615a59f0ef963c20b24e4db6d17643163e
|
4
|
+
data.tar.gz: cbeb4c7c21187336a284cb714765fb80b02b982c6b4fafa60784d8f7950fe528
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70190b1a1233782dc440e5ef913f4a83b6bc936ea96d744f5a44b3dbceb41f8a1ef9c3264746eb251356b95c13c5503b2b2567076bc45c28d628ee278b9c2522
|
7
|
+
data.tar.gz: 600bc166bef41126b93a0e78190bbf6b5698259797e166ee4d787a113d6c4e27e7c6c927135e54b33a7e4cc25a74b2df4cb19413f74618892191863cc4c9b4fb
|
@@ -105,13 +105,13 @@ static VALUE
|
|
105
105
|
no_compress(struct streaming_compress_t* sc, ZSTD_EndDirective endOp)
|
106
106
|
{
|
107
107
|
ZSTD_inBuffer input = { NULL, 0, 0 };
|
108
|
-
const char* output_data = RSTRING_PTR(sc->buf);
|
109
108
|
VALUE result = rb_str_new(0, 0);
|
110
109
|
size_t ret;
|
111
110
|
do {
|
111
|
+
const char* output_data = RSTRING_PTR(sc->buf);
|
112
112
|
ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
|
113
113
|
|
114
|
-
|
114
|
+
ret = zstd_stream_compress(sc->ctx, &output, &input, endOp, false);
|
115
115
|
if (ZSTD_isError(ret)) {
|
116
116
|
rb_raise(rb_eRuntimeError, "flush error error code: %s", ZSTD_getErrorName(ret));
|
117
117
|
}
|
@@ -131,9 +131,9 @@ rb_streaming_compress_compress(VALUE obj, VALUE src)
|
|
131
131
|
struct streaming_compress_t* sc;
|
132
132
|
TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
|
133
133
|
|
134
|
-
const char* output_data = RSTRING_PTR(sc->buf);
|
135
134
|
VALUE result = rb_str_new(0, 0);
|
136
135
|
while (input.pos < input.size) {
|
136
|
+
const char* output_data = RSTRING_PTR(sc->buf);
|
137
137
|
ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
|
138
138
|
size_t const ret = zstd_stream_compress(sc->ctx, &output, &input, ZSTD_e_continue, false);
|
139
139
|
if (ZSTD_isError(ret)) {
|
@@ -150,7 +150,6 @@ rb_streaming_compress_write(int argc, VALUE *argv, VALUE obj)
|
|
150
150
|
size_t total = 0;
|
151
151
|
struct streaming_compress_t* sc;
|
152
152
|
TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
|
153
|
-
const char* output_data = RSTRING_PTR(sc->buf);
|
154
153
|
|
155
154
|
while (argc-- > 0) {
|
156
155
|
VALUE str = *argv++;
|
@@ -160,18 +159,20 @@ rb_streaming_compress_write(int argc, VALUE *argv, VALUE obj)
|
|
160
159
|
ZSTD_inBuffer input = { input_data, input_size, 0 };
|
161
160
|
|
162
161
|
while (input.pos < input.size) {
|
162
|
+
const char* output_data = RSTRING_PTR(sc->buf);
|
163
163
|
ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
|
164
164
|
size_t const ret = zstd_stream_compress(sc->ctx, &output, &input, ZSTD_e_continue, false);
|
165
165
|
if (ZSTD_isError(ret)) {
|
166
166
|
rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(ret));
|
167
167
|
}
|
168
|
-
/*
|
168
|
+
/* Directly append to the pending buffer */
|
169
169
|
if (output.pos > 0) {
|
170
170
|
rb_str_cat(sc->pending, output.dst, output.pos);
|
171
171
|
}
|
172
|
-
total += RSTRING_LEN(str);
|
173
172
|
}
|
173
|
+
total += RSTRING_LEN(str);
|
174
174
|
}
|
175
|
+
|
175
176
|
return SIZET2NUM(total);
|
176
177
|
}
|
177
178
|
|
@@ -202,9 +203,9 @@ rb_streaming_compress_flush(VALUE obj)
|
|
202
203
|
struct streaming_compress_t* sc;
|
203
204
|
TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
|
204
205
|
VALUE drained = no_compress(sc, ZSTD_e_flush);
|
205
|
-
|
206
|
-
|
207
|
-
sc->pending
|
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);
|
208
209
|
return out;
|
209
210
|
}
|
210
211
|
|
@@ -214,9 +215,9 @@ rb_streaming_compress_finish(VALUE obj)
|
|
214
215
|
struct streaming_compress_t* sc;
|
215
216
|
TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
|
216
217
|
VALUE drained = no_compress(sc, ZSTD_e_end);
|
217
|
-
|
218
|
-
|
219
|
-
sc->pending
|
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);
|
220
221
|
return out;
|
221
222
|
}
|
222
223
|
|
@@ -100,15 +100,22 @@ 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
|
}
|
data/ext/zstdruby/zstdruby.c
CHANGED
@@ -39,61 +39,91 @@ static VALUE rb_compress(int argc, VALUE *argv, VALUE self)
|
|
39
39
|
return output;
|
40
40
|
}
|
41
41
|
|
42
|
-
static VALUE
|
43
|
-
|
44
|
-
|
45
|
-
|
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 };
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
output.size += ZSTD_DStreamOutSize();
|
50
|
-
VALUE output_string = rb_str_new(NULL, output.size);
|
51
|
-
output.dst = RSTRING_PTR(output_string);
|
48
|
+
ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only);
|
49
|
+
set_decompress_params(dctx, kwargs);
|
52
50
|
|
53
|
-
|
51
|
+
for (;;) {
|
52
|
+
ZSTD_outBuffer o = (ZSTD_outBuffer){ buf, cap, 0 };
|
53
|
+
size_t ret = ZSTD_decompressStream(dctx, &o, &in);
|
54
54
|
if (ZSTD_isError(ret)) {
|
55
|
-
|
56
|
-
rb_raise(rb_eRuntimeError, "
|
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;
|
57
63
|
}
|
58
|
-
rb_str_cat(result, output.dst, output.pos);
|
59
64
|
}
|
60
|
-
|
61
|
-
return
|
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);
|
62
71
|
}
|
63
72
|
|
64
73
|
static VALUE rb_decompress(int argc, VALUE *argv, VALUE self)
|
65
74
|
{
|
66
|
-
VALUE input_value;
|
67
|
-
VALUE kwargs;
|
75
|
+
VALUE input_value, kwargs;
|
68
76
|
rb_scan_args(argc, argv, "10:", &input_value, &kwargs);
|
69
77
|
StringValue(input_value);
|
70
|
-
char* input_data = RSTRING_PTR(input_value);
|
71
|
-
size_t input_size = RSTRING_LEN(input_value);
|
72
|
-
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
|
73
|
-
if (dctx == NULL) {
|
74
|
-
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDCtx failed");
|
75
|
-
}
|
76
|
-
set_decompress_params(dctx, kwargs);
|
77
78
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
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
|
+
}
|
87
105
|
|
88
|
-
|
89
|
-
|
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
|
+
}
|
112
|
+
|
113
|
+
VALUE out = decode_one_frame(dctx, in + off, in_size - off, kwargs);
|
90
114
|
|
91
|
-
|
92
|
-
|
93
|
-
|
115
|
+
ZSTD_freeDCtx(dctx);
|
116
|
+
xfree(in);
|
117
|
+
RB_GC_GUARD(input_value);
|
118
|
+
return out;
|
119
|
+
}
|
120
|
+
|
121
|
+
off += 1;
|
94
122
|
}
|
95
|
-
|
96
|
-
|
123
|
+
|
124
|
+
xfree(in);
|
125
|
+
RB_GC_GUARD(input_value);
|
126
|
+
rb_raise(rb_eRuntimeError, "not a zstd frame (magic not found)");
|
97
127
|
}
|
98
128
|
|
99
129
|
static void free_cdict(void *dict)
|
data/lib/zstd-ruby/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zstd-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SpringMT
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-09-
|
10
|
+
date: 2025-09-29 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: bundler
|