zstd-ruby 1.5.2.0 → 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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/README.md +68 -3
  4. data/Rakefile +8 -2
  5. data/ext/zstdruby/common.h +15 -0
  6. data/ext/zstdruby/main.c +14 -0
  7. data/ext/zstdruby/streaming_compress.c +177 -0
  8. data/ext/zstdruby/streaming_compress.h +5 -0
  9. data/ext/zstdruby/streaming_decompress.c +123 -0
  10. data/ext/zstdruby/zstdruby.c +113 -31
  11. data/lib/zstd-ruby/version.rb +1 -1
  12. data/lib/zstd-ruby.rb +0 -1
  13. data/zstd-ruby.gemspec +1 -1
  14. metadata +7 -36
  15. data/.github/dependabot.yml +0 -8
  16. data/.github/workflows/ruby.yml +0 -35
  17. data/ext/zstdruby/libzstd/.gitignore +0 -3
  18. data/ext/zstdruby/libzstd/BUCK +0 -232
  19. data/ext/zstdruby/libzstd/Makefile +0 -357
  20. data/ext/zstdruby/libzstd/README.md +0 -217
  21. data/ext/zstdruby/libzstd/deprecated/zbuff.h +0 -214
  22. data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +0 -26
  23. data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +0 -167
  24. data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +0 -75
  25. data/ext/zstdruby/libzstd/dll/example/Makefile +0 -48
  26. data/ext/zstdruby/libzstd/dll/example/README.md +0 -63
  27. data/ext/zstdruby/libzstd/dll/example/build_package.bat +0 -20
  28. data/ext/zstdruby/libzstd/dll/example/fullbench-dll.sln +0 -25
  29. data/ext/zstdruby/libzstd/dll/example/fullbench-dll.vcxproj +0 -181
  30. data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +0 -415
  31. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +0 -2158
  32. data/ext/zstdruby/libzstd/legacy/zstd_v01.h +0 -94
  33. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +0 -3518
  34. data/ext/zstdruby/libzstd/legacy/zstd_v02.h +0 -93
  35. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +0 -3160
  36. data/ext/zstdruby/libzstd/legacy/zstd_v03.h +0 -93
  37. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +0 -3647
  38. data/ext/zstdruby/libzstd/legacy/zstd_v04.h +0 -142
  39. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +0 -4050
  40. data/ext/zstdruby/libzstd/legacy/zstd_v05.h +0 -162
  41. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +0 -4154
  42. data/ext/zstdruby/libzstd/legacy/zstd_v06.h +0 -172
  43. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +0 -4541
  44. data/ext/zstdruby/libzstd/legacy/zstd_v07.h +0 -187
  45. data/ext/zstdruby/libzstd/libzstd.mk +0 -203
  46. data/ext/zstdruby/libzstd/libzstd.pc.in +0 -16
  47. data/ext/zstdruby/libzstd/module.modulemap +0 -25
  48. data/ext/zstdruby/zstdruby.h +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c33df57662a35d3eae35eb7b82afecf5e91191152edcef555b88aab4b803a3a
4
- data.tar.gz: e3d5d34ff446b9a280bcb4e0fc103b4f6cb3312c37756145a578a05bfc237672
3
+ metadata.gz: cb64917059ca60a73732ee8f460f31ab3fbd36bce1eb20b844f8e36de8c9ec75
4
+ data.tar.gz: 01a248c444714b1404b934745f47c73aac8a2acb1bd1b0cb36993b1b61593d33
5
5
  SHA512:
