zstd-ruby 1.5.2.2 → 1.5.2.3

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: '048d980344614b4a0087d7eb25cc01f9937fdf93439bdf4c1c830ca0d6fedeff'
4
- data.tar.gz: 432606f67285abd98fb76650445a4950e28501552a55661ed41b6f87000a4aa1
3
+ metadata.gz: cb64917059ca60a73732ee8f460f31ab3fbd36bce1eb20b844f8e36de8c9ec75
4
+ data.tar.gz: 01a248c444714b1404b934745f47c73aac8a2acb1bd1b0cb36993b1b61593d33
5
5
  SHA512:
6
- metadata.gz: 5f563ede0aa63ff7496f9206db6440f418ccf4b3fb7a9e1fb236bc9a7bfd78a6f4a4d0f4ce0eec497e786a44b7a5f3d74667d45a46952de8b3ba05df4e5c6a06
7
- data.tar.gz: ea58de90bbd0f397245fdb8830b92eae55787999a1e739540492129ba3461119fd6980b39e53fb0083c2edfc57ad6cb3bd33f183bb917120326af3a342e03fcb
6
+ metadata.gz: 629f566ee687ad0e3cf0afd7329f32d67bc10bb58a316541fec249913cb5b7a81323138dd1eef10aed986fbdf57838214fa65218cb3c5ae1fb20b6ffb880aa99
7
+ data.tar.gz: f6ca1102e9fd7c1147b0a2187575eca9fe6539375e4eff0b3a90635fb973b739402ed0951cd8b8f68d55d33a1996593c5da4e6078b39b8a5d2be77d311004110
data/README.md CHANGED
@@ -41,6 +41,12 @@ compressed_data = Zstd.compress(data)
41
41
  compressed_data = Zstd.compress(data, complession_level) # default compression_level is 0
42
42
  ```
43
43
 
44
+ ### Compression using Dictionary
45
+ ```ruby
46
+ # dictionary is supposed to have been created using `zstd --train`
47
+ compressed_using_dict = Zstd.compress_using_dict("", IO.read('dictionary_file'))
48
+ ```
49
+
44
50
  ### Streaming Compression
45
51
  ```
46
52
  stream = Zstd::StreamingCompress.new
@@ -66,6 +72,12 @@ res << stream.finish
66
72
  data = Zstd.decompress(compressed_data)
67
73
  ```
68
74
 
75
+ ### Decomporession using Dictionary
76
+ ```ruby
77
+ # dictionary is supposed to have been created using `zstd --train`
78
+ Zstd.decompress_using_dict(compressed_using_dict, IO.read('dictionary_file'))
79
+ ```
80
+
69
81
  ### Streaming Decompression
70
82
  ```
71
83
  cstr = "" # Compressed data
@@ -4,5 +4,12 @@
4
4
  #include "ruby.h"
5
5
  #include "./libzstd/zstd.h"
6
6
 
7
+ static int convert_compression_level(VALUE compression_level_value)
8
+ {
9
+ if (NIL_P(compression_level_value)) {
10
+ return ZSTD_CLEVEL_DEFAULT;
11
+ }
12
+ return NUM2INT(compression_level_value);
13
+ }
7
14
 
8
15
  #endif /* ZSTD_RUBY_H */
@@ -53,13 +53,7 @@ rb_streaming_compress_initialize(int argc, VALUE *argv, VALUE obj)
53
53
  {
54
54
  VALUE compression_level_value;
55
55
  rb_scan_args(argc, argv, "01", &compression_level_value);
56
-
57
- int compression_level;
58
- if (NIL_P(compression_level_value)) {
59
- compression_level = ZSTD_CLEVEL_DEFAULT;
60
- } else {
61
- compression_level = NUM2INT(compression_level_value);
62
- }
56
+ int compression_level = convert_compression_level(compression_level_value);
63
57
 
64
58
  struct streaming_compress_t* sc;
65
59
  TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
@@ -8,41 +8,74 @@ static VALUE zstdVersion(VALUE self)
8
8
  return INT2NUM(version);
9
9
  }
10
10
 
11
- static VALUE compress(int argc, VALUE *argv, VALUE self)
11
+ static VALUE rb_compress(int argc, VALUE *argv, VALUE self)
12
12
  {
13
13
  VALUE input_value;
14
14
  VALUE compression_level_value;
15
15
  rb_scan_args(argc, argv, "11", &input_value, &compression_level_value);
16
+ int compression_level = convert_compression_level(compression_level_value);
16
17
 
17
18
  StringValue(input_value);
18
- const char* input_data = RSTRING_PTR(input_value);
19
+ char* input_data = RSTRING_PTR(input_value);
19
20
  size_t input_size = RSTRING_LEN(input_value);
21
+ size_t max_compressed_size = ZSTD_compressBound(input_size);
20
22
 
21
- int compression_level;
22
- if (NIL_P(compression_level_value)) {
23
- compression_level = 0; // The default. See ZSTD_CLEVEL_DEFAULT in zstd_compress.c
24
- } else {
25
- compression_level = NUM2INT(compression_level_value);
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));
26
29
  }
