ruby-zstds 1.0.6 → 1.1.0
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 +32 -19
- data/ext/extconf.rb +5 -0
- data/ext/zstds_ext/buffer.c +4 -3
- data/ext/zstds_ext/buffer.h +5 -5
- data/ext/zstds_ext/dictionary.c +104 -42
- data/ext/zstds_ext/dictionary.h +1 -1
- data/ext/zstds_ext/error.c +1 -1
- data/ext/zstds_ext/error.h +2 -1
- data/ext/zstds_ext/gvl.h +24 -0
- data/ext/zstds_ext/io.c +229 -137
- data/ext/zstds_ext/option.c +44 -43
- data/ext/zstds_ext/option.h +62 -51
- data/ext/zstds_ext/stream/compressor.c +103 -50
- data/ext/zstds_ext/stream/compressor.h +4 -1
- data/ext/zstds_ext/stream/decompressor.c +46 -22
- data/ext/zstds_ext/stream/decompressor.h +4 -1
- data/ext/zstds_ext/string.c +93 -62
- data/lib/zstds/dictionary.rb +2 -0
- data/lib/zstds/option.rb +6 -0
- data/lib/zstds/version.rb +1 -1
- metadata +23 -8
data/ext/zstds_ext/option.c
CHANGED
@@ -11,12 +11,12 @@
|
|
11
11
|
|
12
12
|
// -- values --
|
13
13
|
|
14
|
-
static inline VALUE
|
14
|
+
static inline VALUE get_raw_value(VALUE options, const char* name)
|
15
15
|
{
|
16
16
|
return rb_funcall(options, rb_intern("[]"), 1, ID2SYM(rb_intern(name)));
|
17
17
|
}
|
18
18
|
|
19
|
-
static inline bool
|
19
|
+
static inline bool get_bool_value(VALUE raw_value)
|
20
20
|
{
|
21
21
|
int raw_type = TYPE(raw_value);
|
22
22
|
if (raw_type != T_TRUE && raw_type != T_FALSE) {
|
@@ -26,67 +26,65 @@ static inline bool get_bool_option_value(VALUE raw_value)
|
|
26
26
|
return raw_type == T_TRUE;
|
27
27
|
}
|
28
28
|
|
29
|
-
static inline unsigned int
|
29
|
+
static inline unsigned int get_uint_value(VALUE raw_value)
|
30
30
|
{
|
31
31
|
Check_Type(raw_value, T_FIXNUM);
|
32
32
|
|
33
33
|
return NUM2UINT(raw_value);
|
34
34
|
}
|
35
35
|
|
36
|
-
static inline int
|
36
|
+
static inline int get_int_value(VALUE raw_value)
|
37
37
|
{
|
38
38
|
Check_Type(raw_value, T_FIXNUM);
|
39
39
|
|
40
40
|
return NUM2INT(raw_value);
|
41
41
|
}
|
42
42
|
|
43
|
-
static inline unsigned long long
|
43
|
+
static inline unsigned long long get_ull_value(VALUE raw_value)
|
44
44
|
{
|
45
45
|
Check_Type(raw_value, T_FIXNUM);
|
46
46
|
|
47
47
|
return NUM2ULL(raw_value);
|
48
48
|
}
|
49
49
|
|
50
|
-
static inline
|
50
|
+
static inline size_t get_size_value(VALUE raw_value)
|
51
|
+
{
|
52
|
+
Check_Type(raw_value, T_FIXNUM);
|
53
|
+
|
54
|
+
return NUM2SIZET(raw_value);
|
55
|
+
}
|
56
|
+
|
57
|
+
static inline ZSTD_strategy get_strategy_value(VALUE raw_value)
|
51
58
|
{
|
52
59
|
Check_Type(raw_value, T_SYMBOL);
|
53
60
|
|
54
61
|
ID raw_id = SYM2ID(raw_value);
|
55
62
|
if (raw_id == rb_intern("fast")) {
|
56
63
|
return ZSTD_fast;
|
57
|
-
}
|
58
|
-
else if (raw_id == rb_intern("dfast")) {
|
64
|
+
} else if (raw_id == rb_intern("dfast")) {
|
59
65
|
return ZSTD_dfast;
|
60
|
-
}
|
61
|
-
else if (raw_id == rb_intern("greedy")) {
|
66
|
+
} else if (raw_id == rb_intern("greedy")) {
|
62
67
|
return ZSTD_greedy;
|
63
|
-
}
|
64
|
-
else if (raw_id == rb_intern("lazy")) {
|
68
|
+
} else if (raw_id == rb_intern("lazy")) {
|
65
69
|
return ZSTD_lazy;
|
66
|
-
}
|
67
|
-
else if (raw_id == rb_intern("lazy2")) {
|
70
|
+
} else if (raw_id == rb_intern("lazy2")) {
|
68
71
|
return ZSTD_lazy2;
|
69
|
-
}
|
70
|
-
else if (raw_id == rb_intern("btlazy2")) {
|
72
|
+
} else if (raw_id == rb_intern("btlazy2")) {
|
71
73
|
return ZSTD_btlazy2;
|
72
|
-
}
|
73
|
-
else if (raw_id == rb_intern("btopt")) {
|
74
|
+
} else if (raw_id == rb_intern("btopt")) {
|
74
75
|
return ZSTD_btopt;
|
75
|
-
}
|
76
|
-
else if (raw_id == rb_intern("btultra")) {
|
76
|
+
} else if (raw_id == rb_intern("btultra")) {
|
77
77
|
return ZSTD_btultra;
|
78
|
-
}
|
79
|
-
else if (raw_id == rb_intern("btultra2")) {
|
78
|
+
} else if (raw_id == rb_intern("btultra2")) {
|
80
79
|
return ZSTD_btultra2;
|
81
|
-
}
|
82
|
-
else {
|
80
|
+
} else {
|
83
81
|
zstds_ext_raise_error(ZSTDS_EXT_ERROR_VALIDATE_FAILED);
|
84
82
|
}
|
85
83
|
}
|
86
84
|
|
87
|
-
void
|
85
|
+
void zstds_ext_resolve_option(VALUE options, zstds_ext_option_t* option, zstds_ext_option_type_t type, const char* name)
|
88
86
|
{
|
89
|
-
VALUE raw_value =
|
87
|
+
VALUE raw_value = get_raw_value(options, name);
|
90
88
|
|
91
89
|
option->has_value = raw_value != Qnil;
|
92
90
|
if (!option->has_value) {
|
@@ -97,16 +95,16 @@ void zstds_ext_get_option(VALUE options, zstds_ext_option_t* option, zstds_ext_o
|
|
97
95
|
|
98
96
|
switch (type) {
|
99
97
|
case ZSTDS_EXT_OPTION_TYPE_BOOL:
|
100
|
-
value =
|
98
|
+
value = get_bool_value(raw_value) ? 1 : 0;
|
101
99
|
break;
|
102
100
|
case ZSTDS_EXT_OPTION_TYPE_UINT:
|
103
|
-
value = (zstds_ext_option_value_t)
|
101
|
+
value = (zstds_ext_option_value_t) get_uint_value(raw_value);
|
104
102
|
break;
|
105
103
|
case ZSTDS_EXT_OPTION_TYPE_INT:
|
106
|
-
value = (zstds_ext_option_value_t)
|
104
|
+
value = (zstds_ext_option_value_t) get_int_value(raw_value);
|
107
105
|
break;
|
108
106
|
case ZSTDS_EXT_OPTION_TYPE_STRATEGY:
|
109
|
-
value = (zstds_ext_option_value_t)
|
107
|
+
value = (zstds_ext_option_value_t) get_strategy_value(raw_value);
|
110
108
|
break;
|
111
109
|
default:
|
112
110
|
zstds_ext_raise_error(ZSTDS_EXT_ERROR_UNEXPECTED);
|
@@ -115,19 +113,19 @@ void zstds_ext_get_option(VALUE options, zstds_ext_option_t* option, zstds_ext_o
|
|
115
113
|
option->value = value;
|
116
114
|
}
|
117
115
|
|
118
|
-
void
|
116
|
+
void zstds_ext_resolve_ull_option(VALUE options, zstds_ext_ull_option_t* option, const char* name)
|
119
117
|
{
|
120
|
-
VALUE raw_value =
|
118
|
+
VALUE raw_value = get_raw_value(options, name);
|
121
119
|
|
122
120
|
option->has_value = raw_value != Qnil;
|
123
121
|
if (option->has_value) {
|
124
|
-
option->value = (zstds_ext_ull_option_value_t)
|
122
|
+
option->value = (zstds_ext_ull_option_value_t) get_ull_value(raw_value);
|
125
123
|
}
|
126
124
|
}
|
127
125
|
|
128
|
-
void
|
126
|
+
void zstds_ext_resolve_dictionary_option(VALUE options, VALUE* option, const char* name)
|
129
127
|
{
|
130
|
-
VALUE raw_value =
|
128
|
+
VALUE raw_value = get_raw_value(options, name);
|
131
129
|
|
132
130
|
if (raw_value != Qnil) {
|
133
131
|
VALUE root_module = rb_define_module(ZSTDS_EXT_MODULE_NAME);
|
@@ -140,13 +138,18 @@ void zstds_ext_get_dictionary_option(VALUE options, VALUE* option, const char* n
|
|
140
138
|
*option = raw_value;
|
141
139
|
}
|
142
140
|
|
143
|
-
|
141
|
+
bool zstds_ext_get_bool_option_value(VALUE options, const char* name)
|
144
142
|
{
|
145
|
-
VALUE raw_value =
|
143
|
+
VALUE raw_value = get_raw_value(options, name);
|
146
144
|
|
147
|
-
|
145
|
+
return get_bool_value(raw_value);
|
146
|
+
}
|
148
147
|
|
149
|
-
|
148
|
+
size_t zstds_ext_get_size_option_value(VALUE options, const char* name)
|
149
|
+
{
|
150
|
+
VALUE raw_value = get_raw_value(options, name);
|
151
|
+
|
152
|
+
return get_size_value(raw_value);
|
150
153
|
}
|
151
154
|
|
152
155
|
// -- set params --
|
@@ -159,8 +162,7 @@ size_t zstds_ext_get_size_option_value(VALUE options, const char* name)
|
|
159
162
|
} \
|
160
163
|
}
|
161
164
|
|
162
|
-
#define SET_COMPRESSOR_PARAM(ctx, param, option)
|
163
|
-
SET_OPTION_VALUE(ZSTD_CCtx_setParameter, ctx, param, option);
|
165
|
+
#define SET_COMPRESSOR_PARAM(ctx, param, option) SET_OPTION_VALUE(ZSTD_CCtx_setParameter, ctx, param, option);
|
164
166
|
|
165
167
|
zstds_ext_result_t zstds_ext_set_compressor_options(ZSTD_CCtx* ctx, zstds_ext_compressor_options_t* options)
|
166
168
|
{
|
@@ -205,8 +207,7 @@ zstds_ext_result_t zstds_ext_set_compressor_options(ZSTD_CCtx* ctx, zstds_ext_co
|
|
205
207
|
return 0;
|
206
208
|
}
|
207
209
|
|
208
|
-
#define SET_DECOMPRESSOR_PARAM(ctx, param, option)
|
209
|
-
SET_OPTION_VALUE(ZSTD_DCtx_setParameter, ctx, param, option);
|
210
|
+
#define SET_DECOMPRESSOR_PARAM(ctx, param, option) SET_OPTION_VALUE(ZSTD_DCtx_setParameter, ctx, param, option);
|
210
211
|
|
211
212
|
zstds_ext_result_t zstds_ext_set_decompressor_options(ZSTD_DCtx* ctx, zstds_ext_decompressor_options_t* options)
|
212
213
|
{
|
data/ext/zstds_ext/option.h
CHANGED
@@ -13,7 +13,8 @@
|
|
13
13
|
// Default option values depends on zstd library.
|
14
14
|
// We will set only user defined values.
|
15
15
|
|
16
|
-
enum
|
16
|
+
enum
|
17
|
+
{
|
17
18
|
ZSTDS_EXT_OPTION_TYPE_BOOL = 1,
|
18
19
|
ZSTDS_EXT_OPTION_TYPE_UINT,
|
19
20
|
ZSTDS_EXT_OPTION_TYPE_INT,
|
@@ -24,17 +25,20 @@ typedef zstds_ext_byte_fast_t zstds_ext_option_type_t;
|
|
24
25
|
typedef int zstds_ext_option_value_t;
|
25
26
|
typedef unsigned long long zstds_ext_ull_option_value_t;
|
26
27
|
|
27
|
-
typedef struct
|
28
|
+
typedef struct
|
29
|
+
{
|
28
30
|
bool has_value;
|
29
31
|
zstds_ext_option_value_t value;
|
30
32
|
} zstds_ext_option_t;
|
31
33
|
|
32
|
-
typedef struct
|
34
|
+
typedef struct
|
35
|
+
{
|
33
36
|
bool has_value;
|
34
37
|
zstds_ext_ull_option_value_t value;
|
35
38
|
} zstds_ext_ull_option_t;
|
36
39
|
|
37
|
-
typedef struct
|
40
|
+
typedef struct
|
41
|
+
{
|
38
42
|
zstds_ext_option_t compression_level;
|
39
43
|
zstds_ext_option_t window_log;
|
40
44
|
zstds_ext_option_t hash_log;
|
@@ -58,59 +62,66 @@ typedef struct {
|
|
58
62
|
VALUE dictionary;
|
59
63
|
} zstds_ext_compressor_options_t;
|
60
64
|
|
61
|
-
typedef struct
|
65
|
+
typedef struct
|
66
|
+
{
|
62
67
|
zstds_ext_option_t window_log_max;
|
63
68
|
VALUE dictionary;
|
64
69
|
} zstds_ext_decompressor_options_t;
|
65
70
|
|
66
|
-
void
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
71
|
+
void zstds_ext_resolve_option(
|
72
|
+
VALUE options,
|
73
|
+
zstds_ext_option_t* option,
|
74
|
+
zstds_ext_option_type_t type,
|
75
|
+
const char* name);
|
76
|
+
|
77
|
+
void zstds_ext_resolve_ull_option(VALUE options, zstds_ext_ull_option_t* option, const char* name);
|
78
|
+
void zstds_ext_resolve_dictionary_option(VALUE options, VALUE* option, const char* name);
|
79
|
+
|
80
|
+
#define ZSTDS_EXT_RESOLVE_OPTION(options, target_options, type, name) \
|
81
|
+
zstds_ext_resolve_option(options, &target_options.name, type, #name);
|
82
|
+
|
83
|
+
#define ZSTDS_EXT_RESOLVE_ULL_OPTION(options, target_options, name) \
|
84
|
+
zstds_ext_resolve_ull_option(options, &target_options.name, #name);
|
85
|
+
|
86
|
+
#define ZSTDS_EXT_RESOLVE_DICTIONARY_OPTION(options, target_options, name) \
|
87
|
+
zstds_ext_resolve_dictionary_option(options, &target_options.name, #name);
|
88
|
+
|
89
|
+
#define ZSTDS_EXT_GET_COMPRESSOR_OPTIONS(options) \
|
90
|
+
zstds_ext_compressor_options_t compressor_options; \
|
91
|
+
\
|
92
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_INT, compression_level); \
|
93
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, window_log); \
|
94
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, hash_log); \
|
95
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, chain_log); \
|
96
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, search_log); \
|
97
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, min_match); \
|
98
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, target_length); \
|
99
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_STRATEGY, strategy); \
|
100
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_BOOL, enable_long_distance_matching); \
|
101
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, ldm_hash_log); \
|
102
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, ldm_min_match); \
|
103
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, ldm_bucket_size_log); \
|
104
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, ldm_hash_rate_log); \
|
105
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_BOOL, content_size_flag); \
|
106
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_BOOL, checksum_flag); \
|
107
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_BOOL, dict_id_flag); \
|
108
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, nb_workers); \
|
109
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, job_size); \
|
110
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, compressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, overlap_log); \
|
111
|
+
ZSTDS_EXT_RESOLVE_ULL_OPTION(options, compressor_options, pledged_size); \
|
112
|
+
ZSTDS_EXT_RESOLVE_DICTIONARY_OPTION(options, compressor_options, dictionary);
|
113
|
+
|
114
|
+
#define ZSTDS_EXT_GET_DECOMPRESSOR_OPTIONS(options) \
|
115
|
+
zstds_ext_decompressor_options_t decompressor_options; \
|
116
|
+
\
|
117
|
+
ZSTDS_EXT_RESOLVE_OPTION(options, decompressor_options, ZSTDS_EXT_OPTION_TYPE_UINT, window_log_max); \
|
118
|
+
ZSTDS_EXT_RESOLVE_DICTIONARY_OPTION(options, decompressor_options, dictionary);
|
119
|
+
|
120
|
+
bool zstds_ext_get_bool_option_value(VALUE options, const char* name);
|
110
121
|
size_t zstds_ext_get_size_option_value(VALUE options, const char* name);
|
111
122
|
|
112
|
-
#define
|
113
|
-
|
123
|
+
#define ZSTDS_EXT_GET_BOOL_OPTION(options, name) size_t name = zstds_ext_get_bool_option_value(options, #name);
|
124
|
+
#define ZSTDS_EXT_GET_SIZE_OPTION(options, name) size_t name = zstds_ext_get_size_option_value(options, #name);
|
114
125
|
|
115
126
|
zstds_ext_result_t zstds_ext_set_compressor_options(ZSTD_CCtx* ctx, zstds_ext_compressor_options_t* options);
|
116
127
|
zstds_ext_result_t zstds_ext_set_decompressor_options(ZSTD_DCtx* ctx, zstds_ext_decompressor_options_t* options);
|
@@ -7,8 +7,11 @@
|
|
7
7
|
|
8
8
|
#include "ruby.h"
|
9
9
|
#include "zstds_ext/error.h"
|
10
|
+
#include "zstds_ext/gvl.h"
|
10
11
|
#include "zstds_ext/option.h"
|
11
12
|
|
13
|
+
// -- initialization --
|
14
|
+
|
12
15
|
static void free_compressor(zstds_ext_compressor_t* compressor_ptr)
|
13
16
|
{
|
14
17
|
ZSTD_CCtx* ctx = compressor_ptr->ctx;
|
@@ -27,14 +30,14 @@ static void free_compressor(zstds_ext_compressor_t* compressor_ptr)
|
|
27
30
|
VALUE zstds_ext_allocate_compressor(VALUE klass)
|
28
31
|
{
|
29
32
|
zstds_ext_compressor_t* compressor_ptr;
|
30
|
-
|
31
|
-
VALUE self = Data_Make_Struct(klass, zstds_ext_compressor_t, NULL, free_compressor, compressor_ptr);
|
33
|
+
VALUE self = Data_Make_Struct(klass, zstds_ext_compressor_t, NULL, free_compressor, compressor_ptr);
|
32
34
|
|
33
35
|
compressor_ptr->ctx = NULL;
|
34
36
|
compressor_ptr->destination_buffer = NULL;
|
35
37
|
compressor_ptr->destination_buffer_length = 0;
|
36
38
|
compressor_ptr->remaining_destination_buffer = NULL;
|
37
39
|
compressor_ptr->remaining_destination_buffer_length = 0;
|
40
|
+
compressor_ptr->gvl = false;
|
38
41
|
|
39
42
|
return self;
|
40
43
|
}
|
@@ -47,8 +50,9 @@ VALUE zstds_ext_initialize_compressor(VALUE self, VALUE options)
|
|
47
50
|
{
|
48
51
|
GET_COMPRESSOR(self);
|
49
52
|
Check_Type(options, T_HASH);
|
53
|
+
ZSTDS_EXT_GET_SIZE_OPTION(options, destination_buffer_length);
|
54
|
+
ZSTDS_EXT_GET_BOOL_OPTION(options, gvl);
|
50
55
|
ZSTDS_EXT_GET_COMPRESSOR_OPTIONS(options);
|
51
|
-
ZSTDS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
|
52
56
|
|
53
57
|
ZSTD_CCtx* ctx = ZSTD_createCCtx();
|
54
58
|
if (ctx == NULL) {
|
@@ -76,40 +80,56 @@ VALUE zstds_ext_initialize_compressor(VALUE self, VALUE options)
|
|
76
80
|
compressor_ptr->destination_buffer_length = destination_buffer_length;
|
77
81
|
compressor_ptr->remaining_destination_buffer = destination_buffer;
|
78
82
|
compressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
|
83
|
+
compressor_ptr->gvl = gvl;
|
79
84
|
|
80
85
|
return Qnil;
|
81
86
|
}
|
82
87
|
|
88
|
+
// -- compress --
|
89
|
+
|
83
90
|
#define DO_NOT_USE_AFTER_CLOSE(compressor_ptr) \
|
84
91
|
if (compressor_ptr->ctx == NULL || compressor_ptr->destination_buffer == NULL) { \
|
85
92
|
zstds_ext_raise_error(ZSTDS_EXT_ERROR_USED_AFTER_CLOSE); \
|
86
93
|
}
|
87
94
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
95
|
+
typedef struct
|
96
|
+
{
|
97
|
+
zstds_ext_compressor_t* compressor_ptr;
|
98
|
+
ZSTD_inBuffer* in_buffer_ptr;
|
99
|
+
ZSTD_outBuffer* out_buffer_ptr;
|
100
|
+
zstds_result_t result;
|
101
|
+
} compress_args_t;
|
102
|
+
|
103
|
+
static inline void* compress_wrapper(void* data)
|
104
|
+
{
|
105
|
+
compress_args_t* args = data;
|
106
|
+
|
107
|
+
args->result =
|
108
|
+
ZSTD_compressStream2(args->compressor_ptr->ctx, args->out_buffer_ptr, args->in_buffer_ptr, ZSTD_e_continue);
|
109
|
+
|
110
|
+
return NULL;
|
111
|
+
}
|
93
112
|
|
94
113
|
VALUE zstds_ext_compress(VALUE self, VALUE source_value)
|
95
114
|
{
|
96
115
|
GET_COMPRESSOR(self);
|
97
116
|
DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
|
98
|
-
|
117
|
+
Check_Type(source_value, T_STRING);
|
99
118
|
|
100
|
-
|
101
|
-
|
102
|
-
in_buffer.size = source_length;
|
103
|
-
in_buffer.pos = 0;
|
119
|
+
const char* source = RSTRING_PTR(source_value);
|
120
|
+
size_t source_length = RSTRING_LEN(source_value);
|
104
121
|
|
105
|
-
|
106
|
-
out_buffer
|
107
|
-
|
108
|
-
|
122
|
+
ZSTD_inBuffer in_buffer = {.src = source, .size = source_length, .pos = 0};
|
123
|
+
ZSTD_outBuffer out_buffer = {
|
124
|
+
.dst = compressor_ptr->remaining_destination_buffer,
|
125
|
+
.size = compressor_ptr->remaining_destination_buffer_length,
|
126
|
+
.pos = 0};
|
109
127
|
|
110
|
-
|
111
|
-
|
112
|
-
|
128
|
+
compress_args_t args = {.compressor_ptr = compressor_ptr, .in_buffer_ptr = &in_buffer, .out_buffer_ptr = &out_buffer};
|
129
|
+
|
130
|
+
ZSTDS_EXT_GVL_WRAP(compressor_ptr->gvl, compress_wrapper, &args);
|
131
|
+
if (ZSTD_isError(args.result)) {
|
132
|
+
zstds_ext_raise_error(zstds_ext_get_error(ZSTD_getErrorCode(args.result)));
|
113
133
|
}
|
114
134
|
|
115
135
|
compressor_ptr->remaining_destination_buffer += out_buffer.pos;
|
@@ -121,32 +141,65 @@ VALUE zstds_ext_compress(VALUE self, VALUE source_value)
|
|
121
141
|
return rb_ary_new_from_args(2, bytes_written, needs_more_destination);
|
122
142
|
}
|
123
143
|
|
144
|
+
// -- compressor flush --
|
145
|
+
|
146
|
+
typedef struct
|
147
|
+
{
|
148
|
+
zstds_ext_compressor_t* compressor_ptr;
|
149
|
+
ZSTD_outBuffer* out_buffer_ptr;
|
150
|
+
zstds_result_t result;
|
151
|
+
} compress_flush_args_t;
|
152
|
+
|
153
|
+
static inline void* compress_flush_wrapper(void* data)
|
154
|
+
{
|
155
|
+
compress_flush_args_t* args = data;
|
156
|
+
ZSTD_inBuffer in_buffer = {.src = NULL, .size = 0, .pos = 0};
|
157
|
+
|
158
|
+
args->result = ZSTD_compressStream2(args->compressor_ptr->ctx, args->out_buffer_ptr, &in_buffer, ZSTD_e_flush);
|
159
|
+
|
160
|
+
return NULL;
|
161
|
+
}
|
162
|
+
|
124
163
|
VALUE zstds_ext_flush_compressor(VALUE self)
|
125
164
|
{
|
126
165
|
GET_COMPRESSOR(self);
|
127
166
|
DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
|
128
167
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
168
|
+
ZSTD_outBuffer out_buffer = {
|
169
|
+
.dst = compressor_ptr->remaining_destination_buffer,
|
170
|
+
.size = compressor_ptr->remaining_destination_buffer_length,
|
171
|
+
.pos = 0};
|
133
172
|
|
134
|
-
|
135
|
-
out_buffer.dst = compressor_ptr->remaining_destination_buffer;
|
136
|
-
out_buffer.size = compressor_ptr->remaining_destination_buffer_length;
|
137
|
-
out_buffer.pos = 0;
|
173
|
+
compress_flush_args_t args = {.compressor_ptr = compressor_ptr, .out_buffer_ptr = &out_buffer};
|
138
174
|
|
139
|
-
|
140
|
-
if (ZSTD_isError(result)) {
|
141
|
-
zstds_ext_raise_error(zstds_ext_get_error(ZSTD_getErrorCode(result)));
|
175
|
+
ZSTDS_EXT_GVL_WRAP(compressor_ptr->gvl, compress_flush_wrapper, &args);
|
176
|
+
if (ZSTD_isError(args.result)) {
|
177
|
+
zstds_ext_raise_error(zstds_ext_get_error(ZSTD_getErrorCode(args.result)));
|
142
178
|
}
|
143
179
|
|
144
180
|
compressor_ptr->remaining_destination_buffer += out_buffer.pos;
|
145
181
|
compressor_ptr->remaining_destination_buffer_length -= out_buffer.pos;
|
146
182
|
|
147
|
-
|
183
|
+
return args.result != 0 ? Qtrue : Qfalse;
|
184
|
+
}
|
185
|
+
|
186
|
+
// -- compressor finish --
|
187
|
+
|
188
|
+
typedef struct
|
189
|
+
{
|
190
|
+
zstds_ext_compressor_t* compressor_ptr;
|
191
|
+
ZSTD_outBuffer* out_buffer_ptr;
|
192
|
+
zstds_result_t result;
|
193
|
+
} compress_finish_args_t;
|
148
194
|
|
149
|
-
|
195
|
+
static inline void* compress_finish_wrapper(void* data)
|
196
|
+
{
|
197
|
+
compress_finish_args_t* args = data;
|
198
|
+
ZSTD_inBuffer in_buffer = {.src = NULL, .size = 0, .pos = 0};
|
199
|
+
|
200
|
+
args->result = ZSTD_compressStream2(args->compressor_ptr->ctx, args->out_buffer_ptr, &in_buffer, ZSTD_e_end);
|
201
|
+
|
202
|
+
return NULL;
|
150
203
|
}
|
151
204
|
|
152
205
|
VALUE zstds_ext_finish_compressor(VALUE self)
|
@@ -154,29 +207,26 @@ VALUE zstds_ext_finish_compressor(VALUE self)
|
|
154
207
|
GET_COMPRESSOR(self);
|
155
208
|
DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
|
156
209
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
210
|
+
ZSTD_outBuffer out_buffer = {
|
211
|
+
.dst = compressor_ptr->remaining_destination_buffer,
|
212
|
+
.size = compressor_ptr->remaining_destination_buffer_length,
|
213
|
+
.pos = 0};
|
161
214
|
|
162
|
-
|
163
|
-
out_buffer.dst = compressor_ptr->remaining_destination_buffer;
|
164
|
-
out_buffer.size = compressor_ptr->remaining_destination_buffer_length;
|
165
|
-
out_buffer.pos = 0;
|
215
|
+
compress_finish_args_t args = {.compressor_ptr = compressor_ptr, .out_buffer_ptr = &out_buffer};
|
166
216
|
|
167
|
-
|
168
|
-
if (ZSTD_isError(result)) {
|
169
|
-
zstds_ext_raise_error(zstds_ext_get_error(ZSTD_getErrorCode(result)));
|
217
|
+
ZSTDS_EXT_GVL_WRAP(compressor_ptr->gvl, compress_finish_wrapper, &args);
|
218
|
+
if (ZSTD_isError(args.result)) {
|
219
|
+
zstds_ext_raise_error(zstds_ext_get_error(ZSTD_getErrorCode(args.result)));
|
170
220
|
}
|
171
221
|
|
172
222
|
compressor_ptr->remaining_destination_buffer += out_buffer.pos;
|
173
223
|
compressor_ptr->remaining_destination_buffer_length -= out_buffer.pos;
|
174
224
|
|
175
|
-
|
176
|
-
|
177
|
-
return needs_more_destination;
|
225
|
+
return args.result != 0 ? Qtrue : Qfalse;
|
178
226
|
}
|
179
227
|
|
228
|
+
// -- other --
|
229
|
+
|
180
230
|
VALUE zstds_ext_compressor_read_result(VALUE self)
|
181
231
|
{
|
182
232
|
GET_COMPRESSOR(self);
|
@@ -186,10 +236,9 @@ VALUE zstds_ext_compressor_read_result(VALUE self)
|
|
186
236
|
size_t destination_buffer_length = compressor_ptr->destination_buffer_length;
|
187
237
|
size_t remaining_destination_buffer_length = compressor_ptr->remaining_destination_buffer_length;
|
188
238
|
|
189
|
-
const char* result = (const char*)destination_buffer;
|
239
|
+
const char* result = (const char*) destination_buffer;
|
190
240
|
size_t result_length = destination_buffer_length - remaining_destination_buffer_length;
|
191
|
-
|
192
|
-
VALUE result_value = rb_str_new(result, result_length);
|
241
|
+
VALUE result_value = rb_str_new(result, result_length);
|
193
242
|
|
194
243
|
compressor_ptr->remaining_destination_buffer = destination_buffer;
|
195
244
|
compressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
|
@@ -197,6 +246,8 @@ VALUE zstds_ext_compressor_read_result(VALUE self)
|
|
197
246
|
return result_value;
|
198
247
|
}
|
199
248
|
|
249
|
+
// -- cleanup --
|
250
|
+
|
200
251
|
VALUE zstds_ext_compressor_close(VALUE self)
|
201
252
|
{
|
202
253
|
GET_COMPRESSOR(self);
|
@@ -222,6 +273,8 @@ VALUE zstds_ext_compressor_close(VALUE self)
|
|
222
273
|
return Qnil;
|
223
274
|
}
|
224
275
|
|
276
|
+
// -- exports --
|
277
|
+
|
225
278
|
void zstds_ext_compressor_exports(VALUE root_module)
|
226
279
|
{
|
227
280
|
VALUE module = rb_define_module_under(root_module, "Stream");
|