6
- metadata.gz: 3f0f2cab5053a1bd6ffc3af753aae2ba2d61c20623738e8c4214a9b67dedd6a76df1fdec888b1fe21fbc3334457d8fe4ed03c9ff17dcfbe19f55022846291ea3
7
- data.tar.gz: 59ee08ebad25d6c1f21d3b611f7352db6b4cb219a047fe0d9782c9eaae17aa6972bc70e4818c91289e8f7c03cab0dea9db7ac06ce372295c718fa0dae5046c94
6
+ metadata.gz: 629f566ee687ad0e3cf0afd7329f32d67bc10bb58a316541fec249913cb5b7a81323138dd1eef10aed986fbdf57838214fa65218cb3c5ae1fb20b6ffb880aa99
7
+ data.tar.gz: f6ca1102e9fd7c1147b0a2187575eca9fe6539375e4eff0b3a90635fb973b739402ed0951cd8b8f68d55d33a1996593c5da4e6078b39b8a5d2be77d311004110
data/.gitignore CHANGED
@@ -17,3 +17,5 @@ vendor/
17
17
 
18
18
  # rspec failure tracking
19
19
  .rspec_status
20
+
21
+ .ruby-version
data/README.md CHANGED
@@ -34,20 +34,85 @@ Or install it yourself as:
34
34
  require 'zstd-ruby'
35
35
  ```
36
36
 
37
- ### compression
37
+ ### Simple Compression
38
38
 
39
39
  ```ruby
40
40
  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
+ ```
44
49
 
45
- ### decompression
50
+ ### Streaming Compression
51
+ ```
52
+ stream = Zstd::StreamingCompress.new
53
+ stream << "abc" << "def"
54
+ res = stream.flush
55
+ stream << "ghi"
56
+ res << stream.finish
57
+ ```
58
+
59
+ or
60
+
61
+ ```
62
+ stream = Zstd::StreamingCompress.new
63
+ res = stream.compress("abc")
64
+ res << stream.flush
65
+ res << stream.compress("def")
66
+ res << stream.finish
67
+ ```
68
+
69
+ ### Simple Decompression
46
70
 
47
71
  ```ruby
48
72
  data = Zstd.decompress(compressed_data)
