zstd-ruby 1.5.7.1 → 2.0.0.pre.preview1

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: 0a831f7214f9a1a344bdb30a7e969d4ed7ecbf90c3c909c463e600167168060c
4
- data.tar.gz: 3979c655745321a2dc26bd54888e0cd5f072f666dc8b50b8fe97b7d18c2540f7
3
+ metadata.gz: b3fef282bc259f5b954abd4641462fcab60068f0e08ed0d166478c8de4c2005c
4
+ data.tar.gz: 543f92bc5984e4e9ced2ed89d23ce6ba091746605f22a19af0465dcdf22f98c6
5
5
  SHA512:
6
- metadata.gz: 9be787af166434f6d56a9bfcaad31e9832f134a0d08a08b657137b3c1983ebc1334c0bc5580e7480005bf4ae1fedd694fa1c36891fd73b39f1676f9e9226ff05
7
- data.tar.gz: 70456cc157ce7c20a4320049281ff5e99601f5334211c5dac2e94fed162285c4392bf03bcc4dac79f995db792ee6370265de41ce2b4aee388cbcd329b48da785
6
+ metadata.gz: 40fb6622a2cc3b8df4eee5218ad2bad4f130c910bf8b0ba838f9dd578be95b27e578b0cc77ec92511bbf717834e0034850ffc969b7b749618f316f13b7cd6c0a
7
+ data.tar.gz: f2f877a787c617e6ab76a66b2492b631b5a19c6cc09f0fc5e075c58badc6e0228cfa94926f32289525a96d23f40de853c9ceeb5ee0ba01d917ecdc5bc8529bd2
data/README.md CHANGED
@@ -12,6 +12,20 @@ Fork from https://github.com/jarredholman/ruby-zstd.
12
12
  ## Zstd version
