zstd-ruby 1.5.6.6 → 1.5.6.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1fe1a5bcfa102673b36ea9a48096636faa76535095211998cddfe316775a3d78
4
- data.tar.gz: e2a96d0d1d2bdda0bc3d34080df219aeaa8c5274a2dac7a838730fce54ebe4f6
3
+ metadata.gz: 9acf1d7797f3431d0df130388295910e47c9bdaf36df29e1f116a55b993c130d
4
+ data.tar.gz: c58e20e6f0c2d270a21481b8ac2ba1c427d8cc6b1c2e52305e5b7540fcda41bc
5
5
  SHA512:
6
- metadata.gz: 6bdffd7e5b2d824fdf5ebad116ef4b965c4d4d2a77898df5a51623020db6fddf0e4562aa4d80de7f8978fa5f557ce85e56d19042667c379b3ac97c3a274a9d11
7
- data.tar.gz: 639a3d64cf8a8fa36a10cf180560a4102516d4da21e3100c1cdd724732fb583449c828ac4eeef6f9bad89c2f22467f7adf80b083116121ccff8d356c58246966
6
+ metadata.gz: 9fad54c87b430ddbd437dd5e238b873c7572b2ed23e7b2a6409b817e1a823ab943bd49278c989abc1470a30c7fc8ad983fcf18a0b1dad84f8b99625fee2e6097
7
+ data.tar.gz: d8dd762266849d491ac971bd7eb764ea9bda42da6ef6fbd351bc91ab792e18009f1d52f8005734489776c049b4ef82bd25042020be8cb286c73f94af86b1a2c7
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ .DS_Store
1
2
  /.bundle/
2
3
  /.yardoc
3
4
  /Gemfile.lock
data/README.md CHANGED
@@ -49,6 +49,22 @@ compressed_data = Zstd.compress(data, level: complession_level) # default compre
49
49
  compressed_using_dict = Zstd.compress("", dict: File.read('dictionary_file'))
50
50
  ```
51
51
 
52
+ #### Compression with CDict
53
+
54
+ If you use the same dictionary repeatedly, you can speed up the setup by creating CDict in advance:
55
+
56
+ ```ruby
57
+ cdict = Zstd::CDict.new(File.read('dictionary_file'))
58
+ compressed_using_dict = Zstd.compress("", dict: cdict)
59
+ ```
60
+
61
+ The compression_level can be specified on creating CDict.
62
+
63
+ ```ruby
64
+ cdict = Zstd::CDict.new(File.read('dictionary_file'), 5)
65
+ compressed_using_dict = Zstd.compress("", dict: cdict)
66
+ ```
67
+
52
68
  #### Streaming Compression
53
69
  ```ruby
54
70
  stream = Zstd::StreamingCompress.new
@@ -86,6 +102,16 @@ stream << "ghi"
86
102
  res << stream.finish