49
73
  ```
50
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
+
81
+ ### Streaming Decompression
82
+ ```
83
+ cstr = "" # Compressed data
84
+ stream = Zstd::StreamingDecompress.new
85
+ result = ''
86
+ result << stream.decompress(cstr[0, 10])
87
+ result << stream.decompress(cstr[10..-1])
88
+ ```
89
+
90
+
91
+ ## JRuby
92
+ This gem does not support JRuby.
93
+
94
+ Please consider using https://github.com/luben/zstd-jni.
95
+
96
+ Sample code is below.
97
+
98
+ ```
99
+ require 'java'
100
+ require_relative './zstd-jni-1.5.2-3.jar'
101
+
102
+ str = "testtest"
103
+ compressed = com.github.luben.zstd.Zstd.compress(str.to_java_bytes)
104
+ puts com.github.luben.zstd.Zstd.decompress(compressed, str.length)
105
+ ```
106
+
107
+ ```
108
+ % ls
109
+ test.rb zstd-jni-1.5.2-3.jar
110
+ % ruby -v
111
+ jruby 9.3.2.0 (2.6.8) 2021-12-01 0b8223f905 OpenJDK 64-Bit Server VM 11.0.12+0 on 11.0.12+0 +jit [darwin-x86_64]
112
+ % ruby test.rb
113
+ testtest
114
+ ```
115
+
51
116
  ## Development
52
117
 
53
118
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -56,7 +121,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
56
121
 
57
122
  ## Contributing
58
123
 
59
- Bug reports and pull requests are welcome on GitHub at https://github.com/SpringMT/zstd_ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
124
+ Bug reports and pull requests are welcome on GitHub at https://github.com/SpringMT/zstd-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
60
125
 
61
126
 
62
127
  ## License
data/Rakefile CHANGED
@@ -17,6 +17,12 @@ task :default => [:clobber, :compile, :spec]
17
17
 
18
18
  desc 'Sync zstd libs dirs to ext/zstdruby/libzstd'
19
19
  task :zstd_update do
20
- FileUtils.rm_r('ext/zstdruby/libzstd')
21
- FileUtils.cp_r('zstd/lib', 'ext/zstdruby/libzstd')
20
+ FileUtils.rm_r("ext/zstdruby/libzstd")
21
+ FileUtils.mkdir_p("ext/zstdruby/libzstd")
22
+ ["common", "compress", "decompress", "dictBuilder"].each do |dir|
23
+ FileUtils.cp_r("zstd/lib/#{dir}", "ext/zstdruby/libzstd/#{dir}")
24
+ end
25
+ FileUtils.cp_r('zstd/lib/zdict.h', 'ext/zstdruby/libzstd')
26
+ FileUtils.cp_r('zstd/lib/zstd.h', 'ext/zstdruby/libzstd')
27
+ FileUtils.cp_r('zstd/lib/zstd_errors.h', 'ext/zstdruby/libzstd')
22
28
  end
@@ -0,0 +1,15 @@
1
+ #ifndef ZSTD_RUBY_H
2
+ #define ZSTD_RUBY_H 1
3
+
4
+ #include "ruby.h"
5
+ #include "./libzstd/zstd.h"
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
+ }
14
+
15
+ #endif /* ZSTD_RUBY_H */
@@ -0,0 +1,14 @@
1
+ #include <common.h>
2
+ VALUE rb_mZstd;
3
+ void zstd_ruby_init(void);
4
+ void zstd_ruby_streaming_compress_init(void);
5
+ void zstd_ruby_streaming_decompress_init(void);
6
+
7
+ void
8
+ Init_zstdruby(void)
9
+ {
10
+ rb_mZstd = rb_define_module("Zstd");
11
+ zstd_ruby_init();
12
+ zstd_ruby_streaming_compress_init();
13
+ zstd_ruby_streaming_decompress_init();
14
+ }
@@ -0,0 +1,177 @@
1
+ #include <common.h>
2
+ #include <streaming_compress.h>
3
+
4
+ struct streaming_compress_t {
5
+ ZSTD_CCtx* ctx;
6
+ VALUE buf;
7
+ size_t buf_size;
8
+ };
9
+
10
+ static void
11
+ streaming_compress_mark(void *p)
12
+ {
13
+ struct streaming_compress_t *sc = p;
14
+ rb_gc_mark(sc->buf);
15
+ }
16
+
17
+ static void
18
+ streaming_compress_free(void *p)
19
+ {
20
+ struct streaming_compress_t *sc = p;
21
+ ZSTD_CCtx* ctx = sc->ctx;
22
+ if (ctx != NULL) {
23
+ ZSTD_freeCCtx(ctx);
24
+ }
25
+ xfree(sc);
26
+ }
27
+
28
+ static size_t
29
+ streaming_compress_memsize(const void *p)
30
+ {
31
+ return sizeof(struct streaming_compress_t);
32
+ }
33
+
34
+ static const rb_data_type_t streaming_compress_type = {
35
+ "streaming_compress",
36
+ { streaming_compress_mark, streaming_compress_free, streaming_compress_memsize, },
37
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
38
+ };
39
+
40
+ static VALUE
41
+ rb_streaming_compress_allocate(VALUE klass)
42
+ {
43
+ struct streaming_compress_t* sc;
44
+ VALUE obj = TypedData_Make_Struct(klass, struct streaming_compress_t, &streaming_compress_type, sc);
45
+ sc->ctx = NULL;
46
+ sc->buf = Qnil;
47
+ sc->buf_size = 0;
48
+ return obj;
49
+ }
50
+
51
+ static VALUE
52
+ rb_streaming_compress_initialize(int argc, VALUE *argv, VALUE obj)
53
+ {
54
+ VALUE compression_level_value;
55
+ rb_scan_args(argc, argv, "01", &compression_level_value);
56
+ int compression_level = convert_compression_level(compression_level_value);
57
+
58
+ struct streaming_compress_t* sc;
59
+ TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
60
+ size_t const buffOutSize = ZSTD_CStreamOutSize();
61
+
62
+ ZSTD_CCtx* ctx = ZSTD_createCCtx();
63
+ if (ctx == NULL) {
64
+ rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCCtx error");
65
+ }
66
+ ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, compression_level);
67
+ sc->ctx = ctx;
68
+ sc->buf = rb_str_new(NULL, buffOutSize);
69
+ sc->buf_size = buffOutSize;
70
+
71
+ return obj;
72
+ }
73
+
74
+ #define FIXNUMARG(val, ifnil) \
75
+ (NIL_P((val)) ? (ifnil) \
76
+ : (FIX2INT((val))))
77
+ #define ARG_CONTINUE(val) FIXNUMARG((val), ZSTD_e_continue)
78
+
79
+ static VALUE
80
+ no_compress(struct streaming_compress_t* sc, ZSTD_EndDirective endOp)
81
+ {
82
+ ZSTD_inBuffer input = { NULL, 0, 0 };
83
+ const char* output_data = RSTRING_PTR(sc->buf);
84
+ VALUE result = rb_str_new(0, 0);
85
+ size_t ret;
86
+ do {
87
+ ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
88
+
89
+ size_t const ret = ZSTD_compressStream2(sc->ctx, &output, &input, endOp);
90
+ if (ZSTD_isError(ret)) {
91
+ rb_raise(rb_eRuntimeError, "flush error error code: %s", ZSTD_getErrorName(ret));
92
+ }
93
+ rb_str_cat(result, output.dst, output.pos);
94
+ } while (ret > 0);
95
+ return result;
96
+ }
97
+
98
+ static VALUE
99
+ rb_streaming_compress_compress(VALUE obj, VALUE src)
100
+ {
101
+ StringValue(src);
102
+ const char* input_data = RSTRING_PTR(src);
103
+ size_t input_size = RSTRING_LEN(src);
104
+ ZSTD_inBuffer input = { input_data, input_size, 0 };
105
+
106
+ struct streaming_compress_t* sc;
107
+ TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
108
+ const char* output_data = RSTRING_PTR(sc->buf);
109
+ VALUE result = rb_str_new(0, 0);
110
+ while (input.pos < input.size) {
111
+ ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
112
+ size_t const ret = ZSTD_compressStream2(sc->ctx, &output, &input, ZSTD_e_continue);
113
+ if (ZSTD_isError(ret)) {
114
+ rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(ret));
115
+ }
116
+ rb_str_cat(result, output.dst, output.pos);
117
+ }
118
+ return result;
119
+ }
120
+
121
+ static VALUE
122
+ rb_streaming_compress_addstr(VALUE obj, VALUE src)
123
+ {
124
+ StringValue(src);
125
+ const char* input_data = RSTRING_PTR(src);
126
+ size_t input_size = RSTRING_LEN(src);
127
+ ZSTD_inBuffer input = { input_data, input_size, 0 };
128
+
129
+ struct streaming_compress_t* sc;
130
+ TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
131
+ const char* output_data = RSTRING_PTR(sc->buf);
132
+
133
+ while (input.pos < input.size) {
134
+ ZSTD_outBuffer output = { (void*)output_data, sc->buf_size, 0 };
135
+ size_t const result = ZSTD_compressStream2(sc->ctx, &output, &input, ZSTD_e_continue);
136
+ if (ZSTD_isError(result)) {
137
+ rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(result));
138
+ }
139
+ }
140
+ return obj;
141
+ }
142
+
143
+ static VALUE
144
+ rb_streaming_compress_flush(VALUE obj)
145
+ {
146
+ struct streaming_compress_t* sc;
147
+ TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
148
+ VALUE result = no_compress(sc, ZSTD_e_flush);
149
+ return result;
150
+ }
151
+
152
+ static VALUE
153
+ rb_streaming_compress_finish(VALUE obj)
154
+ {
155
+ struct streaming_compress_t* sc;
156
+ TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
157
+ VALUE result = no_compress(sc, ZSTD_e_end);
158
+ return result;
159
+ }
160
+
161
+ extern VALUE rb_mZstd, cStreamingCompress;
162
+ void
163
+ zstd_ruby_streaming_compress_init(void)
164
+ {
165
+ VALUE cStreamingCompress = rb_define_class_under(rb_mZstd, "StreamingCompress", rb_cObject);
166
+ rb_define_alloc_func(cStreamingCompress, rb_streaming_compress_allocate);
167
+ rb_define_method(cStreamingCompress, "initialize", rb_streaming_compress_initialize, -1);
168
+ rb_define_method(cStreamingCompress, "compress", rb_streaming_compress_compress, 1);
169
+ rb_define_method(cStreamingCompress, "<<", rb_streaming_compress_addstr, 1);
170
+ rb_define_method(cStreamingCompress, "flush", rb_streaming_compress_flush, 0);
171
+ rb_define_method(cStreamingCompress, "finish", rb_streaming_compress_finish, 0);
172
+
173
+ rb_define_const(cStreamingCompress, "CONTINUE", INT2FIX(ZSTD_e_continue));
174
+ rb_define_const(cStreamingCompress, "FLUSH", INT2FIX(ZSTD_e_flush));
175
+ rb_define_const(cStreamingCompress, "END", INT2FIX(ZSTD_e_end));
176
+ }
177
+
@@ -0,0 +1,5 @@
1
+ #if !defined(STREAMING_COMPRESS_H)
2
+ #define STREAMING_COMPRESS_H
3
+
4
+
5
+ #endif // STREAMING_COMPRESS_H
@@ -0,0 +1,123 @@
1
+ #include <common.h>
2
+
3
+ struct streaming_decompress_t {
4
+ ZSTD_DCtx* ctx;
5
+ VALUE buf;
6
+ size_t buf_size;
7
+ };
8
+
9
+ static void
10
+ streaming_decompress_mark(void *p)
11
+ {
12
+ struct streaming_decompress_t *sd = p;
13
+ rb_gc_mark(sd->buf);
14
+ }
15
+
16
+ static void
17
+ streaming_decompress_free(void *p)
18
+ {
19
+ struct streaming_decompress_t *sd = p;
20
+ ZSTD_DCtx* ctx = sd->ctx;
21
+ if (ctx != NULL) {
22
+ ZSTD_freeDCtx(ctx);
23
+ }
24
+ xfree(sd);
25
+ }
26
+
27
+ static size_t
28
+ streaming_decompress_memsize(const void *p)
29
+ {
30
+ return sizeof(struct streaming_decompress_t);
31
+ }
32
+
33
+ static const rb_data_type_t streaming_decompress_type = {
34
+ "streaming_decompress",
35
+ { streaming_decompress_mark, streaming_decompress_free, streaming_decompress_memsize, },
36
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
37
+ };
38
+
39
+ static VALUE
40
+ rb_streaming_decompress_allocate(VALUE klass)
41
+ {
42
+ struct streaming_decompress_t* sd;
43
+ VALUE obj = TypedData_Make_Struct(klass, struct streaming_decompress_t, &streaming_decompress_type, sd);
44
+ sd->ctx = NULL;
45
+ sd->buf = Qnil;
46
+ sd->buf_size = 0;
47
+ return obj;
48
+ }
49
+
50
+ static VALUE
51
+ rb_streaming_decompress_initialize(VALUE obj)
52
+ {
53
+ struct streaming_decompress_t* sd;
54
+ TypedData_Get_Struct(obj, struct streaming_decompress_t, &streaming_decompress_type, sd);
55
+ size_t const buffOutSize = ZSTD_DStreamOutSize();
56
+
57
+ ZSTD_DCtx* ctx = ZSTD_createDCtx();
58
+ if (ctx == NULL) {
59
+ rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDCtx error");
60
+ }
61
+ sd->ctx = ctx;
62
+ sd->buf = rb_str_new(NULL, buffOutSize);
63
+ sd->buf_size = buffOutSize;
64
+
65
+ return obj;
66
+ }
67
+
68
+ static VALUE
69
+ rb_streaming_decompress_decompress(VALUE obj, VALUE src)
70
+ {
71
+ StringValue(src);
72
+ const char* input_data = RSTRING_PTR(src);
73
+ size_t input_size = RSTRING_LEN(src);
74
+ ZSTD_inBuffer input = { input_data, input_size, 0 };
75
+
76
+ struct streaming_decompress_t* sd;
77
+ TypedData_Get_Struct(obj, struct streaming_decompress_t, &streaming_decompress_type, sd);
78
+ const char* output_data = RSTRING_PTR(sd->buf);
79
+ VALUE result = rb_str_new(0, 0);
80
+ while (input.pos < input.size) {
81
+ ZSTD_outBuffer output = { (void*)output_data, sd->buf_size, 0 };
82
+ size_t const ret = ZSTD_decompressStream(sd->ctx, &output, &input);
83
+ if (ZSTD_isError(ret)) {
84
+ rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(ret));
85
+ }
86
+ rb_str_cat(result, output.dst, output.pos);
87
+ }
88
+ return result;
89
+ }
90
+
91
+ static VALUE
92
+ rb_streaming_decompress_addstr(VALUE obj, VALUE src)
93
+ {
94
+ StringValue(src);
95
+ const char* input_data = RSTRING_PTR(src);
96
+ size_t input_size = RSTRING_LEN(src);
97
+ ZSTD_inBuffer input = { input_data, input_size, 0 };
98
+
99
+ struct streaming_decompress_t* sd;
100
+ TypedData_Get_Struct(obj, struct streaming_decompress_t, &streaming_decompress_type, sd);
101
+ const char* output_data = RSTRING_PTR(sd->buf);
102
+
103
+ while (input.pos < input.size) {
104
+ ZSTD_outBuffer output = { (void*)output_data, sd->buf_size, 0 };
105
+ size_t const result = ZSTD_decompressStream(sd->ctx, &output, &input);
106
+ if (ZSTD_isError(result)) {
107
+ rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(result));
108
+ }
109
+ }
110
+ return obj;
111
+ }
112
+
113
+ extern VALUE rb_mZstd, cStreamingDecompress;
114
+ void
115
+ zstd_ruby_streaming_decompress_init(void)
116
+ {
117
+ VALUE cStreamingDecompress = rb_define_class_under(rb_mZstd, "StreamingDecompress", rb_cObject);
118
+ rb_define_alloc_func(cStreamingDecompress, rb_streaming_decompress_allocate);
119
+ rb_define_method(cStreamingDecompress, "initialize", rb_streaming_decompress_initialize, 0);
120
+ rb_define_method(cStreamingDecompress, "decompress", rb_streaming_decompress_decompress, 1);
121
+ rb_define_method(cStreamingDecompress, "<<", rb_streaming_decompress_addstr, 1);
122
+ }
123
+
@@ -1,5 +1,6 @@
1
- #include "zstdruby.h"
2
- #include "./libzstd/zstd.h"
1
+ #include <common.h>
2
+
3
+ extern VALUE rb_mZstd;
3
4
 
4
5
  static VALUE zstdVersion(VALUE self)
5
6
  {
@@ -7,41 +8,74 @@ static VALUE zstdVersion(VALUE self)
7
8
  return INT2NUM(version);
8
9
  }
9
10
 
10
- static VALUE compress(int argc, VALUE *argv, VALUE self)
11
+ static VALUE rb_compress(int argc, VALUE *argv, VALUE self)
11
12
  {
12
13
  VALUE input_value;
13
14
  VALUE compression_level_value;
14
15
  rb_scan_args(argc, argv, "11", &input_value, &compression_level_value);
16
+ int compression_level = convert_compression_level(compression_level_value);
15
17
 
16
18
  StringValue(input_value);
17
- const char* input_data = RSTRING_PTR(input_value);
19
+ char* input_data = RSTRING_PTR(input_value);
18
20
  size_t input_size = RSTRING_LEN(input_value);
21
+ size_t max_compressed_size = ZSTD_compressBound(input_size);
19
22
 
20
- int compression_level;
21
- if (NIL_P(compression_level_value)) {
22
- compression_level = 0; // The default. See ZSTD_CLEVEL_DEFAULT in zstd_compress.c
23
- } else {
24
- 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));
25
29
  }
26
30
 
27
- // 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);
28
46
  size_t max_compressed_size = ZSTD_compressBound(input_size);
29
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
+
30
61
  VALUE output = rb_str_new(NULL, max_compressed_size);
31
62
  char* output_data = RSTRING_PTR(output);
32
-
33
- size_t compressed_size = ZSTD_compress((void*)output_data, max_compressed_size,
34
- (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);
35
65
 
36
66
  if (ZSTD_isError(compressed_size)) {
67
+ ZSTD_freeCDict(cdict);
68
+ ZSTD_freeCCtx(ctx);
37
69
  rb_raise(rb_eRuntimeError, "%s: %s", "compress failed", ZSTD_getErrorName(compressed_size));
38
- } else {
39
- rb_str_resize(output, compressed_size);
40
70
  }
41
71
 
72
+ rb_str_resize(output, compressed_size);
73
+ ZSTD_freeCDict(cdict);
74
+ ZSTD_freeCCtx(ctx);
42
75
  return output;
43
76
  }
44
77
 
78
+
45
79
  static VALUE decompress_buffered(const char* input_data, size_t input_size)
46
80
  {
47
81
  const size_t outputBufferSize = 4096;
@@ -57,7 +91,6 @@ static VALUE decompress_buffered(const char* input_data, size_t input_size)
57
91
  rb_raise(rb_eRuntimeError, "%s: %s", "ZSTD_initDStream failed", ZSTD_getErrorName(initResult));
58
92
  }
59
93
 
60
-
61
94
  VALUE output_string = rb_str_new(NULL, 0);
62
95
  ZSTD_outBuffer output = { NULL, 0, 0 };
63
96
 
@@ -79,23 +112,24 @@ static VALUE decompress_buffered(const char* input_data, size_t input_size)
79
112
  return output_string;
80
113
  }
81
114
 
82
- static VALUE decompress(VALUE self, VALUE input)
115
+ static VALUE rb_decompress(VALUE self, VALUE input_value)
83
116
  {
84
- StringValue(input);
85
- const char* input_data = RSTRING_PTR(input);
86
- size_t input_size = RSTRING_LEN(input);
87
-
88
- 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);
89
120
 
90
- 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) {
91
126
  return decompress_buffered(input_data, input_size);
92
127
  }
93
128
 
94
129
  VALUE output = rb_str_new(NULL, uncompressed_size);
95
130
  char* output_data = RSTRING_PTR(output);
96
-
97
- size_t decompress_size = ZSTD_decompress((void*)output_data, uncompressed_size,
98
- (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);
99
133
 
100
134
  if (ZSTD_isError(decompress_size)) {
101
135
  rb_raise(rb_eRuntimeError, "%s: %s", "decompress error", ZSTD_getErrorName(decompress_size));
@@ -104,13 +138,61 @@ static VALUE decompress(VALUE self, VALUE input)
104
138
  return output;
105
139
  }
106
140
 
107
- VALUE rb_mZstd;
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
+ }
108
189
 
109
190
  void
110
- Init_zstdruby(void)
191
+ zstd_ruby_init(void)
111
192
  {
112
- rb_mZstd = rb_define_module("Zstd");
113
193
  rb_define_module_function(rb_mZstd, "zstd_version", zstdVersion, 0);
114
- rb_define_module_function(rb_mZstd, "compress", compress, -1);
115
- 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);
116
198
  }
@@ -1,3 +1,3 @@
1
1
  module Zstd
2
- VERSION = "1.5.2.0"
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