zstd-ruby 1.5.6.1 → 1.5.6.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40905f48d12335ff309bf984092915cf10b77425f3a913fa7ee721732fd200ec
4
- data.tar.gz: 50af86c41600c37b2395aef57f967e76bac3d296271b257d106b64456f6ab4cf
3
+ metadata.gz: 5c50aade1eb5c3a36dfaba5dc325c1bc416ceaa3558539ae5b389bb4378f6c37
4
+ data.tar.gz: 490b1268c79f5e481969fb1cf2fe2adb9bba5a51ab0e0197fd0338913a228611
5
5
  SHA512:
6
- metadata.gz: 1c01f7837f96849a1cd6bc3068b1b3b3d777e955849c26bc902529007184541a1b78838b33a2c27d4d50a11da4ca0e0f6b42c2c9318f9a1e23d81d4806d7f970
7
- data.tar.gz: 843369ab0c7dcc5010b6d027a73f364e5765dd63898683227a839ff7139fbba6ece018d3c77885b7f21a6aec4846a52f86abe90ee47bb18d675985df4111e873
6
+ metadata.gz: 14db577b5e10bc3a92df632d391dfdb55802da3768e5b829c9b849f440b0b5234be8d924a6b0c5d237cab7befdd540d1535de0ba56dafd30fbfe13c2e635e229
7
+ data.tar.gz: e6959f0da13aaa2a609fec024a3f293e4366760e3efd7626fc545c29ad5a1b0290119bc088cf60cb6665c1f2a5d93f0faf72152be3cf470ce5cf43657695a588
data/README.md CHANGED
@@ -34,20 +34,22 @@ Or install it yourself as:
34
34
  require 'zstd-ruby'
35
35
  ```
36
36
 
37
- ### Simple Compression
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 0
43
+ compressed_data = Zstd.compress(data, level: complession_level) # default compression_level is 3
42
44
  ```
43
45
 
44
- ### Compression using Dictionary
46
+ #### Compression with Dictionary
45
47
  ```ruby
46
48
  # dictionary is supposed to have been created using `zstd --train`
47
- compressed_using_dict = Zstd.compress_using_dict("", IO.read('dictionary_file'))
49
+ compressed_using_dict = Zstd.compress("", dict: File.read('dictionary_file'))
48
50
  ```
49
51
 
50
- ### Streaming Compression
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
- ### Simple Decompression
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
- ### Decomporession using Dictionary
97
+ #### Decompression with Dictionary
76
98
  ```ruby
77
99
  # dictionary is supposed to have been created using `zstd --train`
78
- Zstd.decompress_using_dict(compressed_using_dict, IO.read('dictionary_file'))
100
+ Zstd.decompress(compressed_using_dict, dict: File.read('dictionary_file'))
79
101
  ```
80
102
 
81
- ### Streaming Decompression
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
@@ -1,7 +1,7 @@
1
1
  #ifndef ZSTD_RUBY_H
2
2
  #define ZSTD_RUBY_H 1
3
3
 
4
- #include "ruby.h"
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,4 +1,5 @@
1
- #include <common.h>
1
+ #include "common.h"
2
+
2
3
  VALUE rb_mZstd;
3
4
  void zstd_ruby_init(void);
4
5
  void zstd_ruby_skippable_frame_init(void);
@@ -1,4 +1,4 @@
1
- #include <common.h>
1
+ #include "common.h"
2
2
 
3
3
  extern VALUE rb_mZstd;
4
4
 
@@ -1,5 +1,4 @@
1
- #include <common.h>
2
- #include <streaming_compress.h>
1
+ #include "common.h"
3
2
 
4
3
  struct streaming_compress_t {
5
4
  ZSTD_CCtx* ctx;
@@ -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
- ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, compression_level);
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 = ZSTD_compressStream2(sc->ctx, &output, &input, endOp);
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 = ZSTD_compressStream2(sc->ctx, &output, &input, ZSTD_e_continue);
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
- rb_streaming_compress_addstr(VALUE obj, VALUE src)
143
+ rb_streaming_compress_write(int argc, VALUE *argv, VALUE obj)
143
144
  {
144
- StringValue(src);
145
- const char* input_data = RSTRING_PTR(src);
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 (input.pos < input.size) {
154
- ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
155
- size_t const result = ZSTD_compressStream2(sc->ctx, &output, &input, ZSTD_e_continue);
156
- if (ZSTD_isError(result)) {
157
- rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(result));
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 obj;
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 <common.h>
1
+ #include "common.h"
2
2
 
3
3
  struct streaming_decompress_t {
4
- ZSTD_DCtx* ctx;
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* ctx = sd->ctx;
25
- if (ctx != NULL) {
26
- ZSTD_freeDCtx(ctx);
24
+ ZSTD_DCtx* dctx = sd->dctx;
25
+ if (dctx != NULL) {
26
+ ZSTD_freeDCtx(dctx);
27
27
  }
28
28
  xfree(sd);
29
29
  }
@@ -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->ctx = NULL;
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* ctx = ZSTD_createDCtx();
78
- if (ctx == NULL) {
80
+ ZSTD_DCtx* dctx = ZSTD_createDCtx();
81
+ if (dctx == NULL) {
79
82
  rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDCtx error");
80
83
  }
81
- sd->ctx = ctx;
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->ctx, &output, &input);
107
+ size_t const ret = ZSTD_decompressStream(sd->dctx, &output, &input);
103
108
  if (ZSTD_isError(ret)) {
104
- rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(ret));
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, 0);
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
-
@@ -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
- rb_scan_args(argc, argv, "11", &input_value, &compression_level_value);
16
- int compression_level = convert_compression_level(compression_level_value);
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
- VALUE output = rb_str_new(NULL, max_compressed_size);
24
- char* output_data = RSTRING_PTR(output);
25
- size_t compressed_size = ZSTD_compress((void*)output_data, max_compressed_size,
26
- (void*)input_data, input_size, compression_level);
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
- rb_str_resize(output, compressed_size);
32
- return output;
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 += outputBufferSize;
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 self, VALUE input_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
@@ -1,3 +1,3 @@
1
1
  module Zstd
2
- VERSION = "1.5.6.1"
2
+ VERSION = "1.5.6.2"
3
3
  end
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.1
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-04-01 00:00:00.000000000 Z
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,10 +173,11 @@ 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
167
182
  - renovate.json
168
183
  - zstd-ruby.gemspec
@@ -1,5 +0,0 @@
1
- #if !defined(STREAMING_COMPRESS_H)
2
- #define STREAMING_COMPRESS_H
3
-
4
-
5
- #endif // STREAMING_COMPRESS_H