87
103
  ```
88
104
 
105
+ #### Streaming Compression with CDict of level 5
106
+ ```ruby
107
+ cdict = Zstd::CDict.new(File.read('dictionary_file', 5)
108
+ stream = Zstd::StreamingCompress.new(dict: cdict)
109
+ stream << "abc" << "def"
110
+ res = stream.flush
111
+ stream << "ghi"
112
+ res << stream.finish
113
+ ```
114
+
89
115
  ### Decompression
90
116
 
91
117
  #### Simple Decompression
@@ -100,6 +126,15 @@ data = Zstd.decompress(compressed_data)
100
126
  Zstd.decompress(compressed_using_dict, dict: File.read('dictionary_file'))
101
127
  ```
102
128
 
129
+ #### Decompression with DDict
130
+
131
+ If you use the same dictionary repeatedly, you can speed up the setup by creating DDict in advance:
132
+
133
+ ```ruby
134
+ ddict = Zstd::Ddict.new(File.read('dictionary_file'))
135
+ data = Zstd.compress(compressed_using_dict, ddict)
136
+ ```
137
+
103
138
  #### Streaming Decompression
104
139
  ```ruby
105
140
  cstr = "" # Compressed data
@@ -118,6 +153,8 @@ result << stream.decompress(cstr[0, 10])
118
153
  result << stream.decompress(cstr[10..-1])
119
154
  ```
120
155
 
156
+ DDict can also be specified to `dict:`.
157
+
121
158
  ### Skippable frame
122
159
 
123
160
  ```ruby
@@ -1,13 +1,15 @@
1
1
  #ifndef ZSTD_RUBY_H
2
2
  #define ZSTD_RUBY_H 1
3
3
 
4
+ #include <stdbool.h>
4
5
  #include <ruby.h>
5
6
  #ifdef HAVE_RUBY_THREAD_H
6
7
  #include <ruby/thread.h>
7
8
  #endif
8
- #include <stdbool.h>
9
9
  #include "./libzstd/zstd.h"
10
10
 
11
+ extern VALUE rb_cCDict, rb_cDDict;
12
+
11
13
  static int convert_compression_level(VALUE compression_level_value)
12
14
  {
13
15
  if (NIL_P(compression_level_value)) {
@@ -34,12 +36,24 @@ static void set_compress_params(ZSTD_CCtx* const ctx, VALUE level_from_args, VAL
34
36
  ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, compression_level);
35
37
 
36
38
  if (kwargs_values[1] != Qundef && kwargs_values[1] != Qnil) {
37
- char* dict_buffer = RSTRING_PTR(kwargs_values[1]);
38
- size_t dict_size = RSTRING_LEN(kwargs_values[1]);
39
- size_t load_dict_ret = ZSTD_CCtx_loadDictionary(ctx, dict_buffer, dict_size);
40
- if (ZSTD_isError(load_dict_ret)) {
39
+ if (CLASS_OF(kwargs_values[1]) == rb_cCDict) {
40
+ ZSTD_CDict* cdict = DATA_PTR(kwargs_values[1]);
41
+ size_t ref_dict_ret = ZSTD_CCtx_refCDict(ctx, cdict);
42
+ if (ZSTD_isError(ref_dict_ret)) {
43
+ ZSTD_freeCCtx(ctx);
44
+ rb_raise(rb_eRuntimeError, "%s", "ZSTD_CCtx_refCDict failed");
45
+ }
46
+ } else if (TYPE(kwargs_values[1]) == T_STRING) {
47
+ char* dict_buffer = RSTRING_PTR(kwargs_values[1]);
48
+ size_t dict_size = RSTRING_LEN(kwargs_values[1]);
49
+ size_t load_dict_ret = ZSTD_CCtx_loadDictionary(ctx, dict_buffer, dict_size);
50
+ if (ZSTD_isError(load_dict_ret)) {
51
+ ZSTD_freeCCtx(ctx);
52
+ rb_raise(rb_eRuntimeError, "%s", "ZSTD_CCtx_loadDictionary failed");
53
+ }
54
+ } else {
41
55
  ZSTD_freeCCtx(ctx);
42
- rb_raise(rb_eRuntimeError, "%s", "ZSTD_CCtx_loadDictionary failed");
56
+ rb_raise(rb_eArgError, "`dict:` must be a Zstd::CDict or a String");
43
57
  }
44
58
  }
45
59
  }
@@ -113,12 +127,24 @@ static void set_decompress_params(ZSTD_DCtx* const dctx, VALUE kwargs)
113
127
  rb_get_kwargs(kwargs, kwargs_keys, 0, 1, kwargs_values);
114
128
 
115
129
  if (kwargs_values[0] != Qundef && kwargs_values[0] != Qnil) {
116
- char* dict_buffer = RSTRING_PTR(kwargs_values[0]);
117
- size_t dict_size = RSTRING_LEN(kwargs_values[0]);
118
- size_t load_dict_ret = ZSTD_DCtx_loadDictionary(dctx, dict_buffer, dict_size);
119
- if (ZSTD_isError(load_dict_ret)) {
130
+ if (CLASS_OF(kwargs_values[0]) == rb_cDDict) {
131
+ ZSTD_DDict* ddict = DATA_PTR(kwargs_values[0]);
132
+ size_t ref_dict_ret = ZSTD_DCtx_refDDict(dctx, ddict);
133
+ if (ZSTD_isError(ref_dict_ret)) {
134
+ ZSTD_freeDCtx(dctx);
135
+ rb_raise(rb_eRuntimeError, "%s", "ZSTD_DCtx_refDDict failed");
136
+ }
137
+ } else if (TYPE(kwargs_values[0]) == T_STRING) {
138
+ char* dict_buffer = RSTRING_PTR(kwargs_values[0]);
139
+ size_t dict_size = RSTRING_LEN(kwargs_values[0]);
140
+ size_t load_dict_ret = ZSTD_DCtx_loadDictionary(dctx, dict_buffer, dict_size);
141
+ if (ZSTD_isError(load_dict_ret)) {
142
+ ZSTD_freeDCtx(dctx);
143
+ rb_raise(rb_eRuntimeError, "%s", "ZSTD_CCtx_loadDictionary failed");
144
+ }
145
+ } else {
120
146
  ZSTD_freeDCtx(dctx);
121
- rb_raise(rb_eRuntimeError, "%s", "ZSTD_CCtx_loadDictionary failed");
147
+ rb_raise(rb_eArgError, "`dict:` must be a Zstd::DDict or a String");
122
148
  }
123
149
  }
124
150
  }
data/ext/zstdruby/main.c CHANGED
@@ -1,6 +1,8 @@
1
1
  #include "common.h"
2
2
 
3
3
  VALUE rb_mZstd;
4
+ VALUE rb_cCDict;
5
+ VALUE rb_cDDict;
4
6
  void zstd_ruby_init(void);
5
7
  void zstd_ruby_skippable_frame_init(void);
6
8
  void zstd_ruby_streaming_compress_init(void);
@@ -14,6 +16,8 @@ Init_zstdruby(void)
14
16
  #endif
15
17
 
16
18
  rb_mZstd = rb_define_module("Zstd");
19
+ rb_cCDict = rb_define_class_under(rb_mZstd, "CDict", rb_cObject);
20
+ rb_cDDict = rb_define_class_under(rb_mZstd, "DDict", rb_cObject);
17
21
  zstd_ruby_init();
18
22
  zstd_ruby_skippable_frame_init();
19
23
  zstd_ruby_streaming_compress_init();
@@ -195,6 +195,90 @@ static VALUE rb_decompress_using_dict(int argc, VALUE *argv, VALUE self)
195
195
  return output;
196
196
  }
197
197
 
198
+ static void free_cdict(void *dict)
199
+ {
200
+ ZSTD_freeCDict(dict);
201
+ }
202
+
203
+ static size_t sizeof_cdict(const void *dict)
204
+ {
205
+ return ZSTD_sizeof_CDict(dict);
206
+ }
207
+
208
+ static void free_ddict(void *dict)
209
+ {
210
+ ZSTD_freeDDict(dict);
211
+ }
212
+
213
+ static size_t sizeof_ddict(const void *dict)
214
+ {
215
+ return ZSTD_sizeof_DDict(dict);
216
+ }
217
+
218
+ static const rb_data_type_t cdict_type = {
219
+ "Zstd::CDict",
220
+ {0, free_cdict, sizeof_cdict,},
221
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
222
+ };
223
+
224
+ static const rb_data_type_t ddict_type = {
225
+ "Zstd::DDict",
226
+ {0, free_ddict, sizeof_ddict,},
227
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
228
+ };
229
+
230
+ static VALUE rb_cdict_alloc(VALUE self)
231
+ {
232
+ ZSTD_CDict* cdict = NULL;
233
+ return TypedData_Wrap_Struct(self, &cdict_type, cdict);
234
+ }
235
+
236
+ static VALUE rb_cdict_initialize(int argc, VALUE *argv, VALUE self)
237
+ {
238
+ VALUE dict;
239
+ VALUE compression_level_value;
240
+ rb_scan_args(argc, argv, "11", &dict, &compression_level_value);
241
+ int compression_level = convert_compression_level(compression_level_value);
242
+
243
+ StringValue(dict);
244
+ char* dict_buffer = RSTRING_PTR(dict);
245
+ size_t dict_size = RSTRING_LEN(dict);
246
+
247
+ ZSTD_CDict* const cdict = ZSTD_createCDict(dict_buffer, dict_size, compression_level);
248
+ if (cdict == NULL) {
249
+ rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCDict failed");
250
+ }
251
+
252
+ DATA_PTR(self) = cdict;
253
+ return self;
254
+ }
255
+
256
+ static VALUE rb_ddict_alloc(VALUE self)
257
+ {
258
+ ZSTD_CDict* ddict = NULL;
259
+ return TypedData_Wrap_Struct(self, &ddict_type, ddict);
260
+ }
261
+
262
+ static VALUE rb_ddict_initialize(VALUE self, VALUE dict)
263
+ {
264
+ StringValue(dict);
265
+ char* dict_buffer = RSTRING_PTR(dict);
266
+ size_t dict_size = RSTRING_LEN(dict);
267
+
268
+ ZSTD_DDict* const ddict = ZSTD_createDDict(dict_buffer, dict_size);
269
+ if (ddict == NULL) {
270
+ rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDDict failed");
271
+ }
272
+
273
+ DATA_PTR(self) = ddict;
274
+ return self;
275
+ }
276
+
277
+ static VALUE rb_prohibit_copy(VALUE self, VALUE obj)
278
+ {
279
+ rb_raise(rb_eRuntimeError, "CDict cannot be duplicated");
280
+ }
281
+
198
282
  void
199
283
  zstd_ruby_init(void)
200
284
  {
@@ -203,4 +287,12 @@ zstd_ruby_init(void)
203
287
  rb_define_module_function(rb_mZstd, "compress_using_dict", rb_compress_using_dict, -1);
204
288
  rb_define_module_function(rb_mZstd, "decompress", rb_decompress, -1);
205
289
  rb_define_module_function(rb_mZstd, "decompress_using_dict", rb_decompress_using_dict, -1);
290
+
291
+ rb_define_alloc_func(rb_cCDict, rb_cdict_alloc);
292
+ rb_define_private_method(rb_cCDict, "initialize", rb_cdict_initialize, -1);
293
+ rb_define_method(rb_cCDict, "initialize_copy", rb_prohibit_copy, 1);
294
+
295
+ rb_define_alloc_func(rb_cDDict, rb_ddict_alloc);
296
+ rb_define_private_method(rb_cDDict, "initialize", rb_ddict_initialize, 1);
297
+ rb_define_method(rb_cDDict, "initialize_copy", rb_prohibit_copy, 1);
206
298
  }
@@ -3,7 +3,7 @@ module Zstd
3
3
  class StreamWriter
4
4
  def initialize(io, level: nil)
5
5
  @io = io
6
- @stream = Zstd::StreamingCompress.new(level)
6
+ @stream = Zstd::StreamingCompress.new(level: level)
7
7
  end
8
8
 
9
9
  def write(*data)
@@ -1,3 +1,3 @@
1
1
  module Zstd
2
- VERSION = "1.5.6.6"
2
+ VERSION = "1.5.6.7"
3
3
  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.6
4
+ version: 1.5.6.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - SpringMT
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-23 00:00:00.000000000 Z
11
+ date: 2025-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -200,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
200
  - !ruby/object:Gem::Version
201
201
  version: '0'
202
202
  requirements: []
203
- rubygems_version: 3.5.3
203
+ rubygems_version: 3.4.19
204
204
  signing_key:
205
205
  specification_version: 4
206
206
  summary: Ruby binding for zstd(Zstandard - Fast real-time compression algorithm)