13
13
  [v1.5.7](https://github.com/facebook/zstd/tree/v1.5.7)
14
14
 
15
+ ## Versioning Policy
16
+
17
+ Starting from v2.0.0, this gem follows Semantic Versioning.
18
+
19
+ - **Major version** (X.0.0): Breaking changes to the API
20
+ - **Minor version** (X.Y.0): New features, including Zstd library version updates
21
+ - **Patch version** (X.Y.Z): Bug fixes and other backward-compatible changes
22
+
23
+ ### Zstd Library Updates
24
+
25
+ Updates to the underlying Zstd library version will be released as **minor version** updates, as they may introduce new features or performance improvements while maintaining backward compatibility.
26
+
27
+ **Note**: Versions prior to v2.0.0 followed the Zstd library versioning scheme with an additional patch number (e.g., 1.5.6.2). This approach has been replaced with semantic versioning to provide clearer expectations for API stability.
28
+
15
29
  ## Installation
16
30
 
17
31
  Add this line to your application's Gemfile:
@@ -155,6 +169,20 @@ result << stream.decompress(cstr[10..-1])
155
169
 
156
170
  DDict can also be specified to `dict:`.
157
171
 
172
+ #### Streaming Decompression with Position Tracking
173
+
174
+ If you need to know how much of the input data was consumed during decompression, you can use the `decompress_with_pos` method:
175
+
176
+ ```ruby
177
+ cstr = "" # Compressed data
178
+ stream = Zstd::StreamingDecompress.new
179
+ result, consumed_bytes = stream.decompress_with_pos(cstr[0, 10])
180
+ # result contains the decompressed data
181
+ # consumed_bytes contains the number of bytes from input that were processed
182
+ ```
183
+
184
+ This is particularly useful when processing streaming data where you need to track the exact position in the input stream.
185
+
158
186
  ### Skippable frame
159
187
 
160
188
  ```ruby
@@ -18,7 +18,7 @@ static int convert_compression_level(VALUE compression_level_value)
18
18
  return NUM2INT(compression_level_value);
19
19
  }
20
20
 
21
- static void set_compress_params(ZSTD_CCtx* const ctx, VALUE level_from_args, VALUE kwargs)
21
+ static void set_compress_params(ZSTD_CCtx* const ctx, VALUE kwargs)
22
22
  {
23
23
  ID kwargs_keys[2];
24
24
  kwargs_keys[0] = rb_intern("level");
@@ -29,9 +29,6 @@ static void set_compress_params(ZSTD_CCtx* const ctx, VALUE level_from_args, VAL
29
29
  int compression_level = ZSTD_CLEVEL_DEFAULT;
30
30
  if (kwargs_values[0] != Qundef && kwargs_values[0] != Qnil) {
31
31
  compression_level = convert_compression_level(kwargs_values[0]);
32
- } else if (!NIL_P(level_from_args)) {
33
- rb_warn("`level` in args is deprecated; use keyword args `level:` instead.");
34
- compression_level = convert_compression_level(level_from_args);
35
32
  }
36
33
  ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, compression_level);
37
34
 
@@ -0,0 +1 @@
1
+ _Init_zstdruby
@@ -2,9 +2,14 @@ require "mkmf"
2
2
 
3
3
  have_func('rb_gc_mark_movable')
4
4
 
5
- $CFLAGS = '-I. -O3 -std=c99 -DZSTD_STATIC_LINKING_ONLY -DZSTD_MULTITHREAD -pthread -DDEBUGLEVEL=0'
5
+ $CFLAGS = '-I. -O3 -std=c99 -DZSTD_STATIC_LINKING_ONLY -DZSTD_MULTITHREAD -pthread -DDEBUGLEVEL=0 -fvisibility=hidden -DZSTDLIB_VISIBLE=\'__attribute__((visibility("hidden")))\' -DZSTDLIB_HIDDEN=\'__attribute__((visibility("hidden")))\''
6
6
  $CPPFLAGS += " -fdeclspec" if CONFIG['CXX'] =~ /clang/
7
7
 
8
+ # macOS specific: Use exported_symbols_list to control symbol visibility
9
+ if RUBY_PLATFORM =~ /darwin/
10
+ $LDFLAGS += " -exported_symbols_list #{File.expand_path('exports.txt', __dir__)}"
11
+ end
12
+
8
13
  Dir.chdir File.expand_path('..', __FILE__) do
9
14
  $srcs = Dir['**/*.c', '**/*.S']
10
15
 
data/ext/zstdruby/main.c CHANGED
@@ -8,7 +8,7 @@ void zstd_ruby_skippable_frame_init(void);
8
8
  void zstd_ruby_streaming_compress_init(void);
9
9
  void zstd_ruby_streaming_decompress_init(void);
10
10
 
11
- void
11
+ RUBY_FUNC_EXPORTED void
12
12
  Init_zstdruby(void)
13
13
  {
14
14
  #ifdef HAVE_RB_EXT_RACTOR_SAFE
@@ -4,7 +4,6 @@ struct streaming_compress_t {
4
4
  ZSTD_CCtx* ctx;
5
5
  VALUE buf;
6
6
  size_t buf_size;
7
- VALUE pending; /* accumulate compressed bytes produced by write() */
8
7
  };
9
8
 
10
9
  static void
@@ -13,10 +12,8 @@ streaming_compress_mark(void *p)
13
12
  struct streaming_compress_t *sc = p;
14
13
  #ifdef HAVE_RB_GC_MARK_MOVABLE
15
14
  rb_gc_mark_movable(sc->buf);
16
- rb_gc_mark_movable(sc->pending);
17
15
  #else
18
16
  rb_gc_mark(sc->buf);
19
- rb_gc_mark(sc->pending);
20
17
  #endif
21
18
  }
22
19
 
@@ -43,7 +40,6 @@ streaming_compress_compact(void *p)
43
40
  {
44
41
  struct streaming_compress_t *sc = p;
45
42
  sc->buf = rb_gc_location(sc->buf);
46
- sc->pending = rb_gc_location(sc->pending);
47
43
  }
48
44
  #endif
49
45
 
@@ -68,7 +64,6 @@ rb_streaming_compress_allocate(VALUE klass)
68
64
  sc->ctx = NULL;
69
65
  sc->buf = Qnil;
70
66
  sc->buf_size = 0;
71
- sc->pending = Qnil;
72
67
  return obj;
73
68
  }
74
69
 
@@ -76,8 +71,7 @@ static VALUE
76
71
  rb_streaming_compress_initialize(int argc, VALUE *argv, VALUE obj)
77
72
  {
78
73
  VALUE kwargs;
79
- VALUE compression_level_value;
80
- rb_scan_args(argc, argv, "01:", &compression_level_value, &kwargs);
74
+ rb_scan_args(argc, argv, "00:", &kwargs);
81
75
 
82
76
  struct streaming_compress_t* sc;
83
77
  TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
@@ -87,12 +81,11 @@ rb_streaming_compress_initialize(int argc, VALUE *argv, VALUE obj)
87
81
  if (ctx == NULL) {
88
82
  rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCCtx error");
89
83
  }
90
- set_compress_params(ctx, compression_level_value, kwargs);
84
+ set_compress_params(ctx, kwargs);
91
85
 
92
86
  sc->ctx = ctx;
93
87
  sc->buf = rb_str_new(NULL, buffOutSize);
94
88
  sc->buf_size = buffOutSize;
95
- sc->pending = rb_str_new(0, 0);
96
89
 
97
90
  return obj;
98
91
  }
@@ -149,6 +142,7 @@ static VALUE
149
142
  rb_streaming_compress_write(int argc, VALUE *argv, VALUE obj)
150
143
  {
151
144
  size_t total = 0;
145
+ VALUE result = rb_str_new(0, 0);
152
146
  struct streaming_compress_t* sc;
153
147
  TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
154
148
  const char* output_data = RSTRING_PTR(sc->buf);
@@ -166,10 +160,6 @@ rb_streaming_compress_write(int argc, VALUE *argv, VALUE obj)
166
160
  if (ZSTD_isError(ret)) {
167
161
  rb_raise(rb_eRuntimeError, "compress error error code: %s", ZSTD_getErrorName(ret));
168
162
  }
169
- /* collect produced bytes */
170
- if (output.pos > 0) {
171
- rb_str_cat(sc->pending, output.dst, output.pos);
172
- }
173
163
  total += RSTRING_LEN(str);
174
164
  }
175
165
  }
@@ -202,11 +192,8 @@ rb_streaming_compress_flush(VALUE obj)
202
192
  {
203
193
  struct streaming_compress_t* sc;
204
194
  TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
205
- VALUE drained = no_compress(sc, ZSTD_e_flush);
206
- rb_str_cat(sc->pending, RSTRING_PTR(drained), RSTRING_LEN(drained));
207
- VALUE out = sc->pending;
208
- sc->pending = rb_str_new(0, 0);
209
- return out;
195
+ VALUE result = no_compress(sc, ZSTD_e_flush);
196
+ return result;
210
197
  }
211
198
 
212
199
  static VALUE
@@ -214,11 +201,8 @@ rb_streaming_compress_finish(VALUE obj)
214
201
  {
215
202
  struct streaming_compress_t* sc;
216
203
  TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
217
- VALUE drained = no_compress(sc, ZSTD_e_end);
218
- rb_str_cat(sc->pending, RSTRING_PTR(drained), RSTRING_LEN(drained));
219
- VALUE out = sc->pending;
220
- sc->pending = rb_str_new(0, 0);
221
- return out;
204
+ VALUE result = no_compress(sc, ZSTD_e_end);
205
+ return result;
222
206
  }
223
207
 
224
208
  extern VALUE rb_mZstd, cStreamingCompress;
@@ -113,6 +113,27 @@ rb_streaming_decompress_decompress(VALUE obj, VALUE src)
113
113
  return result;
114
114
  }
115
115
 
116
+ static VALUE
117
+ rb_streaming_decompress_decompress_with_pos(VALUE obj, VALUE src)
118
+ {
119
+ StringValue(src);
120
+ const char* input_data = RSTRING_PTR(src);
121
+ size_t input_size = RSTRING_LEN(src);
122
+ ZSTD_inBuffer input = { input_data, input_size, 0 };
123
+
124
+ struct streaming_decompress_t* sd;
125
+ TypedData_Get_Struct(obj, struct streaming_decompress_t, &streaming_decompress_type, sd);
126
+ const char* output_data = RSTRING_PTR(sd->buf);
127
+ VALUE result = rb_str_new(0, 0);
128
+ ZSTD_outBuffer output = { (void*)output_data, sd->buf_size, 0 };
129
+ size_t const ret = zstd_stream_decompress(sd->dctx, &output, &input, false);
130
+ if (ZSTD_isError(ret)) {
131
+ rb_raise(rb_eRuntimeError, "decompress error error code: %s", ZSTD_getErrorName(ret));
132
+ }
133
+ rb_str_cat(result, output.dst, output.pos);
134
+ return rb_ary_new_from_args(2, result, ULONG2NUM(input.pos));
135
+ }
136
+
116
137
  extern VALUE rb_mZstd, cStreamingDecompress;
117
138
  void
118
139
  zstd_ruby_streaming_decompress_init(void)
@@ -121,4 +142,5 @@ zstd_ruby_streaming_decompress_init(void)
121
142
  rb_define_alloc_func(cStreamingDecompress, rb_streaming_decompress_allocate);
122
143
  rb_define_method(cStreamingDecompress, "initialize", rb_streaming_decompress_initialize, -1);
123
144
  rb_define_method(cStreamingDecompress, "decompress", rb_streaming_decompress_decompress, 1);
145
+ rb_define_method(cStreamingDecompress, "decompress_with_pos", rb_streaming_decompress_decompress_with_pos, 1);
124
146
  }
@@ -11,16 +11,15 @@ static VALUE zstdVersion(VALUE self)
11
11
  static VALUE rb_compress(int argc, VALUE *argv, VALUE self)
12
12
  {
13
13
  VALUE input_value;
14
- VALUE compression_level_value;
15
14
  VALUE kwargs;
16
- rb_scan_args(argc, argv, "11:", &input_value, &compression_level_value, &kwargs);
15
+ rb_scan_args(argc, argv, "10:", &input_value, &kwargs);
17
16
 
18
17
  ZSTD_CCtx* const ctx = ZSTD_createCCtx();
19
18
  if (ctx == NULL) {
20
19
  rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCCtx error");
21
20
  }
22
21
 
23
- set_compress_params(ctx, compression_level_value, kwargs);
22
+ set_compress_params(ctx, kwargs);
24
23
 
25
24
  StringValue(input_value);
26
25
  char* input_data = RSTRING_PTR(input_value);
@@ -40,51 +39,6 @@ static VALUE rb_compress(int argc, VALUE *argv, VALUE self)
40
39
  return output;
41
40
  }
42
41
 
43
- static VALUE rb_compress_using_dict(int argc, VALUE *argv, VALUE self)
44
- {
45
- rb_warn("Zstd.compress_using_dict is deprecated; use Zstd.compress with `dict:` instead.");
46
- VALUE input_value;
47
- VALUE dict;
48
- VALUE compression_level_value;
49
- rb_scan_args(argc, argv, "21", &input_value, &dict, &compression_level_value);
50
- int compression_level = convert_compression_level(compression_level_value);
51
-
52
- StringValue(input_value);
53
- char* input_data = RSTRING_PTR(input_value);
54
- size_t input_size = RSTRING_LEN(input_value);
55
- size_t max_compressed_size = ZSTD_compressBound(input_size);
56
-
57
- char* dict_buffer = RSTRING_PTR(dict);
58
- size_t dict_size = RSTRING_LEN(dict);
59
-
60
- ZSTD_CDict* const cdict = ZSTD_createCDict(dict_buffer, dict_size, compression_level);
61
- if (cdict == NULL) {
62
- rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCDict failed");
63
- }
64
- ZSTD_CCtx* const ctx = ZSTD_createCCtx();
65
- if (ctx == NULL) {
66
- ZSTD_freeCDict(cdict);
67
- rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCCtx failed");
68
- }
69
-
70
- VALUE output = rb_str_new(NULL, max_compressed_size);
71
- char* output_data = RSTRING_PTR(output);
72
- size_t const compressed_size = ZSTD_compress_usingCDict(ctx, (void*)output_data, max_compressed_size,
73
- (void*)input_data, input_size, cdict);
74
-
75
- if (ZSTD_isError(compressed_size)) {
76
- ZSTD_freeCDict(cdict);
77
- ZSTD_freeCCtx(ctx);
78
- rb_raise(rb_eRuntimeError, "%s: %s", "compress failed", ZSTD_getErrorName(compressed_size));
79
- }
80
-
81
- rb_str_resize(output, compressed_size);
82
- ZSTD_freeCDict(cdict);
83
- ZSTD_freeCCtx(ctx);
84
- return output;
85
- }
86
-
87
-
88
42
  static VALUE decompress_buffered(ZSTD_DCtx* dctx, const char* input_data, size_t input_size)
89
43
  {
90
44
  ZSTD_inBuffer input = { input_data, input_size, 0 };
@@ -142,59 +96,6 @@ static VALUE rb_decompress(int argc, VALUE *argv, VALUE self)
142
96
  return output;
143
97
  }
144
98
 
145
- static VALUE rb_decompress_using_dict(int argc, VALUE *argv, VALUE self)
146
- {
147
- rb_warn("Zstd.decompress_using_dict is deprecated; use Zstd.decompress with `dict:` instead.");
148
- VALUE input_value;
149
- VALUE dict;
150
- rb_scan_args(argc, argv, "20", &input_value, &dict);
151
-
152
- StringValue(input_value);
153
- char* input_data = RSTRING_PTR(input_value);
154
- size_t input_size = RSTRING_LEN(input_value);
155
-
156
- char* dict_buffer = RSTRING_PTR(dict);
157
- size_t dict_size = RSTRING_LEN(dict);
158
- ZSTD_DDict* const ddict = ZSTD_createDDict(dict_buffer, dict_size);
159
- if (ddict == NULL) {
160
- rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDDict failed");
161
- }
162
- unsigned const expected_dict_id = ZSTD_getDictID_fromDDict(ddict);
163
- unsigned const actual_dict_id = ZSTD_getDictID_fromFrame(input_data, input_size);
164
- if (expected_dict_id != actual_dict_id) {
165
- ZSTD_freeDDict(ddict);
166
- rb_raise(rb_eRuntimeError, "DictID mismatch");
167
- }
168
-
169
- ZSTD_DCtx* const ctx = ZSTD_createDCtx();
170
- if (ctx == NULL) {
171
- ZSTD_freeDDict(ddict);
172
- rb_raise(rb_eRuntimeError, "%s", "ZSTD_createDCtx failed");
173
- }
174
-
175
- unsigned long long const uncompressed_size = ZSTD_getFrameContentSize(input_data, input_size);
176
- if (uncompressed_size == ZSTD_CONTENTSIZE_ERROR) {
177
- ZSTD_freeDDict(ddict);
178
- ZSTD_freeDCtx(ctx);
179
- rb_raise(rb_eRuntimeError, "%s: %s", "not compressed by zstd", ZSTD_getErrorName(uncompressed_size));
180
- }
181
- if (uncompressed_size == ZSTD_CONTENTSIZE_UNKNOWN) {
182
- return decompress_buffered(ctx, input_data, input_size);
183
- }
184
-
185
- VALUE output = rb_str_new(NULL, uncompressed_size);
186
- char* output_data = RSTRING_PTR(output);
187
- size_t const decompress_size = ZSTD_decompress_usingDDict(ctx, output_data, uncompressed_size, input_data, input_size, ddict);
188
- if (ZSTD_isError(decompress_size)) {
189
- ZSTD_freeDDict(ddict);
190
- ZSTD_freeDCtx(ctx);
191
- rb_raise(rb_eRuntimeError, "%s: %s", "decompress error", ZSTD_getErrorName(decompress_size));
192
- }
193
- ZSTD_freeDDict(ddict);
194
- ZSTD_freeDCtx(ctx);
195
- return output;
196
- }
197
-
198
99
  static void free_cdict(void *dict)
199
100
  {
200
101
  ZSTD_freeCDict(dict);
@@ -284,9 +185,7 @@ zstd_ruby_init(void)
284
185
  {
285
186
  rb_define_module_function(rb_mZstd, "zstd_version", zstdVersion, 0);
286
187
  rb_define_module_function(rb_mZstd, "compress", rb_compress, -1);
287
- rb_define_module_function(rb_mZstd, "compress_using_dict", rb_compress_using_dict, -1);
288
188
  rb_define_module_function(rb_mZstd, "decompress", rb_decompress, -1);
289
- rb_define_module_function(rb_mZstd, "decompress_using_dict", rb_decompress_using_dict, -1);
290
189
 
291
190
  rb_define_alloc_func(rb_cCDict, rb_cdict_alloc);
292
191
  rb_define_private_method(rb_cCDict, "initialize", rb_cdict_initialize, -1);
@@ -1,3 +1,3 @@
1
1
  module Zstd
2
- VERSION = "1.5.7.1"
2
+ VERSION = "2.0.0-preview1"
3
3
  end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zstd-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.7.1
4
+ version: 2.0.0.pre.preview1
5
5
  platform: ruby
6
6
  authors:
7
7
  - SpringMT
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 2025-09-26 00:00:00.000000000 Z
11
+ date: 2025-07-26 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: bundler
@@ -99,6 +100,7 @@ files:
99
100
  - bin/console
100
101
  - bin/setup
101
102
  - ext/zstdruby/common.h
103
+ - ext/zstdruby/exports.txt
102
104
  - ext/zstdruby/extconf.rb
103
105
  - ext/zstdruby/libzstd/common/allocations.h
104
106
  - ext/zstdruby/libzstd/common/bits.h
@@ -186,6 +188,7 @@ homepage: https://github.com/SpringMT/zstd-ruby
186
188
  licenses:
187
189
  - MIT
188
190
  metadata: {}
191
+ post_install_message:
189
192
  rdoc_options: []
190
193
  require_paths:
191
194
  - lib
@@ -196,11 +199,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
196
199
  version: '0'
197
200
  required_rubygems_version: !ruby/object:Gem::Requirement
198
201
  requirements:
199
- - - ">="
202
+ - - ">"
200
203
  - !ruby/object:Gem::Version
201
- version: '0'
204
+ version: 1.3.1
202
205
  requirements: []
203
- rubygems_version: 3.6.2
206
+ rubygems_version: 3.4.19
207
+ signing_key:
204
208
  specification_version: 4
205
209
  summary: Ruby binding for zstd(Zstandard - Fast real-time compression algorithm)
206
210
  test_files: []