zstd-ruby 1.5.6.0 → 1.5.6.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 +4 -4
- data/README.md +41 -10
- data/ext/zstdruby/common.h +52 -1
- data/ext/zstdruby/main.c +2 -1
- data/ext/zstdruby/skippable_frame.c +1 -1
- data/ext/zstdruby/streaming_compress.c +53 -21
- data/ext/zstdruby/streaming_decompress.c +19 -38
- data/ext/zstdruby/zstdruby.c +38 -18
- data/lib/zstd-ruby/stream_reader.rb +22 -0
- data/lib/zstd-ruby/stream_writer.rb +23 -0
- data/lib/zstd-ruby/version.rb +1 -1
- data/renovate.json +6 -0
- data/zstd-ruby.gemspec +2 -1
- metadata +20 -4
- data/ext/zstdruby/streaming_compress.h +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c50aade1eb5c3a36dfaba5dc325c1bc416ceaa3558539ae5b389bb4378f6c37
|
4
|
+
data.tar.gz: 490b1268c79f5e481969fb1cf2fe2adb9bba5a51ab0e0197fd0338913a228611
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14db577b5e10bc3a92df632d391dfdb55802da3768e5b829c9b849f440b0b5234be8d924a6b0c5d237cab7befdd540d1535de0ba56dafd30fbfe13c2e635e229
|
7
|
+
data.tar.gz: e6959f0da13aaa2a609fec024a3f293e4366760e3efd7626fc545c29ad5a1b0290119bc088cf60cb6665c1f2a5d93f0faf72152be3cf470ce5cf43657695a588
|
data/README.md
CHANGED
@@ -10,7 +10,7 @@ See https://github.com/facebook/zstd
|
|
10
10
|
Fork from https://github.com/jarredholman/ruby-zstd.
|
11
11
|
|
12
12
|
## Zstd version
|
13
|
-
v1.5.
|
13
|
+
[v1.5.6](https://github.com/facebook/zstd/tree/v1.5.6)
|
14
14
|
|
15
15
|
## Installation
|
16
16
|
|
@@ -34,20 +34,22 @@ Or install it yourself as:
|
|
34
34
|
require 'zstd-ruby'
|
35
35
|
```
|
36
36
|
|
37
|
-
###
|
37
|
+
### Compression
|
38
|
+
|
39
|
+
#### Simple Compression
|
38
40
|
|
39
41
|
```ruby
|
40
42
|
compressed_data = Zstd.compress(data)
|
41
|
-
compressed_data = Zstd.compress(data, complession_level) # default compression_level is
|
43
|
+
compressed_data = Zstd.compress(data, level: complession_level) # default compression_level is 3
|
42
44
|
```
|
43
45
|
|
44
|
-
|
46
|
+
#### Compression with Dictionary
|
45
47
|
```ruby
|
46
48
|
# dictionary is supposed to have been created using `zstd --train`
|
47
|
-
compressed_using_dict = Zstd.
|
49
|
+
compressed_using_dict = Zstd.compress("", dict: File.read('dictionary_file'))
|
48
50
|
```
|
49
51
|
|
50
|
-
|
52
|
+
#### Streaming Compression
|
51
53
|
```ruby
|
52
54
|
stream = Zstd::StreamingCompress.new
|
53
55
|
stream << "abc" << "def"
|
@@ -66,19 +68,39 @@ res << stream.compress("def")
|
|
66
68
|
res << stream.finish
|
67
69
|
```
|
68
70
|
|
69
|
-
|
71
|
+
#### Streaming Compression with Dictionary
|
72
|
+
```ruby
|
73
|
+
stream = Zstd::StreamingCompress.new(dict: File.read('dictionary_file'))
|
74
|
+
stream << "abc" << "def"
|
75
|
+
res = stream.flush
|
76
|
+
stream << "ghi"
|
77
|
+
res << stream.finish
|
78
|
+
```
|
79
|
+
|
80
|
+
#### Streaming Compression with level and Dictionary
|
81
|
+
```ruby
|
82
|
+
stream = Zstd::StreamingCompress.new(level: 5, dict: File.read('dictionary_file'))
|
83
|
+
stream << "abc" << "def"
|
84
|
+
res = stream.flush
|
85
|
+
stream << "ghi"
|
86
|
+
res << stream.finish
|
87
|
+
```
|
88
|
+
|
89
|
+
### Decompression
|
90
|
+
|
91
|
+
#### Simple Decompression
|
70
92
|
|
71
93
|
```ruby
|
72
94
|
data = Zstd.decompress(compressed_data)
|
73
95
|
```
|
74
96
|
|
75
|
-
|
97
|
+
#### Decompression with Dictionary
|
76
98
|
```ruby
|
77
99
|
# dictionary is supposed to have been created using `zstd --train`
|
78
|
-
Zstd.
|
100
|
+
Zstd.decompress(compressed_using_dict, dict: File.read('dictionary_file'))
|
79
101
|
```
|
80
102
|
|
81
|
-
|
103
|
+
#### Streaming Decompression
|
82
104
|
```ruby
|
83
105
|
cstr = "" # Compressed data
|
84
106
|
stream = Zstd::StreamingDecompress.new
|
@@ -87,6 +109,15 @@ result << stream.decompress(cstr[0, 10])
|
|
87
109
|
result << stream.decompress(cstr[10..-1])
|
88
110
|
```
|
89
111
|
|
112
|
+
#### Streaming Decompression with dictionary
|
113
|
+
```ruby
|
114
|
+
cstr = "" # Compressed data
|
115
|
+
stream = Zstd::StreamingDecompress.new(dict: File.read('dictionary_file'))
|
116
|
+
result = ''
|
117
|
+
result << stream.decompress(cstr[0, 10])
|
118
|
+
result << stream.decompress(cstr[10..-1])
|
119
|
+
```
|
120
|
+
|
90
121
|
### Skippable frame
|
91
122
|
|
92
123
|
```ruby
|
data/ext/zstdruby/common.h
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#ifndef ZSTD_RUBY_H
|
2
2
|
#define ZSTD_RUBY_H 1
|
3
3
|
|
4
|
-
#include
|
4
|
+
#include <ruby.h>
|
5
5
|
#include "./libzstd/zstd.h"
|
6
6
|
|
7
7
|
static int convert_compression_level(VALUE compression_level_value)
|
@@ -12,4 +12,55 @@ static int convert_compression_level(VALUE compression_level_value)
|
|
12
12
|
return NUM2INT(compression_level_value);
|
13
13
|
}
|
14
14
|
|
15
|
+
static size_t zstd_compress(ZSTD_CCtx* const ctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input, ZSTD_EndDirective endOp)
|
16
|
+
{
|
17
|
+
return ZSTD_compressStream2(ctx, output, input, endOp);
|
18
|
+
}
|
19
|
+
|
20
|
+
static void set_compress_params(ZSTD_CCtx* const ctx, VALUE level_from_args, VALUE kwargs)
|
21
|
+
{
|
22
|
+
ID kwargs_keys[2];
|
23
|
+
kwargs_keys[0] = rb_intern("level");
|
24
|
+
kwargs_keys[1] = rb_intern("dict");
|
25
|
+
VALUE kwargs_values[2];
|
26
|
+
rb_get_kwargs(kwargs, kwargs_keys, 0, 2, kwargs_values);
|
27
|
+
|
28
|
+
int compression_level = ZSTD_CLEVEL_DEFAULT;
|
29
|
+
if (kwargs_values[0] != Qundef && kwargs_values[0] != Qnil) {
|
30
|
+
compression_level = convert_compression_level(kwargs_values[0]);
|
31
|
+
} else if (!NIL_P(level_from_args)) {
|
32
|
+
rb_warn("`level` in args is deprecated; use keyword args `level:` instead.");
|
33
|
+
compression_level = convert_compression_level(level_from_args);
|
34
|
+
}
|
35
|
+
ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, compression_level);
|
36
|
+
|
37
|
+
if (kwargs_values[1] != Qundef && kwargs_values[1] != Qnil) {
|
38
|
+
char* dict_buffer = RSTRING_PTR(kwargs_values[1]);
|
39
|
+
size_t dict_size = RSTRING_LEN(kwargs_values[1]);
|
40
|
+
size_t load_dict_ret = ZSTD_CCtx_loadDictionary(ctx, dict_buffer, dict_size);
|
41
|
+
if (ZSTD_isError(load_dict_ret)) {
|
42
|
+
ZSTD_freeCCtx(ctx);
|
43
|
+
rb_raise(rb_eRuntimeError, "%s", "ZSTD_CCtx_loadDictionary failed");
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
static void set_decompress_params(ZSTD_DCtx* const dctx, VALUE kwargs)
|
49
|
+
{
|
50
|
+
ID kwargs_keys[1];
|
51
|
+
kwargs_keys[0] = rb_intern("dict");
|
52
|
+
VALUE kwargs_values[1];
|
53
|
+
rb_get_kwargs(kwargs, kwargs_keys, 0, 1, kwargs_values);
|
54
|
+
|
55
|
+
if (kwargs_values[0] != Qundef && kwargs_values[0] != Qnil) {
|
56
|
+
char* dict_buffer = RSTRING_PTR(kwargs_values[0]);
|
57
|
+
size_t dict_size = RSTRING_LEN(kwargs_values[0]);
|
58
|
+
size_t load_dict_ret = ZSTD_DCtx_loadDictionary(dctx, dict_buffer, dict_size);
|
59
|
+
if (ZSTD_isError(load_dict_ret)) {
|
60
|
+
ZSTD_freeDCtx(dctx);
|
61
|
+
rb_raise(rb_eRuntimeError, "%s", "ZSTD_CCtx_loadDictionary failed");
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
15
66
|
#endif /* ZSTD_RUBY_H */
|
data/ext/zstdruby/main.c
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
#include
|
2
|
-
#include <streaming_compress.h>
|
1
|
+
#include "common.h"
|
3
2
|
|
4
3
|
struct streaming_compress_t {
|
5
4
|
ZSTD_CCtx* ctx;
|
@@ -36,7 +35,7 @@ streaming_compress_memsize(const void *p)
|
|
36
35
|
}
|
37
36
|
|
38
37
|
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
39
|
-
static
|
38
|
+
static void
|
40
39
|
streaming_compress_compact(void *p)
|
41
40
|
{
|
42
41
|
struct streaming_compress_t *sc = p;
|
@@ -71,9 +70,9 @@ rb_streaming_compress_allocate(VALUE klass)
|
|
71
70
|
static VALUE
|
72
71
|
rb_streaming_compress_initialize(int argc, VALUE *argv, VALUE obj)
|
73
72
|
{
|
73
|
+
VALUE kwargs;
|
74
74
|
VALUE compression_level_value;
|
75
|
-
rb_scan_args(argc, argv, "01", &compression_level_value);
|
76
|
-
int compression_level = convert_compression_level(compression_level_value);
|
75
|
+
rb_scan_args(argc, argv, "01:", &compression_level_value, &kwargs);
|
77
76
|
|
78
77
|
struct streaming_compress_t* sc;
|
79
78
|
TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
|
@@ -83,7 +82,8 @@ rb_streaming_compress_initialize(int argc, VALUE *argv, VALUE obj)
|
|
83
82
|
if (ctx == NULL) {
|
84
83
|
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCCtx error");
|
85
84
|
}
|
86
|
-
|
85
|
+
set_compress_params(ctx, compression_level_value, kwargs);
|
86
|
+
|
87
87
|
sc->ctx = ctx;
|
88
88
|
sc->buf = rb_str_new(NULL, buffOutSize);
|
89
89
|
sc->buf_size = buffOutSize;
|
@@ -106,7 +106,7 @@ no_compress(struct streaming_compress_t* sc, ZSTD_EndDirective endOp)
|
|
106
106
|
do {
|
107
107
|
ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
|
108
108
|
|
109
|
-
size_t const ret =
|
109
|
+
size_t const ret = zstd_compress(sc->ctx, &output, &input, endOp);
|
110
110
|
if (ZSTD_isError(ret)) {
|
111
111
|
rb_raise(rb_eRuntimeError, "flush error error code: %s", ZSTD_getErrorName(ret));
|
112
112
|
}
|
@@ -125,11 +125,12 @@ rb_streaming_compress_compress(VALUE obj, VALUE src)
|
|
125
125
|
|
126
126
|
struct streaming_compress_t* sc;
|
127
127
|
TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
|
128
|
+
|
128
129
|
const char* output_data = RSTRING_PTR(sc->buf);
|
129
130
|
VALUE result = rb_str_new(0, 0);
|
130
131
|
while (input.pos < input.size) {
|
131
132
|
ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
|
132
|
-
size_t const ret =
|
133
|
+
size_t const ret = zstd_compress(sc->ctx, &output, &input, ZSTD_e_continue);
|
133
134
|
if (ZSTD_isError(ret)) {
|
134
135
|
rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(ret));
|
135
136
|
}
|
@@ -139,27 +140,54 @@ rb_streaming_compress_compress(VALUE obj, VALUE src)
|
|
139
140
|
}
|
140
141
|
|
141
142
|
static VALUE
|
142
|
-
|
143
|
+
rb_streaming_compress_write(int argc, VALUE *argv, VALUE obj)
|
143
144
|
{
|
144
|
-
|
145
|
-
|
146
|
-
size_t input_size = RSTRING_LEN(src);
|
147
|
-
ZSTD_inBuffer input = { input_data, input_size, 0 };
|
148
|
-
|
145
|
+
size_t total = 0;
|
146
|
+
VALUE result = rb_str_new(0, 0);
|
149
147
|
struct streaming_compress_t* sc;
|
150
148
|
TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
|
151
149
|
const char* output_data = RSTRING_PTR(sc->buf);
|
152
150
|
|
153
|
-
while (
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
151
|
+
while (argc-- > 0) {
|
152
|
+
VALUE str = *argv++;
|
153
|
+
StringValue(str);
|
154
|
+
const char* input_data = RSTRING_PTR(str);
|
155
|
+
size_t input_size = RSTRING_LEN(str);
|
156
|
+
ZSTD_inBuffer input = { input_data, input_size, 0 };
|
157
|
+
|
158
|
+
while (input.pos < input.size) {
|
159
|
+
ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
|
160
|
+
size_t const ret = zstd_compress(sc->ctx, &output, &input, ZSTD_e_continue);
|
161
|
+
if (ZSTD_isError(ret)) {
|
162
|
+
rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(ret));
|
163
|
+
}
|
164
|
+
total += RSTRING_LEN(str);
|
158
165
|
}
|
159
166
|
}
|
160
|
-
return
|
167
|
+
return SIZET2NUM(total);
|
161
168
|
}
|
162
169
|
|
170
|
+
/*
|
171
|
+
* Document-method: <<
|
172
|
+
* Same as IO.
|
173
|
+
*/
|
174
|
+
#define rb_streaming_compress_addstr rb_io_addstr
|
175
|
+
/*
|
176
|
+
* Document-method: printf
|
177
|
+
* Same as IO.
|
178
|
+
*/
|
179
|
+
#define rb_streaming_compress_printf rb_io_printf
|
180
|
+
/*
|
181
|
+
* Document-method: print
|
182
|
+
* Same as IO.
|
183
|
+
*/
|
184
|
+
#define rb_streaming_compress_print rb_io_print
|
185
|
+
/*
|
186
|
+
* Document-method: puts
|
187
|
+
* Same as IO.
|
188
|
+
*/
|
189
|
+
#define rb_streaming_compress_puts rb_io_puts
|
190
|
+
|
163
191
|
static VALUE
|
164
192
|
rb_streaming_compress_flush(VALUE obj)
|
165
193
|
{
|
@@ -186,7 +214,12 @@ zstd_ruby_streaming_compress_init(void)
|
|
186
214
|
rb_define_alloc_func(cStreamingCompress, rb_streaming_compress_allocate);
|
187
215
|
rb_define_method(cStreamingCompress, "initialize", rb_streaming_compress_initialize, -1);
|
188
216
|
rb_define_method(cStreamingCompress, "compress", rb_streaming_compress_compress, 1);
|
217
|
+
rb_define_method(cStreamingCompress, "write", rb_streaming_compress_write, -1);
|
189
218
|
rb_define_method(cStreamingCompress, "<<", rb_streaming_compress_addstr, 1);
|
219
|
+
rb_define_method(cStreamingCompress, "printf", rb_streaming_compress_printf, -1);
|
220
|
+
rb_define_method(cStreamingCompress, "print", rb_streaming_compress_print, -1);
|
221
|
+
rb_define_method(cStreamingCompress, "puts", rb_streaming_compress_puts, -1);
|
222
|
+
|
190
223
|
rb_define_method(cStreamingCompress, "flush", rb_streaming_compress_flush, 0);
|
191
224
|
rb_define_method(cStreamingCompress, "finish", rb_streaming_compress_finish, 0);
|
192
225
|
|
@@ -194,4 +227,3 @@ zstd_ruby_streaming_compress_init(void)
|
|
194
227
|
rb_define_const(cStreamingCompress, "FLUSH", INT2FIX(ZSTD_e_flush));
|
195
228
|
rb_define_const(cStreamingCompress, "END", INT2FIX(ZSTD_e_end));
|
196
229
|
}
|
197
|
-
|
@@ -1,7 +1,7 @@
|
|
1
|
-
#include
|
1
|
+
#include "common.h"
|
2
2
|
|
3
3
|
struct streaming_decompress_t {
|
4
|
-
ZSTD_DCtx*
|
4
|
+
ZSTD_DCtx* dctx;
|
5
5
|
VALUE buf;
|
6
6
|
size_t buf_size;
|
7
7
|
};
|
@@ -21,9 +21,9 @@ static void
|
|
21
21
|
streaming_decompress_free(void *p)
|
22
22
|
{
|
23
23
|
struct streaming_decompress_t *sd = p;
|
24
|
-
ZSTD_DCtx*
|
25
|
-
if (
|
26
|
-
ZSTD_freeDCtx(
|
24
|
+
ZSTD_DCtx* dctx = sd->dctx;
|
25
|
+
if (dctx != NULL) {
|
26
|
+
ZSTD_freeDCtx(dctx);
|
27
27
|
}
|
28
28
|
xfree(sd);
|
29
29
|
}
|
@@ -35,7 +35,7 @@ streaming_decompress_memsize(const void *p)
|
|
35
35
|
}
|
36
36
|
|
37
37
|
#ifdef HAVE_RB_GC_MARK_MOVABLE
|
38
|
-
static
|
38
|
+
static void
|
39
39
|
streaming_decompress_compact(void *p)
|
40
40
|
{
|
41
41
|
struct streaming_decompress_t *sd = p;
|
@@ -61,24 +61,29 @@ rb_streaming_decompress_allocate(VALUE klass)
|
|
61
61
|
{
|
62
62
|
struct streaming_decompress_t* sd;
|
63
63
|
VALUE obj = TypedData_Make_Struct(klass, struct streaming_decompress_t, &streaming_decompress_type, sd);
|
64
|
-
sd->
|
64
|
+
sd->dctx = NULL;
|
65
65
|
sd->buf = Qnil;
|
66
66
|
sd->buf_size = 0;
|
67
67
|
return obj;
|
68
68
|
}
|
69
69
|
|
70
70
|
static VALUE
|
71
|
-
rb_streaming_decompress_initialize(VALUE obj)
|
71
|
+
rb_streaming_decompress_initialize(int argc, VALUE *argv, VALUE obj)
|
72
72
|
{
|
73
|
+
VALUE kwargs;
|
74
|
+
rb_scan_args(argc, argv, "00:", &kwargs);
|
75
|
+
|
73
76
|
struct streaming_decompress_t* sd;
|
74
77
|
TypedData_Get_Struct(obj, struct streaming_decompress_t, &streaming_decompress_type, sd);
|
75
78
|
size_t const buffOutSize = ZSTD_DStreamOutSize();
|
76
79
|
|
77
|
-
ZSTD_DCtx*
|
78
|
-
if (
|
80
|
+
ZSTD_DCtx* dctx = ZSTD_createDCtx();
|
81
|
+
if (dctx == NULL) {
|
79
82
|
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDCtx error");
|
80
83
|
}
|
81
|
-
|
84
|
+
set_decompress_params(dctx, kwargs);
|
85
|
+
|
86
|
+
sd->dctx = dctx;
|
82
87
|
sd->buf = rb_str_new(NULL, buffOutSize);
|
83
88
|
sd->buf_size = buffOutSize;
|
84
89
|
|
@@ -99,45 +104,21 @@ rb_streaming_decompress_decompress(VALUE obj, VALUE src)
|
|
99
104
|
VALUE result = rb_str_new(0, 0);
|
100
105
|
while (input.pos < input.size) {
|
101
106
|
ZSTD_outBuffer output = { (void*)output_data, sd->buf_size, 0 };
|
102
|
-
size_t const ret = ZSTD_decompressStream(sd->
|
107
|
+
size_t const ret = ZSTD_decompressStream(sd->dctx, &output, &input);
|
103
108
|
if (ZSTD_isError(ret)) {
|
104
|
-
rb_raise(rb_eRuntimeError, "
|
109
|
+
rb_raise(rb_eRuntimeError, "decompress error error code: %s", ZSTD_getErrorName(ret));
|
105
110
|
}
|
106
111
|
rb_str_cat(result, output.dst, output.pos);
|
107
112
|
}
|
108
113
|
return result;
|
109
114
|
}
|
110
115
|
|
111
|
-
static VALUE
|
112
|
-
rb_streaming_decompress_addstr(VALUE obj, VALUE src)
|
113
|
-
{
|
114
|
-
StringValue(src);
|
115
|
-
const char* input_data = RSTRING_PTR(src);
|
116
|
-
size_t input_size = RSTRING_LEN(src);
|
117
|
-
ZSTD_inBuffer input = { input_data, input_size, 0 };
|
118
|
-
|
119
|
-
struct streaming_decompress_t* sd;
|
120
|
-
TypedData_Get_Struct(obj, struct streaming_decompress_t, &streaming_decompress_type, sd);
|
121
|
-
const char* output_data = RSTRING_PTR(sd->buf);
|
122
|
-
|
123
|
-
while (input.pos < input.size) {
|
124
|
-
ZSTD_outBuffer output = { (void*)output_data, sd->buf_size, 0 };
|
125
|
-
size_t const result = ZSTD_decompressStream(sd->ctx, &output, &input);
|
126
|
-
if (ZSTD_isError(result)) {
|
127
|
-
rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(result));
|
128
|
-
}
|
129
|
-
}
|
130
|
-
return obj;
|
131
|
-
}
|
132
|
-
|
133
116
|
extern VALUE rb_mZstd, cStreamingDecompress;
|
134
117
|
void
|
135
118
|
zstd_ruby_streaming_decompress_init(void)
|
136
119
|
{
|
137
120
|
VALUE cStreamingDecompress = rb_define_class_under(rb_mZstd, "StreamingDecompress", rb_cObject);
|
138
121
|
rb_define_alloc_func(cStreamingDecompress, rb_streaming_decompress_allocate);
|
139
|
-
rb_define_method(cStreamingDecompress, "initialize", rb_streaming_decompress_initialize,
|
122
|
+
rb_define_method(cStreamingDecompress, "initialize", rb_streaming_decompress_initialize, -1);
|
140
123
|
rb_define_method(cStreamingDecompress, "decompress", rb_streaming_decompress_decompress, 1);
|
141
|
-
rb_define_method(cStreamingDecompress, "<<", rb_streaming_decompress_addstr, 1);
|
142
124
|
}
|
143
|
-
|
data/ext/zstdruby/zstdruby.c
CHANGED
@@ -12,28 +12,39 @@ static VALUE rb_compress(int argc, VALUE *argv, VALUE self)
|
|
12
12
|
{
|
13
13
|
VALUE input_value;
|
14
14
|
VALUE compression_level_value;
|
15
|
-
|
16
|
-
|
15
|
+
VALUE kwargs;
|
16
|
+
rb_scan_args(argc, argv, "11:", &input_value, &compression_level_value, &kwargs);
|
17
|
+
|
18
|
+
ZSTD_CCtx* const ctx = ZSTD_createCCtx();
|
19
|
+
if (ctx == NULL) {
|
20
|
+
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCCtx error");
|
21
|
+
}
|
22
|
+
|
23
|
+
set_compress_params(ctx, compression_level_value, kwargs);
|
17
24
|
|
18
25
|
StringValue(input_value);
|
19
26
|
char* input_data = RSTRING_PTR(input_value);
|
20
27
|
size_t input_size = RSTRING_LEN(input_value);
|
28
|
+
ZSTD_inBuffer input = { input_data, input_size, 0 };
|
21
29
|
size_t max_compressed_size = ZSTD_compressBound(input_size);
|
30
|
+
VALUE buf = rb_str_new(NULL, max_compressed_size);
|
31
|
+
char* output_data = RSTRING_PTR(buf);
|
32
|
+
ZSTD_outBuffer output = { (void*)output_data, max_compressed_size, 0 };
|
22
33
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
if (ZSTD_isError(compressed_size)) {
|
28
|
-
rb_raise(rb_eRuntimeError, "%s: %s", "compress failed", ZSTD_getErrorName(compressed_size));
|
34
|
+
size_t const ret = zstd_compress(ctx, &output, &input, ZSTD_e_end);
|
35
|
+
if (ZSTD_isError(ret)) {
|
36
|
+
ZSTD_freeCCtx(ctx);
|
37
|
+
rb_raise(rb_eRuntimeError, "%s: %s", "compress failed", ZSTD_getErrorName(ret));
|
29
38
|
}
|
30
|
-
|
31
|
-
|
32
|
-
|
39
|
+
VALUE result = rb_str_new(0, 0);
|
40
|
+
rb_str_cat(result, output.dst, output.pos);
|
41
|
+
ZSTD_freeCCtx(ctx);
|
42
|
+
return result;
|
33
43
|
}
|
34
44
|
|
35
45
|
static VALUE rb_compress_using_dict(int argc, VALUE *argv, VALUE self)
|
36
46
|
{
|
47
|
+
rb_warn("Zstd.compress_using_dict is deprecated; use Zstd.compress with `dict:` instead.");
|
37
48
|
VALUE input_value;
|
38
49
|
VALUE dict;
|
39
50
|
VALUE compression_level_value;
|
@@ -78,8 +89,6 @@ static VALUE rb_compress_using_dict(int argc, VALUE *argv, VALUE self)
|
|
78
89
|
|
79
90
|
static VALUE decompress_buffered(const char* input_data, size_t input_size)
|
80
91
|
{
|
81
|
-
const size_t outputBufferSize = 4096;
|
82
|
-
|
83
92
|
ZSTD_DStream* const dstream = ZSTD_createDStream();
|
84
93
|
if (dstream == NULL) {
|
85
94
|
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDStream failed");
|
@@ -96,7 +105,7 @@ static VALUE decompress_buffered(const char* input_data, size_t input_size)
|
|
96
105
|
|
97
106
|
ZSTD_inBuffer input = { input_data, input_size, 0 };
|
98
107
|
while (input.pos < input.size) {
|
99
|
-
output.size +=
|
108
|
+
output.size += ZSTD_DStreamOutSize();
|
100
109
|
rb_str_resize(output_string, output.size);
|
101
110
|
output.dst = RSTRING_PTR(output_string);
|
102
111
|
|
@@ -112,8 +121,11 @@ static VALUE decompress_buffered(const char* input_data, size_t input_size)
|
|
112
121
|
return output_string;
|
113
122
|
}
|
114
123
|
|
115
|
-
static VALUE rb_decompress(VALUE
|
124
|
+
static VALUE rb_decompress(int argc, VALUE *argv, VALUE self)
|
116
125
|
{
|
126
|
+
VALUE input_value;
|
127
|
+
VALUE kwargs;
|
128
|
+
rb_scan_args(argc, argv, "10:", &input_value, &kwargs);
|
117
129
|
StringValue(input_value);
|
118
130
|
char* input_data = RSTRING_PTR(input_value);
|
119
131
|
size_t input_size = RSTRING_LEN(input_value);
|
@@ -122,15 +134,22 @@ static VALUE rb_decompress(VALUE self, VALUE input_value)
|
|
122
134
|
if (uncompressed_size == ZSTD_CONTENTSIZE_ERROR) {
|
123
135
|
rb_raise(rb_eRuntimeError, "%s: %s", "not compressed by zstd", ZSTD_getErrorName(uncompressed_size));
|
124
136
|
}
|
137
|
+
// ZSTD_decompressStream may be called multiple times when ZSTD_CONTENTSIZE_UNKNOWN, causing slowness.
|
138
|
+
// Therefore, we will not standardize on ZSTD_decompressStream
|
125
139
|
if (uncompressed_size == ZSTD_CONTENTSIZE_UNKNOWN) {
|
126
140
|
return decompress_buffered(input_data, input_size);
|
127
141
|
}
|
128
142
|
|
143
|
+
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
|
144
|
+
if (dctx == NULL) {
|
145
|
+
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDCtx failed");
|
146
|
+
}
|
147
|
+
set_decompress_params(dctx, kwargs);
|
148
|
+
|
129
149
|
VALUE output = rb_str_new(NULL, uncompressed_size);
|
130
150
|
char* output_data = RSTRING_PTR(output);
|
131
|
-
size_t const decompress_size = ZSTD_decompress((void*)output_data, uncompressed_size,
|
132
|
-
(void*)input_data, input_size);
|
133
151
|
|
152
|
+
size_t const decompress_size = ZSTD_decompressDCtx(dctx, output_data, uncompressed_size, input_data, input_size);
|
134
153
|
if (ZSTD_isError(decompress_size)) {
|
135
154
|
rb_raise(rb_eRuntimeError, "%s: %s", "decompress error", ZSTD_getErrorName(decompress_size));
|
136
155
|
}
|
@@ -140,6 +159,7 @@ static VALUE rb_decompress(VALUE self, VALUE input_value)
|
|
140
159
|
|
141
160
|
static VALUE rb_decompress_using_dict(int argc, VALUE *argv, VALUE self)
|
142
161
|
{
|
162
|
+
rb_warn("Zstd.decompress_using_dict is deprecated; use Zstd.decompress with `dict:` instead.");
|
143
163
|
VALUE input_value;
|
144
164
|
VALUE dict;
|
145
165
|
rb_scan_args(argc, argv, "20", &input_value, &dict);
|
@@ -193,6 +213,6 @@ zstd_ruby_init(void)
|
|
193
213
|
rb_define_module_function(rb_mZstd, "zstd_version", zstdVersion, 0);
|
194
214
|
rb_define_module_function(rb_mZstd, "compress", rb_compress, -1);
|
195
215
|
rb_define_module_function(rb_mZstd, "compress_using_dict", rb_compress_using_dict, -1);
|
196
|
-
rb_define_module_function(rb_mZstd, "decompress", rb_decompress, 1);
|
216
|
+
rb_define_module_function(rb_mZstd, "decompress", rb_decompress, -1);
|
197
217
|
rb_define_module_function(rb_mZstd, "decompress_using_dict", rb_decompress_using_dict, -1);
|
198
218
|
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Zstd
|
2
|
+
# @todo Exprimental
|
3
|
+
class StreamReader
|
4
|
+
def initialize(io)
|
5
|
+
@io = io
|
6
|
+
@stream = Zstd::StreamingDecompress.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def read(length)
|
10
|
+
if @io.eof?
|
11
|
+
raise StandardError, "EOF"
|
12
|
+
end
|
13
|
+
data = @io.read(length)
|
14
|
+
@stream.decompress(data)
|
15
|
+
end
|
16
|
+
|
17
|
+
def close
|
18
|
+
@io.write(@stream.finish)
|
19
|
+
@io.close
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Zstd
|
2
|
+
# @todo Exprimental
|
3
|
+
class StreamWriter
|
4
|
+
def initialize(io, level: nil)
|
5
|
+
@io = io
|
6
|
+
@stream = Zstd::StreamingCompress.new(level)
|
7
|
+
end
|
8
|
+
|
9
|
+
def write(*data)
|
10
|
+
@stream.write(*data)
|
11
|
+
@io.write(@stream.flush)
|
12
|
+
end
|
13
|
+
|
14
|
+
def finish
|
15
|
+
@io.write(@stream.finish)
|
16
|
+
end
|
17
|
+
|
18
|
+
def close
|
19
|
+
@io.write(@stream.finish)
|
20
|
+
@io.close
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/zstd-ruby/version.rb
CHANGED
data/renovate.json
ADDED
data/zstd-ruby.gemspec
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
#end
|
25
25
|
|
26
26
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
|
-
f.match(%r{^(test|spec|features|benchmarks|zstd|.github)/})
|
27
|
+
f.match(%r{^(test|spec|features|benchmarks|zstd|.github|examples)/})
|
28
28
|
end
|
29
29
|
spec.bindir = "exe"
|
30
30
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
@@ -35,4 +35,5 @@ Gem::Specification.new do |spec|
|
|
35
35
|
spec.add_development_dependency "rake", "~> 13.0"
|
36
36
|
spec.add_development_dependency "rake-compiler", '~> 1'
|
37
37
|
spec.add_development_dependency "rspec", "~> 3.0"
|
38
|
+
spec.add_development_dependency "pry"
|
38
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zstd-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.6.
|
4
|
+
version: 1.5.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SpringMT
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
description: Ruby binding for zstd(Zstandard - Fast real-time compression algorithm).
|
70
84
|
See https://github.com/facebook/zstd
|
71
85
|
email:
|
@@ -159,11 +173,13 @@ files:
|
|
159
173
|
- ext/zstdruby/main.c
|
160
174
|
- ext/zstdruby/skippable_frame.c
|
161
175
|
- ext/zstdruby/streaming_compress.c
|
162
|
-
- ext/zstdruby/streaming_compress.h
|
163
176
|
- ext/zstdruby/streaming_decompress.c
|
164
177
|
- ext/zstdruby/zstdruby.c
|
165
178
|
- lib/zstd-ruby.rb
|
179
|
+
- lib/zstd-ruby/stream_reader.rb
|
180
|
+
- lib/zstd-ruby/stream_writer.rb
|
166
181
|
- lib/zstd-ruby/version.rb
|
182
|
+
- renovate.json
|
167
183
|
- zstd-ruby.gemspec
|
168
184
|
homepage: https://github.com/SpringMT/zstd-ruby
|
169
185
|
licenses:
|
@@ -184,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
184
200
|
- !ruby/object:Gem::Version
|
185
201
|
version: '0'
|
186
202
|
requirements: []
|
187
|
-
rubygems_version: 3.3
|
203
|
+
rubygems_version: 3.5.3
|
188
204
|
signing_key:
|
189
205
|
specification_version: 4
|
190
206
|
summary: Ruby binding for zstd(Zstandard - Fast real-time compression algorithm)
|