27
30
 
28
- // do compress
31
+ rb_str_resize(output, compressed_size);
32
+ return output;
33
+ }
34
+
35
+ static VALUE rb_compress_using_dict(int argc, VALUE *argv, VALUE self)
36
+ {
37
+ VALUE input_value;
38
+ VALUE dict;
39
+ VALUE compression_level_value;
40
+ rb_scan_args(argc, argv, "21", &input_value, &dict, &compression_level_value);
41
+ int compression_level = convert_compression_level(compression_level_value);
42
+
43
+ StringValue(input_value);
44
+ char* input_data = RSTRING_PTR(input_value);
45
+ size_t input_size = RSTRING_LEN(input_value);
29
46
  size_t max_compressed_size = ZSTD_compressBound(input_size);
30
47
 
48
+ char* dict_buffer = RSTRING_PTR(dict);
49
+ size_t dict_size = RSTRING_LEN(dict);
50
+
51
+ ZSTD_CDict* const cdict = ZSTD_createCDict(dict_buffer, dict_size, compression_level);
52
+ if (cdict == NULL) {
53
+ rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCDict failed");
54
+ }
55
+ ZSTD_CCtx* const ctx = ZSTD_createCCtx();
56
+ if (ctx == NULL) {
57
+ ZSTD_freeCDict(cdict);
58
+ rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCCtx failed");
59
+ }
60
+
31
61
  VALUE output = rb_str_new(NULL, max_compressed_size);
32
62
  char* output_data = RSTRING_PTR(output);
33
-
34
- size_t compressed_size = ZSTD_compress((void*)output_data, max_compressed_size,
35
- (const void*)input_data, input_size, compression_level);
63
+ size_t const compressed_size = ZSTD_compress_usingCDict(ctx, (void*)output_data, max_compressed_size,
64
+ (void*)input_data, input_size, cdict);
36
65
 
37
66
  if (ZSTD_isError(compressed_size)) {
67
+ ZSTD_freeCDict(cdict);
68
+ ZSTD_freeCCtx(ctx);
38
69
  rb_raise(rb_eRuntimeError, "%s: %s", "compress failed", ZSTD_getErrorName(compressed_size));
39
- } else {
40
- rb_str_resize(output, compressed_size);
41
70
  }
42
71
 
72
+ rb_str_resize(output, compressed_size);
73
+ ZSTD_freeCDict(cdict);
74
+ ZSTD_freeCCtx(ctx);
43
75
  return output;
44
76
  }
45
77
 
78
+
46
79
  static VALUE decompress_buffered(const char* input_data, size_t input_size)
47
80
  {
48
81
  const size_t outputBufferSize = 4096;
@@ -58,7 +91,6 @@ static VALUE decompress_buffered(const char* input_data, size_t input_size)
58
91
  rb_raise(rb_eRuntimeError, "%s: %s", "ZSTD_initDStream failed", ZSTD_getErrorName(initResult));
59
92
  }
60
93
 
61
-
62
94
  VALUE output_string = rb_str_new(NULL, 0);
63
95
  ZSTD_outBuffer output = { NULL, 0, 0 };
64
96
 
@@ -80,23 +112,24 @@ static VALUE decompress_buffered(const char* input_data, size_t input_size)
80
112
  return output_string;
81
113
  }
82
114
 
