ruby-brs 1.1.1 → 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.
@@ -5,17 +5,20 @@
5
5
  #define BRS_EXT_STREAM_COMPRESSOR_H
6
6
 
7
7
  #include <brotli/encode.h>
8
- #include <stdint.h>
8
+ #include <stdbool.h>
9
9
  #include <stdlib.h>
10
10
 
11
+ #include "brs_ext/common.h"
11
12
  #include "ruby.h"
12
13
 
13
- typedef struct {
14
+ typedef struct
15
+ {
14
16
  BrotliEncoderState* state_ptr;
15
- uint8_t* destination_buffer;
17
+ brs_ext_byte_t* destination_buffer;
16
18
  size_t destination_buffer_length;
17
- uint8_t* remaining_destination_buffer;
19
+ brs_ext_byte_t* remaining_destination_buffer;
18
20
  size_t remaining_destination_buffer_length;
21
+ bool gvl;
19
22
  } brs_ext_compressor_t;
20
23
 
21
24
  VALUE brs_ext_allocate_compressor(VALUE klass);
@@ -4,15 +4,15 @@
4
4
  #include "brs_ext/stream/decompressor.h"
5
5
 
6
6
  #include <brotli/decode.h>
7
- #include <stdint.h>
8
- #include <stdlib.h>
9
7
 
10
8
  #include "brs_ext/buffer.h"
11
- #include "brs_ext/common.h"
12
9
  #include "brs_ext/error.h"
10
+ #include "brs_ext/gvl.h"
13
11
  #include "brs_ext/option.h"
14
12
  #include "ruby.h"
15
13
 
14
+ // -- initialization --
15
+
16
16
  static void free_decompressor(brs_ext_decompressor_t* decompressor_ptr)
17
17
  {
18
18
  BrotliDecoderState* state_ptr = decompressor_ptr->state_ptr;
@@ -20,7 +20,7 @@ static void free_decompressor(brs_ext_decompressor_t* decompressor_ptr)
20
20
  BrotliDecoderDestroyInstance(state_ptr);
21
21
  }
22
22
 
23
- uint8_t* destination_buffer = decompressor_ptr->destination_buffer;
23
+ brs_ext_byte_t* destination_buffer = decompressor_ptr->destination_buffer;
24
24
  if (destination_buffer != NULL) {
25
25
  free(destination_buffer);
26
26
  }
@@ -31,7 +31,6 @@ static void free_decompressor(brs_ext_decompressor_t* decompressor_ptr)
31
31
  VALUE brs_ext_allocate_decompressor(VALUE klass)
32
32
  {
33
33
  brs_ext_decompressor_t* decompressor_ptr;
34
-
35
34
  VALUE self = Data_Make_Struct(klass, brs_ext_decompressor_t, NULL, free_decompressor, decompressor_ptr);
36
35
 
37
36
  decompressor_ptr->state_ptr = NULL;
@@ -51,8 +50,9 @@ VALUE brs_ext_initialize_decompressor(VALUE self, VALUE options)
51
50
  {
52
51
  GET_DECOMPRESSOR(self);
53
52
  Check_Type(options, T_HASH);
53
+ BRS_EXT_GET_SIZE_OPTION(options, destination_buffer_length);
54
+ BRS_EXT_GET_BOOL_OPTION(options, gvl);
54
55
  BRS_EXT_GET_DECOMPRESSOR_OPTIONS(options);
55
- BRS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
56
56
 
57
57
  BrotliDecoderState* state_ptr = BrotliDecoderCreateInstance(NULL, NULL, NULL);
58
58
  if (state_ptr == NULL) {
@@ -69,7 +69,7 @@ VALUE brs_ext_initialize_decompressor(VALUE self, VALUE options)
69
69
  destination_buffer_length = BRS_DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_DECOMPRESSOR;
70
70
  }
71
71
 
72
- uint8_t* destination_buffer = malloc(destination_buffer_length);
72
+ brs_ext_byte_t* destination_buffer = malloc(destination_buffer_length);
73
73
  if (destination_buffer == NULL) {
74
74
  BrotliDecoderDestroyInstance(state_ptr);
75
75
  brs_ext_raise_error(BRS_EXT_ERROR_ALLOCATE_FAILED);
@@ -80,62 +80,87 @@ VALUE brs_ext_initialize_decompressor(VALUE self, VALUE options)
80
80
  decompressor_ptr->destination_buffer_length = destination_buffer_length;
81
81
  decompressor_ptr->remaining_destination_buffer = destination_buffer;
82
82
  decompressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
83
+ decompressor_ptr->gvl = gvl;
83
84
 
84
85
  return Qnil;
85
86
  }
86
87
 
88
+ // -- decompress --
89
+
87
90
  #define DO_NOT_USE_AFTER_CLOSE(decompressor_ptr) \
88
91
  if (decompressor_ptr->state_ptr == NULL || decompressor_ptr->destination_buffer == NULL) { \
89
92
  brs_ext_raise_error(BRS_EXT_ERROR_USED_AFTER_CLOSE); \
90
93
  }
91
94
 
92
- #define GET_SOURCE_DATA(source_value) \
93
- Check_Type(source_value, T_STRING); \
94
- \
95
- const char* source = RSTRING_PTR(source_value); \
96
- size_t source_length = RSTRING_LEN(source_value); \
97
- const uint8_t* remaining_source = (const uint8_t*)source; \
98
- size_t remaining_source_length = source_length;
95
+ typedef struct
96
+ {
97
+ brs_ext_decompressor_t* decompressor_ptr;
98
+ const brs_ext_byte_t* remaining_source;
99
+ size_t* remaining_source_length_ptr;
100
+ BrotliDecoderResult result;
101
+ } decompress_args_t;
102
+
103
+ static inline void* decompress_wrapper(void* data)
104
+ {
105
+ decompress_args_t* args = data;
106
+ brs_ext_decompressor_t* decompressor_ptr = args->decompressor_ptr;
107
+
108
+ args->result = BrotliDecoderDecompressStream(
109
+ decompressor_ptr->state_ptr,
110
+ args->remaining_source_length_ptr,
111
+ &args->remaining_source,
112
+ &decompressor_ptr->remaining_destination_buffer_length,
113
+ &decompressor_ptr->remaining_destination_buffer,
114
+ NULL);
115
+
116
+ return NULL;
117
+ }
99
118
 
100
119
  VALUE brs_ext_decompress(VALUE self, VALUE source_value)
101
120
  {
102
121
  GET_DECOMPRESSOR(self);
103
122
  DO_NOT_USE_AFTER_CLOSE(decompressor_ptr);
104
- GET_SOURCE_DATA(source_value);
123
+ Check_Type(source_value, T_STRING);
105
124
 
106
- BrotliDecoderResult result = BrotliDecoderDecompressStream(
107
- decompressor_ptr->state_ptr,
108
- &remaining_source_length, &remaining_source,
109
- &decompressor_ptr->remaining_destination_buffer_length, &decompressor_ptr->remaining_destination_buffer,
110
- NULL);
125
+ const char* source = RSTRING_PTR(source_value);
126
+ size_t source_length = RSTRING_LEN(source_value);
127
+ const brs_ext_byte_t* remaining_source = (const brs_ext_byte_t*) source;
128
+ size_t remaining_source_length = source_length;
129
+
130
+ decompress_args_t args = {
131
+ .decompressor_ptr = decompressor_ptr,
132
+ .remaining_source = remaining_source,
133
+ .remaining_source_length_ptr = &remaining_source_length};
134
+
135
+ BRS_EXT_GVL_WRAP(decompressor_ptr->gvl, decompress_wrapper, &args);
111
136
 
112
137
  if (
113
- result != BROTLI_DECODER_RESULT_SUCCESS &&
114
- result != BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT &&
115
- result != BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
138
+ args.result != BROTLI_DECODER_RESULT_SUCCESS && args.result != BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT &&
139
+ args.result != BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
116
140
  BrotliDecoderErrorCode error_code = BrotliDecoderGetErrorCode(decompressor_ptr->state_ptr);
117
141
  brs_ext_raise_error(brs_ext_get_decompressor_error(error_code));
118
142
  }
119
143
 
120
144
  VALUE bytes_read = SIZET2NUM(source_length - remaining_source_length);
121
- VALUE needs_more_destination = result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT ? Qtrue : Qfalse;
145
+ VALUE needs_more_destination = args.result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT ? Qtrue : Qfalse;
122
146
 
123
147
  return rb_ary_new_from_args(2, bytes_read, needs_more_destination);
124
148
  }
125
149
 
150
+ // -- other --
151
+
126
152
  VALUE brs_ext_decompressor_read_result(VALUE self)
127
153
  {
128
154
  GET_DECOMPRESSOR(self);
129
155
  DO_NOT_USE_AFTER_CLOSE(decompressor_ptr);
130
156
 
131
- uint8_t* destination_buffer = decompressor_ptr->destination_buffer;
132
- size_t destination_buffer_length = decompressor_ptr->destination_buffer_length;
133
- size_t remaining_destination_buffer_length = decompressor_ptr->remaining_destination_buffer_length;
157
+ brs_ext_byte_t* destination_buffer = decompressor_ptr->destination_buffer;
158
+ size_t destination_buffer_length = decompressor_ptr->destination_buffer_length;
159
+ size_t remaining_destination_buffer_length = decompressor_ptr->remaining_destination_buffer_length;
134
160
 
135
- const char* result = (const char*)destination_buffer;
161
+ const char* result = (const char*) destination_buffer;
136
162
  size_t result_length = destination_buffer_length - remaining_destination_buffer_length;
137
-
138
- VALUE result_value = rb_str_new(result, result_length);
163
+ VALUE result_value = rb_str_new(result, result_length);
139
164
 
140
165
  decompressor_ptr->remaining_destination_buffer = destination_buffer;
141
166
  decompressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
@@ -143,6 +168,8 @@ VALUE brs_ext_decompressor_read_result(VALUE self)
143
168
  return result_value;
144
169
  }
145
170
 
171
+ // -- cleanup --
172
+
146
173
  VALUE brs_ext_decompressor_close(VALUE self)
147
174
  {
148
175
  GET_DECOMPRESSOR(self);
@@ -155,7 +182,7 @@ VALUE brs_ext_decompressor_close(VALUE self)
155
182
  decompressor_ptr->state_ptr = NULL;
156
183
  }
157
184
 
158
- uint8_t* destination_buffer = decompressor_ptr->destination_buffer;
185
+ brs_ext_byte_t* destination_buffer = decompressor_ptr->destination_buffer;
159
186
  if (destination_buffer != NULL) {
160
187
  free(destination_buffer);
161
188
 
@@ -168,6 +195,8 @@ VALUE brs_ext_decompressor_close(VALUE self)
168
195
  return Qnil;
169
196
  }
170
197
 
198
+ // -- exports --
199
+
171
200
  void brs_ext_decompressor_exports(VALUE root_module)
172
201
  {
173
202
  VALUE module = rb_define_module_under(root_module, "Stream");
@@ -5,17 +5,20 @@
5
5
  #define BRS_EXT_STREAM_DECOMPRESSOR_H
6
6
 
7
7
  #include <brotli/decode.h>
8
- #include <stdint.h>
8
+ #include <stdbool.h>
9
9
  #include <stdlib.h>
10
10
 
11
+ #include "brs_ext/common.h"
11
12
  #include "ruby.h"
12
13
 
13
- typedef struct {
14
+ typedef struct
15
+ {
14
16
  BrotliDecoderState* state_ptr;
15
- uint8_t* destination_buffer;
17
+ brs_ext_byte_t* destination_buffer;
16
18
  size_t destination_buffer_length;
17
- uint8_t* remaining_destination_buffer;
19
+ brs_ext_byte_t* remaining_destination_buffer;
18
20
  size_t remaining_destination_buffer_length;
21
+ bool gvl;
19
22
  } brs_ext_decompressor_t;
20
23
 
21
24
  VALUE brs_ext_allocate_decompressor(VALUE klass);
@@ -6,12 +6,11 @@
6
6
  #include <brotli/decode.h>
7
7
  #include <brotli/encode.h>
8
8
  #include <brotli/types.h>
9
- #include <stdint.h>
10
9
  #include <stdlib.h>
11
10
 
12
11
  #include "brs_ext/buffer.h"
13
- #include "brs_ext/common.h"
14
12
  #include "brs_ext/error.h"
13
+ #include "brs_ext/gvl.h"
15
14
  #include "brs_ext/macro.h"
16
15
  #include "brs_ext/option.h"
17
16
  #include "ruby.h"
@@ -19,8 +18,10 @@
19
18
  // -- buffer --
20
19
 
21
20
  static inline brs_ext_result_t increase_destination_buffer(
22
- VALUE destination_value, size_t destination_length,
23
- size_t* remaining_destination_buffer_length_ptr, size_t destination_buffer_length)
21
+ VALUE destination_value,
22
+ size_t destination_length,
23
+ size_t* remaining_destination_buffer_length_ptr,
24
+ size_t destination_buffer_length)
24
25
  {
25
26
  if (*remaining_destination_buffer_length_ptr == destination_buffer_length) {
26
27
  // We want to write more data at once, than buffer has.
@@ -39,42 +40,63 @@ static inline brs_ext_result_t increase_destination_buffer(
39
40
  return 0;
40
41
  }
41
42
 
42
- // -- utils --
43
-
44
- #define GET_SOURCE_DATA(source_value) \
45
- Check_Type(source_value, T_STRING); \
46
- \
47
- const char* source = RSTRING_PTR(source_value); \
48
- size_t source_length = RSTRING_LEN(source_value);
49
-
50
43
  // -- compress --
51
44
 
45
+ typedef struct
46
+ {
47
+ BrotliEncoderState* state_ptr;
48
+ const brs_ext_byte_t** remaining_source_ptr;
49
+ size_t* remaining_source_length_ptr;
50
+ brs_ext_byte_t* remaining_destination_buffer;
51
+ size_t* remaining_destination_buffer_length_ptr;
52
+ BROTLI_BOOL result;
53
+ } compress_args_t;
54
+
55
+ static inline void* compress_wrapper(void* data)
56
+ {
57
+ compress_args_t* args = data;
58
+
59
+ args->result = BrotliEncoderCompressStream(
60
+ args->state_ptr,
61
+ BROTLI_OPERATION_FINISH,
62
+ args->remaining_source_length_ptr,
63
+ args->remaining_source_ptr,
64
+ args->remaining_destination_buffer_length_ptr,
65
+ &args->remaining_destination_buffer,
66
+ NULL);
67
+
68
+ return NULL;
69
+ }
70
+
52
71
  static inline brs_ext_result_t compress(
53
72
  BrotliEncoderState* state_ptr,
54
- const char* source, size_t source_length,
55
- VALUE destination_value, size_t destination_buffer_length)
73
+ const char* source,
74
+ size_t source_length,
75
+ VALUE destination_value,
76
+ size_t destination_buffer_length,
77
+ bool gvl)
56
78
  {
57
- BROTLI_BOOL result;
58
- brs_ext_result_t ext_result;
59
-
60
- const uint8_t* remaining_source = (const uint8_t*)source;
61
- size_t remaining_source_length = source_length;
79
+ brs_ext_result_t ext_result;
80
+ const brs_ext_byte_t* remaining_source = (const brs_ext_byte_t*) source;
81
+ size_t remaining_source_length = source_length;
82
+ size_t destination_length = 0;
83
+ size_t remaining_destination_buffer_length = destination_buffer_length;
62
84
 
63
- size_t destination_length = 0;
64
- size_t remaining_destination_buffer_length = destination_buffer_length;
85
+ compress_args_t args = {
86
+ .state_ptr = state_ptr,
87
+ .remaining_source_ptr = &remaining_source,
88
+ .remaining_source_length_ptr = &remaining_source_length};
65
89
 
66
90
  while (true) {
67
- uint8_t* remaining_destination_buffer = (uint8_t*)RSTRING_PTR(destination_value) + destination_length;
68
- size_t prev_remaining_destination_buffer_length = remaining_destination_buffer_length;
91
+ brs_ext_byte_t* remaining_destination_buffer =
92
+ (brs_ext_byte_t*) RSTRING_PTR(destination_value) + destination_length;
93
+ size_t prev_remaining_destination_buffer_length = remaining_destination_buffer_length;
69
94
 
70
- result = BrotliEncoderCompressStream(
71
- state_ptr,
72
- BROTLI_OPERATION_FINISH,
73
- &remaining_source_length, &remaining_source,
74
- &remaining_destination_buffer_length, &remaining_destination_buffer,
75
- NULL);
95
+ args.remaining_destination_buffer = remaining_destination_buffer;
96
+ args.remaining_destination_buffer_length_ptr = &remaining_destination_buffer_length;
76
97
 
77
- if (!result) {
98
+ BRS_EXT_GVL_WRAP(gvl, compress_wrapper, &args);
99
+ if (!args.result) {
78
100
  return BRS_EXT_ERROR_UNEXPECTED;
79
101
  }
80
102
 
@@ -82,8 +104,7 @@ static inline brs_ext_result_t compress(
82
104
 
83
105
  if (BrotliEncoderHasMoreOutput(state_ptr) || !BrotliEncoderIsFinished(state_ptr)) {
84
106
  ext_result = increase_destination_buffer(
85
- destination_value, destination_length,
86
- &remaining_destination_buffer_length, destination_buffer_length);
107
+ destination_value, destination_length, &remaining_destination_buffer_length, destination_buffer_length);
87
108
 
88
109
  if (ext_result != 0) {
89
110
  return ext_result;
@@ -107,10 +128,11 @@ static inline brs_ext_result_t compress(
107
128
 
108
129
  VALUE brs_ext_compress_string(VALUE BRS_EXT_UNUSED(self), VALUE source_value, VALUE options)
109
130
  {
110
- GET_SOURCE_DATA(source_value);
131
+ Check_Type(source_value, T_STRING);
111
132
  Check_Type(options, T_HASH);
133
+ BRS_EXT_GET_SIZE_OPTION(options, destination_buffer_length);
134
+ BRS_EXT_GET_BOOL_OPTION(options, gvl);
112
135
  BRS_EXT_GET_COMPRESSOR_OPTIONS(options);
113
- BRS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
114
136
 
115
137
  BrotliEncoderState* state_ptr = BrotliEncoderCreateInstance(NULL, NULL, NULL);
116
138
  if (state_ptr == NULL) {
@@ -135,10 +157,10 @@ VALUE brs_ext_compress_string(VALUE BRS_EXT_UNUSED(self), VALUE source_value, VA
135
157
  brs_ext_raise_error(BRS_EXT_ERROR_ALLOCATE_FAILED);
136
158
  }
137
159
 
138
- ext_result = compress(
139
- state_ptr,
140
- source, source_length,
141
- destination_value, destination_buffer_length);
160
+ const char* source = RSTRING_PTR(source_value);
161
+ size_t source_length = RSTRING_LEN(source_value);
162
+
163
+ ext_result = compress(state_ptr, source, source_length, destination_value, destination_buffer_length, gvl);
142
164
 
143
165
  BrotliEncoderDestroyInstance(state_ptr);
144
166
 
@@ -151,44 +173,71 @@ VALUE brs_ext_compress_string(VALUE BRS_EXT_UNUSED(self), VALUE source_value, VA
151
173
 
152
174
  // -- decompress --
153
175
 
176
+ typedef struct
177
+ {
178
+ BrotliDecoderState* state_ptr;
179
+ const brs_ext_byte_t** remaining_source_ptr;
180
+ size_t* remaining_source_length_ptr;
181
+ brs_ext_byte_t* remaining_destination_buffer;
182
+ size_t* remaining_destination_buffer_length_ptr;
183
+ brs_ext_result_t result;
184
+ } decompress_args_t;
185
+
186
+ static inline void* decompress_wrapper(void* data)
187
+ {
188
+ decompress_args_t* args = data;
189
+
190
+ args->result = BrotliDecoderDecompressStream(
191
+ args->state_ptr,
192
+ args->remaining_source_length_ptr,
193
+ args->remaining_source_ptr,
194
+ args->remaining_destination_buffer_length_ptr,
195
+ &args->remaining_destination_buffer,
196
+ NULL);
197
+
198
+ return NULL;
199
+ }
200
+
154
201
  static inline brs_ext_result_t decompress(
155
202
  BrotliDecoderState* state_ptr,
156
- const char* source, size_t source_length,
157
- VALUE destination_value, size_t destination_buffer_length)
203
+ const char* source,
204
+ size_t source_length,
205
+ VALUE destination_value,
206
+ size_t destination_buffer_length,
207
+ bool gvl)
158
208
  {
159
- BrotliDecoderResult result;
160
- brs_ext_result_t ext_result;
161
-
162
- const uint8_t* remaining_source = (const uint8_t*)source;
163
- size_t remaining_source_length = source_length;
209
+ brs_ext_result_t ext_result;
210
+ const brs_ext_byte_t* remaining_source = (const brs_ext_byte_t*) source;
211
+ size_t remaining_source_length = source_length;
212
+ size_t destination_length = 0;
213
+ size_t remaining_destination_buffer_length = destination_buffer_length;
164
214
 
165
- size_t destination_length = 0;
166
- size_t remaining_destination_buffer_length = destination_buffer_length;
215
+ decompress_args_t args = {
216
+ .state_ptr = state_ptr,
217
+ .remaining_source_ptr = &remaining_source,
218
+ .remaining_source_length_ptr = &remaining_source_length};
167
219
 
168
220
  while (true) {
169
- uint8_t* remaining_destination_buffer = (uint8_t*)RSTRING_PTR(destination_value) + destination_length;
170
- size_t prev_remaining_destination_buffer_length = remaining_destination_buffer_length;
221
+ brs_ext_byte_t* remaining_destination_buffer =
222
+ (brs_ext_byte_t*) RSTRING_PTR(destination_value) + destination_length;
223
+ size_t prev_remaining_destination_buffer_length = remaining_destination_buffer_length;
171
224
 
172
- result = BrotliDecoderDecompressStream(
173
- state_ptr,
174
- &remaining_source_length, &remaining_source,
175
- &remaining_destination_buffer_length, &remaining_destination_buffer,
176
- NULL);
225
+ args.remaining_destination_buffer = remaining_destination_buffer;
226
+ args.remaining_destination_buffer_length_ptr = &remaining_destination_buffer_length;
177
227
 
228
+ BRS_EXT_GVL_WRAP(gvl, decompress_wrapper, &args);
178
229
  if (
179
- result != BROTLI_DECODER_RESULT_SUCCESS &&
180
- result != BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT &&
181
- result != BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
230
+ args.result != BROTLI_DECODER_RESULT_SUCCESS && args.result != BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT &&
231
+ args.result != BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
182
232
  BrotliDecoderErrorCode error_code = BrotliDecoderGetErrorCode(state_ptr);
183
233
  return brs_ext_get_decompressor_error(error_code);
184
234
  }
185
235
 
186
236
  destination_length += prev_remaining_destination_buffer_length - remaining_destination_buffer_length;
187
237
 
188
- if (result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
238
+ if (args.result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
189
239
  ext_result = increase_destination_buffer(
190
- destination_value, destination_length,
191
- &remaining_destination_buffer_length, destination_buffer_length);
240
+ destination_value, destination_length, &remaining_destination_buffer_length, destination_buffer_length);
192
241
 
193
242
  if (ext_result != 0) {
194
243
  return ext_result;
@@ -212,10 +261,11 @@ static inline brs_ext_result_t decompress(
212
261
 
213
262
  VALUE brs_ext_decompress_string(VALUE BRS_EXT_UNUSED(self), VALUE source_value, VALUE options)
214
263
  {
215
- GET_SOURCE_DATA(source_value);
264
+ Check_Type(source_value, T_STRING);
216
265
  Check_Type(options, T_HASH);
266
+ BRS_EXT_GET_SIZE_OPTION(options, destination_buffer_length);
267
+ BRS_EXT_GET_BOOL_OPTION(options, gvl);
217
268
  BRS_EXT_GET_DECOMPRESSOR_OPTIONS(options);
218
- BRS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
219
269
 
220
270
  BrotliDecoderState* state_ptr = BrotliDecoderCreateInstance(NULL, NULL, NULL);
221
271
  if (state_ptr == NULL) {
@@ -240,10 +290,10 @@ VALUE brs_ext_decompress_string(VALUE BRS_EXT_UNUSED(self), VALUE source_value,
240
290
  brs_ext_raise_error(BRS_EXT_ERROR_ALLOCATE_FAILED);
241
291
  }
242
292
 
243
- ext_result = decompress(
244
- state_ptr,
245
- source, source_length,
246
- destination_value, destination_buffer_length);
293
+ const char* source = RSTRING_PTR(source_value);
294
+ size_t source_length = RSTRING_LEN(source_value);
295
+
296
+ ext_result = decompress(state_ptr, source, source_length, destination_value, destination_buffer_length, gvl);
247
297
 
248
298
  BrotliDecoderDestroyInstance(state_ptr);
249
299
 
@@ -254,6 +304,8 @@ VALUE brs_ext_decompress_string(VALUE BRS_EXT_UNUSED(self), VALUE source_value,
254
304
  return destination_value;
255
305
  }
256
306
 
307
+ // -- exports --
308
+
257
309
  void brs_ext_string_exports(VALUE root_module)
258
310
  {
259
311
  rb_define_module_function(root_module, "_native_compress_string", RUBY_METHOD_FUNC(brs_ext_compress_string), 2);