zstd-ruby 1.5.7.0 → 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 +4 -4
- data/README.md +28 -0
- data/ext/zstdruby/common.h +1 -4
- data/ext/zstdruby/exports.txt +1 -0
- data/ext/zstdruby/extconf.rb +6 -1
- data/ext/zstdruby/main.c +1 -1
- data/ext/zstdruby/streaming_compress.c +2 -3
- data/ext/zstdruby/streaming_decompress.c +22 -0
- data/ext/zstdruby/zstdruby.c +2 -103
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3fef282bc259f5b954abd4641462fcab60068f0e08ed0d166478c8de4c2005c
|
4
|
+
data.tar.gz: 543f92bc5984e4e9ced2ed89d23ce6ba091746605f22a19af0465dcdf22f98c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/ext/zstdruby/common.h
CHANGED
@@ -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
|
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
|
data/ext/zstdruby/extconf.rb
CHANGED
@@ -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
@@ -71,8 +71,7 @@ static VALUE
|
|
71
71
|
rb_streaming_compress_initialize(int argc, VALUE *argv, VALUE obj)
|
72
72
|
{
|
73
73
|
VALUE kwargs;
|
74
|
-
|
75
|
-
rb_scan_args(argc, argv, "01:", &compression_level_value, &kwargs);
|
74
|
+
rb_scan_args(argc, argv, "00:", &kwargs);
|
76
75
|
|
77
76
|
struct streaming_compress_t* sc;
|
78
77
|
TypedData_Get_Struct(obj, struct streaming_compress_t, &streaming_compress_type, sc);
|
@@ -82,7 +81,7 @@ rb_streaming_compress_initialize(int argc, VALUE *argv, VALUE obj)
|
|
82
81
|
if (ctx == NULL) {
|
83
82
|
rb_raise(rb_eRuntimeError, "%s", "ZSTD_createCCtx error");
|
84
83
|
}
|
85
|
-
set_compress_params(ctx,
|
84
|
+
set_compress_params(ctx, kwargs);
|
86
85
|
|
87
86
|
sc->ctx = ctx;
|
88
87
|
sc->buf = rb_str_new(NULL, buffOutSize);
|
@@ -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
|
}
|
data/ext/zstdruby/zstdruby.c
CHANGED
@@ -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, "
|
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,
|
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);
|
data/lib/zstd-ruby/version.rb
CHANGED
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:
|
4
|
+
version: 2.0.0.pre.preview1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SpringMT
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-07-
|
11
|
+
date: 2025-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -100,6 +100,7 @@ files:
|
|
100
100
|
- bin/console
|
101
101
|
- bin/setup
|
102
102
|
- ext/zstdruby/common.h
|
103
|
+
- ext/zstdruby/exports.txt
|
103
104
|
- ext/zstdruby/extconf.rb
|
104
105
|
- ext/zstdruby/libzstd/common/allocations.h
|
105
106
|
- ext/zstdruby/libzstd/common/bits.h
|
@@ -198,9 +199,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
198
199
|
version: '0'
|
199
200
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
200
201
|
requirements:
|
201
|
-
- - "
|
202
|
+
- - ">"
|
202
203
|
- !ruby/object:Gem::Version
|
203
|
-
version:
|
204
|
+
version: 1.3.1
|
204
205
|
requirements: []
|
205
206
|
rubygems_version: 3.4.19
|
206
207
|
signing_key:
|