83
- static VALUE decompress(VALUE self, VALUE input)
115
+ static VALUE rb_decompress(VALUE self, VALUE input_value)
84
116
  {
85
- StringValue(input);
86
- const char* input_data = RSTRING_PTR(input);
87
- size_t input_size = RSTRING_LEN(input);
88
-
89
- uint64_t uncompressed_size = ZSTD_getDecompressedSize(input_data, input_size);
117
+ StringValue(input_value);
118
+ char* input_data = RSTRING_PTR(input_value);
119
+ size_t input_size = RSTRING_LEN(input_value);
90
120
 
91
- if (uncompressed_size == 0) {
121
+ unsigned long long const uncompressed_size = ZSTD_getFrameContentSize(input_data, input_size);
122
+ if (uncompressed_size == ZSTD_CONTENTSIZE_ERROR) {
123
+ rb_raise(rb_eRuntimeError, "%s: %s", "not compressed by zstd", ZSTD_getErrorName(uncompressed_size));
124
+ }
125
+ if (uncompressed_size == ZSTD_CONTENTSIZE_UNKNOWN) {
92
126
  return decompress_buffered(input_data, input_size);
93
127
  }
94
128
 
95
129
  VALUE output = rb_str_new(NULL, uncompressed_size);
96
130
  char* output_data = RSTRING_PTR(output);
97
-
98
- size_t decompress_size = ZSTD_decompress((void*)output_data, uncompressed_size,
99
- (const void*)input_data, input_size);
131
+ size_t const decompress_size = ZSTD_decompress((void*)output_data, uncompressed_size,
132
+ (void*)input_data, input_size);
100
133
 
101
134
  if (ZSTD_isError(decompress_size)) {
102
135
  rb_raise(rb_eRuntimeError, "%s: %s", "decompress error", ZSTD_getErrorName(decompress_size));
@@ -105,10 +138,61 @@ static VALUE decompress(VALUE self, VALUE input)
105
138
  return output;
106
139
  }
107
140
 
141
+ static VALUE rb_decompress_using_dict(int argc, VALUE *argv, VALUE self)
142
+ {
143
+ VALUE input_value;
144
+ VALUE dict;
145
+ rb_scan_args(argc, argv, "20", &input_value, &dict);
146
+
147
+ StringValue(input_value);
148
+ char* input_data = RSTRING_PTR(input_value);
149
+ size_t input_size = RSTRING_LEN(input_value);
150
+ unsigned long long const uncompressed_size = ZSTD_getFrameContentSize(input_data, input_size);
151
+ if (uncompressed_size == ZSTD_CONTENTSIZE_ERROR) {
152
+ rb_raise(rb_eRuntimeError, "%s: %s", "not compressed by zstd", ZSTD_getErrorName(uncompressed_size));
153
+ }
154
+ if (uncompressed_size == ZSTD_CONTENTSIZE_UNKNOWN) {
155
+ return decompress_buffered(input_data, input_size);
156
+ }
157
+ VALUE output = rb_str_new(NULL, uncompressed_size);
158
+ char* output_data = RSTRING_PTR(output);
159
+
160
+ char* dict_buffer = RSTRING_PTR(dict);
161
+ size_t dict_size = RSTRING_LEN(dict);
162
+ ZSTD_DDict* const ddict = ZSTD_createDDict(dict_buffer, dict_size);
163
+ if (ddict == NULL) {
164
+ rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDDict failed");
165
+ }
166
+
167
+ unsigned const expected_dict_id = ZSTD_getDictID_fromDDict(ddict);
168
+ unsigned const actual_dict_id = ZSTD_getDictID_fromFrame(input_data, input_size);
169
+ if (expected_dict_id != actual_dict_id) {
170
+ ZSTD_freeDDict(ddict);
171
+ rb_raise(rb_eRuntimeError, "%s: %s", "DictID mismatch", ZSTD_getErrorName(uncompressed_size));
172
+ }
173
+
174
+ ZSTD_DCtx* const ctx = ZSTD_createDCtx();
175
+ if (ctx == NULL) {
176
+ ZSTD_freeDDict(ddict);
177
+ rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDCtx failed");
178
+ }
179
+ size_t const decompress_size = ZSTD_decompress_usingDDict(ctx, output_data, uncompressed_size, input_data, input_size, ddict);
180
+ if (ZSTD_isError(decompress_size)) {
181
+ ZSTD_freeDDict(ddict);
182
+ ZSTD_freeDCtx(ctx);
183
+ rb_raise(rb_eRuntimeError, "%s: %s", "decompress error", ZSTD_getErrorName(decompress_size));
184
+ }
185
+ ZSTD_freeDDict(ddict);
186
+ ZSTD_freeDCtx(ctx);
187
+ return output;
188
+ }
189
+
108
190
  void
109
191
  zstd_ruby_init(void)
110
192
  {
111
193
  rb_define_module_function(rb_mZstd, "zstd_version", zstdVersion, 0);
112
- rb_define_module_function(rb_mZstd, "compress", compress, -1);
113
- rb_define_module_function(rb_mZstd, "decompress", decompress, 1);
194
+ rb_define_module_function(rb_mZstd, "compress", rb_compress, -1);
195
+ 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);
197
+ rb_define_module_function(rb_mZstd, "decompress_using_dict", rb_decompress_using_dict, -1);
114
198
  }
@@ -1,3 +1,3 @@
1
1
  module Zstd
2
- VERSION = "1.5.2.2"
2
+ VERSION = "1.5.2.3"
3
3
  end
data/lib/zstd-ruby.rb CHANGED
@@ -2,5 +2,4 @@ require "zstd-ruby/version"
2
2
  require "zstd-ruby/zstdruby"
3
3
 
4
4
  module Zstd
5
- # Your code goes here...
6
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zstd-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.2.2
4
+ version: 1.5.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - SpringMT