ruby-brs 1.1.5 → 1.2.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/brs_ext/buffer.c +21 -7
- data/ext/brs_ext/buffer.h +7 -7
- data/ext/brs_ext/error.h +2 -1
- data/ext/brs_ext/gvl.h +24 -0
- data/ext/brs_ext/io.c +240 -122
- data/ext/brs_ext/option.c +37 -27
- data/ext/brs_ext/option.h +37 -29
- data/ext/brs_ext/stream/compressor.c +118 -52
- data/ext/brs_ext/stream/compressor.h +4 -1
- data/ext/brs_ext/stream/decompressor.c +54 -22
- data/ext/brs_ext/stream/decompressor.h +4 -1
- data/ext/brs_ext/string.c +118 -64
- data/ext/extconf.rb +2 -0
- data/lib/brs/option.rb +6 -0
- data/lib/brs/version.rb +1 -1
- metadata +23 -8
data/ext/brs_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,35 +26,39 @@ 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
|
36
|
+
static inline size_t get_size_value(VALUE raw_value)
|
37
|
+
{
|
38
|
+
Check_Type(raw_value, T_FIXNUM);
|
39
|
+
|
40
|
+
return NUM2SIZET(raw_value);
|
41
|
+
}
|
42
|
+
|
43
|
+
static inline BrotliEncoderMode get_mode_value(VALUE raw_value)
|
37
44
|
{
|
38
45
|
Check_Type(raw_value, T_SYMBOL);
|
39
46
|
|
40
47
|
ID raw_id = SYM2ID(raw_value);
|
41
48
|
if (raw_id == rb_intern("text")) {
|
42
49
|
return BROTLI_MODE_TEXT;
|
43
|
-
}
|
44
|
-
else if (raw_id == rb_intern("font")) {
|
50
|
+
} else if (raw_id == rb_intern("font")) {
|
45
51
|
return BROTLI_MODE_FONT;
|
46
|
-
}
|
47
|
-
else if (raw_id == rb_intern("generic")) {
|
52
|
+
} else if (raw_id == rb_intern("generic")) {
|
48
53
|
return BROTLI_MODE_GENERIC;
|
49
|
-
}
|
50
|
-
else {
|
54
|
+
} else {
|
51
55
|
brs_ext_raise_error(BRS_EXT_ERROR_VALIDATE_FAILED);
|
52
56
|
}
|
53
57
|
}
|
54
58
|
|
55
|
-
void
|
59
|
+
void brs_ext_resolve_option(VALUE options, brs_ext_option_t* option, brs_ext_option_type_t type, const char* name)
|
56
60
|
{
|
57
|
-
VALUE raw_value =
|
61
|
+
VALUE raw_value = get_raw_value(options, name);
|
58
62
|
|
59
63
|
option->has_value = raw_value != Qnil;
|
60
64
|
if (!option->has_value) {
|
@@ -65,13 +69,13 @@ void brs_ext_get_option(VALUE options, brs_ext_option_t* option, brs_ext_option_
|
|
65
69
|
|
66
70
|
switch (type) {
|
67
71
|
case BRS_EXT_OPTION_TYPE_BOOL:
|
68
|
-
value =
|
72
|
+
value = get_bool_value(raw_value) ? 1 : 0;
|
69
73
|
break;
|
70
74
|
case BRS_EXT_OPTION_TYPE_UINT:
|
71
|
-
value = (brs_ext_option_value_t)
|
75
|
+
value = (brs_ext_option_value_t) get_uint_value(raw_value);
|
72
76
|
break;
|
73
77
|
case BRS_EXT_OPTION_TYPE_MODE:
|
74
|
-
value = (brs_ext_option_value_t)
|
78
|
+
value = (brs_ext_option_value_t) get_mode_value(raw_value);
|
75
79
|
break;
|
76
80
|
default:
|
77
81
|
brs_ext_raise_error(BRS_EXT_ERROR_UNEXPECTED);
|
@@ -80,13 +84,18 @@ void brs_ext_get_option(VALUE options, brs_ext_option_t* option, brs_ext_option_
|
|
80
84
|
option->value = value;
|
81
85
|
}
|
82
86
|
|
83
|
-
|
87
|
+
bool brs_ext_get_bool_option_value(VALUE options, const char* name)
|
84
88
|
{
|
85
|
-
VALUE raw_value =
|
89
|
+
VALUE raw_value = get_raw_value(options, name);
|
86
90
|
|
87
|
-
|
91
|
+
return get_bool_value(raw_value);
|
92
|
+
}
|
88
93
|
|
89
|
-
|
94
|
+
size_t brs_ext_get_size_option_value(VALUE options, const char* name)
|
95
|
+
{
|
96
|
+
VALUE raw_value = get_raw_value(options, name);
|
97
|
+
|
98
|
+
return get_size_value(raw_value);
|
90
99
|
}
|
91
100
|
|
92
101
|
// -- set params --
|
@@ -105,7 +114,8 @@ brs_ext_result_t brs_ext_set_compressor_options(BrotliEncoderState* state_ptr, b
|
|
105
114
|
SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_QUALITY, options->quality);
|
106
115
|
SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_LGWIN, options->lgwin);
|
107
116
|
SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_LGBLOCK, options->lgblock);
|
108
|
-
SET_ENCODER_PARAM(
|
117
|
+
SET_ENCODER_PARAM(
|
118
|
+
state_ptr, BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING, options->disable_literal_context_modeling);
|
109
119
|
SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_SIZE_HINT, options->size_hint);
|
110
120
|
SET_ENCODER_PARAM(state_ptr, BROTLI_PARAM_LARGE_WINDOW, options->large_window);
|
111
121
|
|
@@ -115,9 +125,12 @@ brs_ext_result_t brs_ext_set_compressor_options(BrotliEncoderState* state_ptr, b
|
|
115
125
|
#define SET_DECODER_PARAM(state_ptr, param, option) \
|
116
126
|
SET_OPTION_VALUE(BrotliDecoderSetParameter, state_ptr, param, option);
|
117
127
|
|
118
|
-
brs_ext_result_t brs_ext_set_decompressor_options(
|
128
|
+
brs_ext_result_t brs_ext_set_decompressor_options(
|
129
|
+
BrotliDecoderState* state_ptr,
|
130
|
+
brs_ext_decompressor_options_t* options)
|
119
131
|
{
|
120
|
-
SET_DECODER_PARAM(
|
132
|
+
SET_DECODER_PARAM(
|
133
|
+
state_ptr, BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION, options->disable_ring_buffer_reallocation);
|
121
134
|
SET_DECODER_PARAM(state_ptr, BROTLI_DECODER_PARAM_LARGE_WINDOW, options->large_window);
|
122
135
|
|
123
136
|
return 0;
|
@@ -133,11 +146,8 @@ void brs_ext_option_exports(VALUE root_module)
|
|
133
146
|
{
|
134
147
|
VALUE module = rb_define_module_under(root_module, "Option");
|
135
148
|
|
136
|
-
VALUE modes =
|
137
|
-
3,
|
138
|
-
ID2SYM(rb_intern("text")),
|
139
|
-
ID2SYM(rb_intern("font")),
|
140
|
-
ID2SYM(rb_intern("generic")));
|
149
|
+
VALUE modes =
|
150
|
+
rb_ary_new_from_args(3, ID2SYM(rb_intern("text")), ID2SYM(rb_intern("font")), ID2SYM(rb_intern("generic")));
|
141
151
|
rb_define_const(module, "MODES", modes);
|
142
152
|
RB_GC_GUARD(modes);
|
143
153
|
|
data/ext/brs_ext/option.h
CHANGED
@@ -15,7 +15,8 @@
|
|
15
15
|
// Default option values depends on brotli library.
|
16
16
|
// We will set only user defined values.
|
17
17
|
|
18
|
-
enum
|
18
|
+
enum
|
19
|
+
{
|
19
20
|
BRS_EXT_OPTION_TYPE_BOOL = 1,
|
20
21
|
BRS_EXT_OPTION_TYPE_UINT,
|
21
22
|
BRS_EXT_OPTION_TYPE_MODE
|
@@ -24,12 +25,14 @@ enum {
|
|
24
25
|
typedef brs_ext_byte_fast_t brs_ext_option_type_t;
|
25
26
|
typedef uint32_t brs_ext_option_value_t;
|
26
27
|
|
27
|
-
typedef struct
|
28
|
+
typedef struct
|
29
|
+
{
|
28
30
|
bool has_value;
|
29
31
|
brs_ext_option_value_t value;
|
30
32
|
} brs_ext_option_t;
|
31
33
|
|
32
|
-
typedef struct
|
34
|
+
typedef struct
|
35
|
+
{
|
33
36
|
brs_ext_option_t mode;
|
34
37
|
brs_ext_option_t quality;
|
35
38
|
brs_ext_option_t lgwin;
|
@@ -39,40 +42,45 @@ typedef struct {
|
|
39
42
|
brs_ext_option_t large_window;
|
40
43
|
} brs_ext_compressor_options_t;
|
41
44
|
|
42
|
-
typedef struct
|
45
|
+
typedef struct
|
46
|
+
{
|
43
47
|
brs_ext_option_t disable_ring_buffer_reallocation;
|
44
48
|
brs_ext_option_t large_window;
|
45
49
|
} brs_ext_decompressor_options_t;
|
46
50
|
|
47
|
-
void
|
48
|
-
|
49
|
-
#define
|
50
|
-
|
51
|
-
|
52
|
-
#define BRS_EXT_GET_COMPRESSOR_OPTIONS(options)
|
53
|
-
brs_ext_compressor_options_t compressor_options;
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
#define BRS_EXT_GET_DECOMPRESSOR_OPTIONS(options)
|
64
|
-
brs_ext_decompressor_options_t decompressor_options;
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
51
|
+
void brs_ext_resolve_option(VALUE options, brs_ext_option_t* option, brs_ext_option_type_t type, const char* name);
|
52
|
+
|
53
|
+
#define BRS_EXT_RESOLVE_OPTION(options, target_options, type, name) \
|
54
|
+
brs_ext_resolve_option(options, &target_options.name, type, #name);
|
55
|
+
|
56
|
+
#define BRS_EXT_GET_COMPRESSOR_OPTIONS(options) \
|
57
|
+
brs_ext_compressor_options_t compressor_options; \
|
58
|
+
\
|
59
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_MODE, mode); \
|
60
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, quality); \
|
61
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, lgwin); \
|
62
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, lgblock); \
|
63
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_BOOL, disable_literal_context_modeling); \
|
64
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_UINT, size_hint); \
|
65
|
+
BRS_EXT_RESOLVE_OPTION(options, compressor_options, BRS_EXT_OPTION_TYPE_BOOL, large_window);
|
66
|
+
|
67
|
+
#define BRS_EXT_GET_DECOMPRESSOR_OPTIONS(options) \
|
68
|
+
brs_ext_decompressor_options_t decompressor_options; \
|
69
|
+
\
|
70
|
+
BRS_EXT_RESOLVE_OPTION(options, decompressor_options, BRS_EXT_OPTION_TYPE_BOOL, disable_ring_buffer_reallocation); \
|
71
|
+
BRS_EXT_RESOLVE_OPTION(options, decompressor_options, BRS_EXT_OPTION_TYPE_BOOL, large_window);
|
72
|
+
|
73
|
+
bool brs_ext_get_bool_option_value(VALUE options, const char* name);
|
69
74
|
size_t brs_ext_get_size_option_value(VALUE options, const char* name);
|
70
75
|
|
71
|
-
#define
|
72
|
-
|
76
|
+
#define BRS_EXT_GET_BOOL_OPTION(options, name) size_t name = brs_ext_get_bool_option_value(options, #name);
|
77
|
+
#define BRS_EXT_GET_SIZE_OPTION(options, name) size_t name = brs_ext_get_size_option_value(options, #name);
|
73
78
|
|
74
79
|
brs_ext_result_t brs_ext_set_compressor_options(BrotliEncoderState* state_ptr, brs_ext_compressor_options_t* options);
|
75
|
-
|
80
|
+
|
81
|
+
brs_ext_result_t brs_ext_set_decompressor_options(
|
82
|
+
BrotliDecoderState* state_ptr,
|
83
|
+
brs_ext_decompressor_options_t* options);
|
76
84
|
|
77
85
|
void brs_ext_option_exports(VALUE root_module);
|
78
86
|
|
@@ -8,9 +8,12 @@
|
|
8
8
|
|
9
9
|
#include "brs_ext/buffer.h"
|
10
10
|
#include "brs_ext/error.h"
|
11
|
+
#include "brs_ext/gvl.h"
|
11
12
|
#include "brs_ext/option.h"
|
12
13
|
#include "ruby.h"
|
13
14
|
|
15
|
+
// -- initialization --
|
16
|
+
|
14
17
|
static void free_compressor(brs_ext_compressor_t* compressor_ptr)
|
15
18
|
{
|
16
19
|
BrotliEncoderState* state_ptr = compressor_ptr->state_ptr;
|
@@ -29,14 +32,14 @@ static void free_compressor(brs_ext_compressor_t* compressor_ptr)
|
|
29
32
|
VALUE brs_ext_allocate_compressor(VALUE klass)
|
30
33
|
{
|
31
34
|
brs_ext_compressor_t* compressor_ptr;
|
32
|
-
|
33
|
-
VALUE self = Data_Make_Struct(klass, brs_ext_compressor_t, NULL, free_compressor, compressor_ptr);
|
35
|
+
VALUE self = Data_Make_Struct(klass, brs_ext_compressor_t, NULL, free_compressor, compressor_ptr);
|
34
36
|
|
35
37
|
compressor_ptr->state_ptr = NULL;
|
36
38
|
compressor_ptr->destination_buffer = NULL;
|
37
39
|
compressor_ptr->destination_buffer_length = 0;
|
38
40
|
compressor_ptr->remaining_destination_buffer = NULL;
|
39
41
|
compressor_ptr->remaining_destination_buffer_length = 0;
|
42
|
+
compressor_ptr->gvl = false;
|
40
43
|
|
41
44
|
return self;
|
42
45
|
}
|
@@ -49,8 +52,9 @@ VALUE brs_ext_initialize_compressor(VALUE self, VALUE options)
|
|
49
52
|
{
|
50
53
|
GET_COMPRESSOR(self);
|
51
54
|
Check_Type(options, T_HASH);
|
55
|
+
BRS_EXT_GET_SIZE_OPTION(options, destination_buffer_length);
|
56
|
+
BRS_EXT_GET_BOOL_OPTION(options, gvl);
|
52
57
|
BRS_EXT_GET_COMPRESSOR_OPTIONS(options);
|
53
|
-
BRS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
|
54
58
|
|
55
59
|
BrotliEncoderState* state_ptr = BrotliEncoderCreateInstance(NULL, NULL, NULL);
|
56
60
|
if (state_ptr == NULL) {
|
@@ -78,72 +82,137 @@ VALUE brs_ext_initialize_compressor(VALUE self, VALUE options)
|
|
78
82
|
compressor_ptr->destination_buffer_length = destination_buffer_length;
|
79
83
|
compressor_ptr->remaining_destination_buffer = destination_buffer;
|
80
84
|
compressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
|
85
|
+
compressor_ptr->gvl = gvl;
|
81
86
|
|
82
87
|
return Qnil;
|
83
88
|
}
|
84
89
|
|
90
|
+
// -- compress --
|
91
|
+
|
85
92
|
#define DO_NOT_USE_AFTER_CLOSE(compressor_ptr) \
|
86
93
|
if (compressor_ptr->state_ptr == NULL || compressor_ptr->destination_buffer == NULL) { \
|
87
94
|
brs_ext_raise_error(BRS_EXT_ERROR_USED_AFTER_CLOSE); \
|
88
95
|
}
|
89
96
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
const
|
94
|
-
size_t
|
95
|
-
|
96
|
-
|
97
|
+
typedef struct
|
98
|
+
{
|
99
|
+
brs_ext_compressor_t* compressor_ptr;
|
100
|
+
const brs_ext_byte_t* remaining_source;
|
101
|
+
size_t* remaining_source_length_ptr;
|
102
|
+
BROTLI_BOOL result;
|
103
|
+
} compress_args_t;
|
104
|
+
|
105
|
+
static inline void* compress_wrapper(void* data)
|
106
|
+
{
|
107
|
+
compress_args_t* args = data;
|
108
|
+
brs_ext_compressor_t* compressor_ptr = args->compressor_ptr;
|
109
|
+
|
110
|
+
args->result = BrotliEncoderCompressStream(
|
111
|
+
compressor_ptr->state_ptr,
|
112
|
+
BROTLI_OPERATION_PROCESS,
|
113
|
+
args->remaining_source_length_ptr,
|
114
|
+
&args->remaining_source,
|
115
|
+
&compressor_ptr->remaining_destination_buffer_length,
|
116
|
+
&compressor_ptr->remaining_destination_buffer,
|
117
|
+
NULL);
|
118
|
+
|
119
|
+
return NULL;
|
120
|
+
}
|
97
121
|
|
98
122
|
VALUE brs_ext_compress(VALUE self, VALUE source_value)
|
99
123
|
{
|
100
124
|
GET_COMPRESSOR(self);
|
101
125
|
DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
|
102
|
-
|
126
|
+
Check_Type(source_value, T_STRING);
|
103
127
|
|
104
|
-
|
128
|
+
const char* source = RSTRING_PTR(source_value);
|
129
|
+
size_t source_length = RSTRING_LEN(source_value);
|
130
|
+
const brs_ext_byte_t* remaining_source = (const brs_ext_byte_t*) source;
|
131
|
+
size_t remaining_source_length = source_length;
|
105
132
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
&remaining_source_length
|
110
|
-
&compressor_ptr->remaining_destination_buffer_length, &compressor_ptr->remaining_destination_buffer,
|
111
|
-
NULL);
|
133
|
+
compress_args_t args = {
|
134
|
+
.compressor_ptr = compressor_ptr,
|
135
|
+
.remaining_source = remaining_source,
|
136
|
+
.remaining_source_length_ptr = &remaining_source_length};
|
112
137
|
|
113
|
-
|
138
|
+
BRS_EXT_GVL_WRAP(compressor_ptr->gvl, compress_wrapper, &args);
|
139
|
+
if (!args.result) {
|
114
140
|
brs_ext_raise_error(BRS_EXT_ERROR_UNEXPECTED);
|
115
141
|
}
|
116
142
|
|
117
143
|
VALUE bytes_written = SIZET2NUM(source_length - remaining_source_length);
|
118
|
-
VALUE needs_more_destination = BrotliEncoderHasMoreOutput(state_ptr) ? Qtrue : Qfalse;
|
144
|
+
VALUE needs_more_destination = BrotliEncoderHasMoreOutput(compressor_ptr->state_ptr) ? Qtrue : Qfalse;
|
119
145
|
|
120
146
|
return rb_ary_new_from_args(2, bytes_written, needs_more_destination);
|
121
147
|
}
|
122
148
|
|
123
|
-
|
124
|
-
{
|
125
|
-
GET_COMPRESSOR(self);
|
126
|
-
DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
|
149
|
+
// -- compressor flush --
|
127
150
|
|
128
|
-
|
151
|
+
typedef struct
|
152
|
+
{
|
153
|
+
brs_ext_compressor_t* compressor_ptr;
|
154
|
+
BROTLI_BOOL result;
|
155
|
+
} compressor_flush_args_t;
|
129
156
|
|
130
|
-
|
131
|
-
|
157
|
+
static inline void* compressor_flush_wrapper(void* data)
|
158
|
+
{
|
159
|
+
compressor_flush_args_t* args = data;
|
160
|
+
brs_ext_compressor_t* compressor_ptr = args->compressor_ptr;
|
161
|
+
const brs_ext_byte_t* remaining_source = NULL;
|
162
|
+
size_t remaining_source_length = 0;
|
132
163
|
|
133
|
-
|
134
|
-
state_ptr,
|
164
|
+
args->result = BrotliEncoderCompressStream(
|
165
|
+
compressor_ptr->state_ptr,
|
135
166
|
BROTLI_OPERATION_FLUSH,
|
136
|
-
&remaining_source_length,
|
137
|
-
&
|
167
|
+
&remaining_source_length,
|
168
|
+
&remaining_source,
|
169
|
+
&compressor_ptr->remaining_destination_buffer_length,
|
170
|
+
&compressor_ptr->remaining_destination_buffer,
|
138
171
|
NULL);
|
139
172
|
|
140
|
-
|
173
|
+
return NULL;
|
174
|
+
}
|
175
|
+
|
176
|
+
VALUE brs_ext_flush_compressor(VALUE self)
|
177
|
+
{
|
178
|
+
GET_COMPRESSOR(self);
|
179
|
+
DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
|
180
|
+
|
181
|
+
compressor_flush_args_t args = {.compressor_ptr = compressor_ptr};
|
182
|
+
|
183
|
+
BRS_EXT_GVL_WRAP(compressor_ptr->gvl, compressor_flush_wrapper, &args);
|
184
|
+
if (!args.result) {
|
141
185
|
brs_ext_raise_error(BRS_EXT_ERROR_UNEXPECTED);
|
142
186
|
}
|
143
187
|
|
144
|
-
|
188
|
+
return BrotliEncoderHasMoreOutput(compressor_ptr->state_ptr) ? Qtrue : Qfalse;
|
189
|
+
}
|
190
|
+
|
191
|
+
// -- compressor finish --
|
192
|
+
|
193
|
+
typedef struct
|
194
|
+
{
|
195
|
+
brs_ext_compressor_t* compressor_ptr;
|
196
|
+
BROTLI_BOOL result;
|
197
|
+
} compressor_finish_args_t;
|
198
|
+
|
199
|
+
static inline void* compressor_finish_wrapper(void* data)
|
200
|
+
{
|
201
|
+
compressor_finish_args_t* args = data;
|
202
|
+
brs_ext_compressor_t* compressor_ptr = args->compressor_ptr;
|
203
|
+
const brs_ext_byte_t* remaining_source = NULL;
|
204
|
+
size_t remaining_source_length = 0;
|
205
|
+
|
206
|
+
args->result = BrotliEncoderCompressStream(
|
207
|
+
compressor_ptr->state_ptr,
|
208
|
+
BROTLI_OPERATION_FINISH,
|
209
|
+
&remaining_source_length,
|
210
|
+
&remaining_source,
|
211
|
+
&compressor_ptr->remaining_destination_buffer_length,
|
212
|
+
&compressor_ptr->remaining_destination_buffer,
|
213
|
+
NULL);
|
145
214
|
|
146
|
-
return
|
215
|
+
return NULL;
|
147
216
|
}
|
148
217
|
|
149
218
|
VALUE brs_ext_finish_compressor(VALUE self)
|
@@ -151,27 +220,21 @@ VALUE brs_ext_finish_compressor(VALUE self)
|
|
151
220
|
GET_COMPRESSOR(self);
|
152
221
|
DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
|
153
222
|
|
154
|
-
|
223
|
+
compressor_finish_args_t args = {.compressor_ptr = compressor_ptr};
|
155
224
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
BROTLI_BOOL result = BrotliEncoderCompressStream(
|
160
|
-
state_ptr,
|
161
|
-
BROTLI_OPERATION_FINISH,
|
162
|
-
&remaining_source_length, &remaining_source,
|
163
|
-
&compressor_ptr->remaining_destination_buffer_length, &compressor_ptr->remaining_destination_buffer,
|
164
|
-
NULL);
|
165
|
-
|
166
|
-
if (!result) {
|
225
|
+
BRS_EXT_GVL_WRAP(compressor_ptr->gvl, compressor_finish_wrapper, &args);
|
226
|
+
if (!args.result) {
|
167
227
|
brs_ext_raise_error(BRS_EXT_ERROR_UNEXPECTED);
|
168
228
|
}
|
169
229
|
|
170
|
-
|
171
|
-
|
172
|
-
|
230
|
+
return (BrotliEncoderHasMoreOutput(compressor_ptr->state_ptr) ||
|
231
|
+
!BrotliEncoderIsFinished(compressor_ptr->state_ptr)) ?
|
232
|
+
Qtrue :
|
233
|
+
Qfalse;
|
173
234
|
}
|
174
235
|
|
236
|
+
// -- other --
|
237
|
+
|
175
238
|
VALUE brs_ext_compressor_read_result(VALUE self)
|
176
239
|
{
|
177
240
|
GET_COMPRESSOR(self);
|
@@ -181,10 +244,9 @@ VALUE brs_ext_compressor_read_result(VALUE self)
|
|
181
244
|
size_t destination_buffer_length = compressor_ptr->destination_buffer_length;
|
182
245
|
size_t remaining_destination_buffer_length = compressor_ptr->remaining_destination_buffer_length;
|
183
246
|
|
184
|
-
const char* result = (const char*)destination_buffer;
|
247
|
+
const char* result = (const char*) destination_buffer;
|
185
248
|
size_t result_length = destination_buffer_length - remaining_destination_buffer_length;
|
186
|
-
|
187
|
-
VALUE result_value = rb_str_new(result, result_length);
|
249
|
+
VALUE result_value = rb_str_new(result, result_length);
|
188
250
|
|
189
251
|
compressor_ptr->remaining_destination_buffer = destination_buffer;
|
190
252
|
compressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
|
@@ -192,6 +254,8 @@ VALUE brs_ext_compressor_read_result(VALUE self)
|
|
192
254
|
return result_value;
|
193
255
|
}
|
194
256
|
|
257
|
+
// -- cleanup --
|
258
|
+
|
195
259
|
VALUE brs_ext_compressor_close(VALUE self)
|
196
260
|
{
|
197
261
|
GET_COMPRESSOR(self);
|
@@ -217,6 +281,8 @@ VALUE brs_ext_compressor_close(VALUE self)
|
|
217
281
|
return Qnil;
|
218
282
|
}
|
219
283
|
|
284
|
+
// -- exports --
|
285
|
+
|
220
286
|
void brs_ext_compressor_exports(VALUE root_module)
|
221
287
|
{
|
222
288
|
VALUE module = rb_define_module_under(root_module, "Stream");
|