ruby-lzws 1.1.5 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,17 +5,20 @@
5
5
  #define LZWS_EXT_STREAM_COMPRESSOR_H
6
6
 
7
7
  #include <lzws/compressor/state.h>
8
+ #include <stdbool.h>
8
9
  #include <stdlib.h>
9
10
 
10
11
  #include "lzws_ext/common.h"
11
12
  #include "ruby.h"
12
13
 
13
- typedef struct {
14
+ typedef struct
15
+ {
14
16
  lzws_compressor_state_t* state_ptr;
15
17
  lzws_ext_byte_t* destination_buffer;
16
18
  size_t destination_buffer_length;
17
19
  lzws_ext_byte_t* remaining_destination_buffer;
18
20
  size_t remaining_destination_buffer_length;
21
+ bool gvl;
19
22
  } lzws_ext_compressor_t;
20
23
 
21
24
  VALUE lzws_ext_allocate_compressor(VALUE klass);
@@ -4,15 +4,16 @@
4
4
  #include "lzws_ext/stream/decompressor.h"
5
5
 
6
6
  #include <lzws/buffer.h>
7
- #include <lzws/common.h>
8
- #include <lzws/decompressor/common.h>
9
7
  #include <lzws/decompressor/main.h>
10
8
  #include <lzws/decompressor/state.h>
11
9
 
12
10
  #include "lzws_ext/error.h"
11
+ #include "lzws_ext/gvl.h"
13
12
  #include "lzws_ext/option.h"
14
13
  #include "ruby.h"
15
14
 
15
+ // -- initialization --
16
+
16
17
  static void free_decompressor(lzws_ext_decompressor_t* decompressor_ptr)
17
18
  {
18
19
  lzws_decompressor_state_t* state_ptr = decompressor_ptr->state_ptr;
@@ -31,7 +32,6 @@ static void free_decompressor(lzws_ext_decompressor_t* decompressor_ptr)
31
32
  VALUE lzws_ext_allocate_decompressor(VALUE klass)
32
33
  {
33
34
  lzws_ext_decompressor_t* decompressor_ptr;
34
-
35
35
  VALUE self = Data_Make_Struct(klass, lzws_ext_decompressor_t, NULL, free_decompressor, decompressor_ptr);
36
36
 
37
37
  decompressor_ptr->state_ptr = NULL;
@@ -51,15 +51,13 @@ VALUE lzws_ext_initialize_decompressor(VALUE self, VALUE options)
51
51
  {
52
52
  GET_DECOMPRESSOR(self);
53
53
  Check_Type(options, T_HASH);
54
+ LZWS_EXT_GET_SIZE_OPTION(options, destination_buffer_length);
55
+ LZWS_EXT_GET_BOOL_OPTION(options, gvl);
54
56
  LZWS_EXT_GET_DECOMPRESSOR_OPTIONS(options);
55
- LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
56
57
 
57
58
  lzws_decompressor_state_t* state_ptr;
58
59
 
59
- lzws_result_t result = lzws_decompressor_get_initial_state(
60
- &state_ptr,
61
- without_magic_header, msb, unaligned_bit_groups, quiet);
62
-
60
+ lzws_result_t result = lzws_decompressor_get_initial_state(&state_ptr, &decompressor_options);
63
61
  if (result != 0) {
64
62
  switch (result) {
65
63
  case LZWS_DECOMPRESSOR_ALLOCATE_FAILED:
@@ -71,7 +69,9 @@ VALUE lzws_ext_initialize_decompressor(VALUE self, VALUE options)
71
69
 
72
70
  lzws_ext_byte_t* destination_buffer;
73
71
 
74
- result = lzws_create_destination_buffer_for_decompressor(&destination_buffer, &destination_buffer_length, quiet);
72
+ result = lzws_create_destination_buffer_for_decompressor(
73
+ &destination_buffer, &destination_buffer_length, decompressor_options.quiet);
74
+
75
75
  if (result != 0) {
76
76
  lzws_decompressor_free_state(state_ptr);
77
77
  lzws_ext_raise_error(LZWS_EXT_ERROR_ALLOCATE_FAILED);
@@ -82,38 +82,60 @@ VALUE lzws_ext_initialize_decompressor(VALUE self, VALUE options)
82
82
  decompressor_ptr->destination_buffer_length = destination_buffer_length;
83
83
  decompressor_ptr->remaining_destination_buffer = destination_buffer;
84
84
  decompressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
85
+ decompressor_ptr->gvl = gvl;
85
86
 
86
87
  return Qnil;
87
88
  }
88
89
 
90
+ // -- decompress --
91
+
89
92
  #define DO_NOT_USE_AFTER_CLOSE(decompressor_ptr) \
90
93
  if (decompressor_ptr->state_ptr == NULL || decompressor_ptr->destination_buffer == NULL) { \
91
94
  lzws_ext_raise_error(LZWS_EXT_ERROR_USED_AFTER_CLOSE); \
92
95
  }
93
96
 
94
- #define GET_SOURCE_DATA(source_value) \
95
- Check_Type(source_value, T_STRING); \
96
- \
97
- const char* source = RSTRING_PTR(source_value); \
98
- size_t source_length = RSTRING_LEN(source_value); \
99
- lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*)source; \
100
- size_t remaining_source_length = source_length;
97
+ typedef struct
98
+ {
99
+ lzws_ext_decompressor_t* decompressor_ptr;
100
+ lzws_ext_byte_t* remaining_source;
101
+ size_t* remaining_source_length_ptr;
102
+ lzws_result_t result;
103
+ } decompress_args_t;
104
+
105
+ static inline void* decompress_wrapper(void* data)
106
+ {
107
+ decompress_args_t* args = data;
108
+ lzws_ext_decompressor_t* decompressor_ptr = args->decompressor_ptr;
109
+
110
+ args->result = lzws_decompress(
111
+ decompressor_ptr->state_ptr,
112
+ &args->remaining_source,
113
+ args->remaining_source_length_ptr,
114
+ &decompressor_ptr->remaining_destination_buffer,
115
+ &decompressor_ptr->remaining_destination_buffer_length);
116
+
117
+ return NULL;
118
+ }
101
119
 
102
120
  VALUE lzws_ext_decompress(VALUE self, VALUE source_value)
103
121
  {
104
122
  GET_DECOMPRESSOR(self);
105
123
  DO_NOT_USE_AFTER_CLOSE(decompressor_ptr);
106
- GET_SOURCE_DATA(source_value);
124
+ Check_Type(source_value, T_STRING);
107
125
 
108
- lzws_result_t result = lzws_decompress(
109
- decompressor_ptr->state_ptr,
110
- &remaining_source, &remaining_source_length,
111
- &decompressor_ptr->remaining_destination_buffer, &decompressor_ptr->remaining_destination_buffer_length);
126
+ const char* source = RSTRING_PTR(source_value);
127
+ size_t source_length = RSTRING_LEN(source_value);
128
+ lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*) source;
129
+ size_t remaining_source_length = source_length;
112
130
 
113
- if (
114
- result != 0 &&
115
- result != LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION) {
116
- switch (result) {
131
+ decompress_args_t args = {
132
+ .decompressor_ptr = decompressor_ptr,
133
+ .remaining_source = remaining_source,
134
+ .remaining_source_length_ptr = &remaining_source_length};
135
+
136
+ LZWS_EXT_GVL_WRAP(decompressor_ptr->gvl, decompress_wrapper, &args);
137
+ if (args.result != 0 && args.result != LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION) {
138
+ switch (args.result) {
117
139
  case LZWS_DECOMPRESSOR_INVALID_MAGIC_HEADER:
118
140
  case LZWS_DECOMPRESSOR_INVALID_MAX_CODE_BIT_LENGTH:
119
141
  lzws_ext_raise_error(LZWS_EXT_ERROR_VALIDATE_FAILED);
@@ -125,11 +147,13 @@ VALUE lzws_ext_decompress(VALUE self, VALUE source_value)
125
147
  }
126
148
 
127
149
  VALUE bytes_read = SIZET2NUM(source_length - remaining_source_length);
128
- VALUE needs_more_destination = result == LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION ? Qtrue : Qfalse;
150
+ VALUE needs_more_destination = args.result == LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION ? Qtrue : Qfalse;
129
151
 
130
152
  return rb_ary_new_from_args(2, bytes_read, needs_more_destination);
131
153
  }
132
154
 
155
+ // -- other --
156
+
133
157
  VALUE lzws_ext_decompressor_read_result(VALUE self)
134
158
  {
135
159
  GET_DECOMPRESSOR(self);
@@ -139,10 +163,9 @@ VALUE lzws_ext_decompressor_read_result(VALUE self)
139
163
  size_t destination_buffer_length = decompressor_ptr->destination_buffer_length;
140
164
  size_t remaining_destination_buffer_length = decompressor_ptr->remaining_destination_buffer_length;
141
165
 
142
- const char* result = (const char*)destination_buffer;
166
+ const char* result = (const char*) destination_buffer;
143
167
  size_t result_length = destination_buffer_length - remaining_destination_buffer_length;
144
-
145
- VALUE result_value = rb_str_new(result, result_length);
168
+ VALUE result_value = rb_str_new(result, result_length);
146
169
 
147
170
  decompressor_ptr->remaining_destination_buffer = destination_buffer;
148
171
  decompressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
@@ -150,6 +173,8 @@ VALUE lzws_ext_decompressor_read_result(VALUE self)
150
173
  return result_value;
151
174
  }
152
175
 
176
+ // -- cleanup --
177
+
153
178
  VALUE lzws_ext_decompressor_close(VALUE self)
154
179
  {
155
180
  GET_DECOMPRESSOR(self);
@@ -175,6 +200,8 @@ VALUE lzws_ext_decompressor_close(VALUE self)
175
200
  return Qnil;
176
201
  }
177
202
 
203
+ // -- exports --
204
+
178
205
  void lzws_ext_decompressor_exports(VALUE root_module)
179
206
  {
180
207
  VALUE module = rb_define_module_under(root_module, "Stream");
@@ -5,17 +5,20 @@
5
5
  #define LZWS_EXT_STREAM_DECOMPRESSOR_H
6
6
 
7
7
  #include <lzws/decompressor/state.h>
8
+ #include <stdbool.h>
8
9
  #include <stdlib.h>
9
10
 
10
11
  #include "lzws_ext/common.h"
11
12
  #include "ruby.h"
12
13
 
13
- typedef struct {
14
+ typedef struct
15
+ {
14
16
  lzws_decompressor_state_t* state_ptr;
15
17
  lzws_ext_byte_t* destination_buffer;
16
18
  size_t destination_buffer_length;
17
19
  lzws_ext_byte_t* remaining_destination_buffer;
18
20
  size_t remaining_destination_buffer_length;
21
+ bool gvl;
19
22
  } lzws_ext_decompressor_t;
20
23
 
21
24
  VALUE lzws_ext_allocate_decompressor(VALUE klass);
@@ -4,17 +4,15 @@
4
4
  #include "lzws_ext/string.h"
5
5
 
6
6
  #include <lzws/buffer.h>
7
- #include <lzws/common.h>
8
- #include <lzws/compressor/common.h>
9
7
  #include <lzws/compressor/main.h>
10
8
  #include <lzws/compressor/state.h>
11
- #include <lzws/decompressor/common.h>
12
9
  #include <lzws/decompressor/main.h>
13
10
  #include <lzws/decompressor/state.h>
14
11
  #include <stdlib.h>
15
12
 
16
13
  #include "lzws_ext/buffer.h"
17
14
  #include "lzws_ext/error.h"
15
+ #include "lzws_ext/gvl.h"
18
16
  #include "lzws_ext/macro.h"
19
17
  #include "lzws_ext/option.h"
20
18
  #include "ruby.h"
@@ -22,8 +20,10 @@
22
20
  // -- buffer --
23
21
 
24
22
  static inline lzws_ext_result_t increase_destination_buffer(
25
- VALUE destination_value, size_t destination_length,
26
- size_t* remaining_destination_buffer_length_ptr, size_t destination_buffer_length)
23
+ VALUE destination_value,
24
+ size_t destination_length,
25
+ size_t* remaining_destination_buffer_length_ptr,
26
+ size_t destination_buffer_length)
27
27
  {
28
28
  if (*remaining_destination_buffer_length_ptr == destination_buffer_length) {
29
29
  // We want to write more data at once, than buffer has.
@@ -42,62 +42,103 @@ static inline lzws_ext_result_t increase_destination_buffer(
42
42
  return 0;
43
43
  }
44
44
 
45
- // -- utils --
45
+ // -- compress --
46
46
 
47
- #define GET_SOURCE_DATA(source_value) \
48
- Check_Type(source_value, T_STRING); \
49
- \
50
- const char* source = RSTRING_PTR(source_value); \
51
- size_t source_length = RSTRING_LEN(source_value);
47
+ typedef struct
48
+ {
49
+ lzws_compressor_state_t* state_ptr;
50
+ lzws_ext_byte_t** remaining_source_ptr;
51
+ size_t* remaining_source_length_ptr;
52
+ lzws_ext_byte_t* remaining_destination_buffer;
53
+ size_t* remaining_destination_buffer_length_ptr;
54
+ lzws_result_t result;
55
+ } compress_args_t;
56
+
57
+ typedef struct
58
+ {
59
+ lzws_compressor_state_t* state_ptr;
60
+ lzws_ext_byte_t* remaining_destination_buffer;
61
+ size_t* remaining_destination_buffer_length_ptr;
62
+ lzws_result_t result;
63
+ } compressor_finish_args_t;
52
64
 
53
- // -- compress --
65
+ static inline void* compress_wrapper(void* data)
66
+ {
67
+ compress_args_t* args = data;
68
+
69
+ args->result = lzws_compress(
70
+ args->state_ptr,
71
+ args->remaining_source_ptr,
72
+ args->remaining_source_length_ptr,
73
+ &args->remaining_destination_buffer,
74
+ args->remaining_destination_buffer_length_ptr);
54
75
 
55
- #define BUFFERED_COMPRESS(function, ...) \
56
- while (true) { \
57
- lzws_ext_byte_t* remaining_destination_buffer = (lzws_ext_byte_t*)RSTRING_PTR(destination_value) + destination_length; \
58
- size_t prev_remaining_destination_buffer_length = remaining_destination_buffer_length; \
59
- \
60
- result = function(__VA_ARGS__, &remaining_destination_buffer, &remaining_destination_buffer_length); \
61
- \
62
- if ( \
63
- result != 0 && \
64
- result != LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) { \
65
- return LZWS_EXT_ERROR_UNEXPECTED; \
66
- } \
67
- \
68
- destination_length += prev_remaining_destination_buffer_length - remaining_destination_buffer_length; \
69
- \
70
- if (result == LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) { \
71
- ext_result = increase_destination_buffer( \
72
- destination_value, destination_length, \
73
- &remaining_destination_buffer_length, destination_buffer_length); \
74
- \
75
- if (ext_result != 0) { \
76
- return ext_result; \
77
- } \
78
- \
79
- continue; \
80
- } \
81
- \
82
- break; \
76
+ return NULL;
77
+ }
78
+
79
+ static inline void* compressor_finish_wrapper(void* data)
80
+ {
81
+ compressor_finish_args_t* args = data;
82
+
83
+ args->result = lzws_compressor_finish(
84
+ args->state_ptr, &args->remaining_destination_buffer, args->remaining_destination_buffer_length_ptr);
85
+
86
+ return NULL;
87
+ }
88
+
89
+ #define BUFFERED_COMPRESS(gvl, wrapper, args) \
90
+ while (true) { \
91
+ lzws_ext_byte_t* remaining_destination_buffer = \
92
+ (lzws_ext_byte_t*) RSTRING_PTR(destination_value) + destination_length; \
93
+ size_t prev_remaining_destination_buffer_length = remaining_destination_buffer_length; \
94
+ \
95
+ args.remaining_destination_buffer = remaining_destination_buffer; \
96
+ args.remaining_destination_buffer_length_ptr = &remaining_destination_buffer_length; \
97
+ \
98
+ LZWS_EXT_GVL_WRAP(gvl, wrapper, &args); \
99
+ if (args.result != 0 && args.result != LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) { \
100
+ return LZWS_EXT_ERROR_UNEXPECTED; \
101
+ } \
102
+ \
103
+ destination_length += prev_remaining_destination_buffer_length - remaining_destination_buffer_length; \
104
+ \
105
+ if (args.result == LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) { \
106
+ ext_result = increase_destination_buffer( \
107
+ destination_value, destination_length, &remaining_destination_buffer_length, destination_buffer_length); \
108
+ \
109
+ if (ext_result != 0) { \
110
+ return ext_result; \
111
+ } \
112
+ \
113
+ continue; \
114
+ } \
115
+ \
116
+ break; \
83
117
  }
84
118
 
85
119
  static inline lzws_ext_result_t compress(
86
120
  lzws_compressor_state_t* state_ptr,
87
- const char* source, size_t source_length,
88
- VALUE destination_value, size_t destination_buffer_length)
121
+ const char* source,
122
+ size_t source_length,
123
+ VALUE destination_value,
124
+ size_t destination_buffer_length,
125
+ bool gvl)
89
126
  {
90
- lzws_result_t result;
91
127
  lzws_ext_result_t ext_result;
128
+ lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*) source;
129
+ size_t remaining_source_length = source_length;
130
+ size_t destination_length = 0;
131
+ size_t remaining_destination_buffer_length = destination_buffer_length;
92
132
 
93
- lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*)source;
94
- size_t remaining_source_length = source_length;
133
+ compress_args_t args = {
134
+ .state_ptr = state_ptr,
135
+ .remaining_source_ptr = &remaining_source,
136
+ .remaining_source_length_ptr = &remaining_source_length};
95
137
 
96
- size_t destination_length = 0;
97
- size_t remaining_destination_buffer_length = destination_buffer_length;
138
+ BUFFERED_COMPRESS(gvl, compress_wrapper, args);
98
139
 
99
- BUFFERED_COMPRESS(lzws_compress, state_ptr, &remaining_source, &remaining_source_length);
100
- BUFFERED_COMPRESS(lzws_compressor_finish, state_ptr);
140
+ compressor_finish_args_t finish_args = {.state_ptr = state_ptr};
141
+ BUFFERED_COMPRESS(gvl, compressor_finish_wrapper, finish_args);
101
142
 
102
143
  int exception;
103
144
 
@@ -111,17 +152,15 @@ static inline lzws_ext_result_t compress(
111
152
 
112
153
  VALUE lzws_ext_compress_string(VALUE LZWS_EXT_UNUSED(self), VALUE source_value, VALUE options)
113
154
  {
114
- GET_SOURCE_DATA(source_value);
155
+ Check_Type(source_value, T_STRING);
115
156
  Check_Type(options, T_HASH);
157
+ LZWS_EXT_GET_SIZE_OPTION(options, destination_buffer_length);
158
+ LZWS_EXT_GET_BOOL_OPTION(options, gvl);
116
159
  LZWS_EXT_GET_COMPRESSOR_OPTIONS(options);
117
- LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
118
160
 
119
161
  lzws_compressor_state_t* state_ptr;
120
162
 
121
- lzws_result_t result = lzws_compressor_get_initial_state(
122
- &state_ptr,
123
- without_magic_header, max_code_bit_length, block_mode, msb, unaligned_bit_groups, quiet);
124
-
163
+ lzws_result_t result = lzws_compressor_get_initial_state(&state_ptr, &compressor_options);
125
164
  if (result != 0) {
126
165
  switch (result) {
127
166
  case LZWS_COMPRESSOR_ALLOCATE_FAILED:
@@ -145,10 +184,11 @@ VALUE lzws_ext_compress_string(VALUE LZWS_EXT_UNUSED(self), VALUE source_value,
145
184
  lzws_ext_raise_error(LZWS_EXT_ERROR_ALLOCATE_FAILED);
146
185
  }
147
186
 
148
- lzws_ext_result_t ext_result = compress(
149
- state_ptr,
150
- source, source_length,
151
- destination_value, destination_buffer_length);
187
+ const char* source = RSTRING_PTR(source_value);
188
+ size_t source_length = RSTRING_LEN(source_value);
189
+
190
+ lzws_ext_result_t ext_result =
191
+ compress(state_ptr, source, source_length, destination_value, destination_buffer_length, gvl);
152
192
 
153
193
  lzws_compressor_free_state(state_ptr);
154
194
 
@@ -161,33 +201,60 @@ VALUE lzws_ext_compress_string(VALUE LZWS_EXT_UNUSED(self), VALUE source_value,
161
201
 
162
202
  // -- decompress --
163
203
 
204
+ typedef struct
205
+ {
206
+ lzws_decompressor_state_t* state_ptr;
207
+ lzws_ext_byte_t** remaining_source_ptr;
208
+ size_t* remaining_source_length_ptr;
209
+ lzws_ext_byte_t* remaining_destination_buffer;
210
+ size_t* remaining_destination_buffer_length_ptr;
211
+ lzws_result_t result;
212
+ } decompress_args_t;
213
+
214
+ static inline void* decompress_wrapper(void* data)
215
+ {
216
+ decompress_args_t* args = data;
217
+
218
+ args->result = lzws_decompress(
219
+ args->state_ptr,
220
+ args->remaining_source_ptr,
221
+ args->remaining_source_length_ptr,
222
+ &args->remaining_destination_buffer,
223
+ args->remaining_destination_buffer_length_ptr);
224
+
225
+ return NULL;
226
+ }
227
+
164
228
  static inline lzws_ext_result_t decompress(
165
229
  lzws_decompressor_state_t* state_ptr,
166
- const char* source, size_t source_length,
167
- VALUE destination_value, size_t destination_buffer_length)
230
+ const char* source,
231
+ size_t source_length,
232
+ VALUE destination_value,
233
+ size_t destination_buffer_length,
234
+ bool gvl)
168
235
  {
169
- lzws_result_t result;
170
236
  lzws_ext_result_t ext_result;
237
+ lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*) source;
238
+ size_t remaining_source_length = source_length;
239
+ size_t destination_length = 0;
240
+ size_t remaining_destination_buffer_length = destination_buffer_length;
171
241
 
172
- lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*)source;
173
- size_t remaining_source_length = source_length;
174
-
175
- size_t destination_length = 0;
176
- size_t remaining_destination_buffer_length = destination_buffer_length;
242
+ decompress_args_t args = {
243
+ .state_ptr = state_ptr,
244
+ .remaining_source_ptr = &remaining_source,
245
+ .remaining_source_length_ptr = &remaining_source_length};
177
246
 
178
247
  while (true) {
179
- lzws_ext_byte_t* remaining_destination_buffer = (lzws_ext_byte_t*)RSTRING_PTR(destination_value) + destination_length;
180
- size_t prev_remaining_destination_buffer_length = remaining_destination_buffer_length;
181
-
182
- result = lzws_decompress(
183
- state_ptr,
184
- &remaining_source, &remaining_source_length,
185
- &remaining_destination_buffer, &remaining_destination_buffer_length);
186
-
187
- if (
188
- result != 0 &&
189
- result != LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION) {
190
- switch (result) {
248
+ lzws_ext_byte_t* remaining_destination_buffer =
249
+ (lzws_ext_byte_t*) RSTRING_PTR(destination_value) + destination_length;
250
+ size_t prev_remaining_destination_buffer_length = remaining_destination_buffer_length;
251
+
252
+ args.remaining_destination_buffer = remaining_destination_buffer;
253
+ args.remaining_destination_buffer_length_ptr = &remaining_destination_buffer_length;
254
+
255
+ LZWS_EXT_GVL_WRAP(gvl, decompress_wrapper, &args);
256
+ if (args.result != 0 && args.result != LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION) {
257
+ switch (args.result) {
191
258
  case LZWS_DECOMPRESSOR_INVALID_MAGIC_HEADER:
192
259
  case LZWS_DECOMPRESSOR_INVALID_MAX_CODE_BIT_LENGTH:
193
260
  return LZWS_EXT_ERROR_VALIDATE_FAILED;
@@ -200,10 +267,9 @@ static inline lzws_ext_result_t decompress(
200
267
 
201
268
  destination_length += prev_remaining_destination_buffer_length - remaining_destination_buffer_length;
202
269
 
203
- if (result == LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION) {
270
+ if (args.result == LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION) {
204
271
  ext_result = increase_destination_buffer(
205
- destination_value, destination_length,
206
- &remaining_destination_buffer_length, destination_buffer_length);
272
+ destination_value, destination_length, &remaining_destination_buffer_length, destination_buffer_length);
207
273
 
208
274
  if (ext_result != 0) {
209
275
  return ext_result;
@@ -227,17 +293,15 @@ static inline lzws_ext_result_t decompress(
227
293
 
228
294
  VALUE lzws_ext_decompress_string(VALUE LZWS_EXT_UNUSED(self), VALUE source_value, VALUE options)
229
295
  {
230
- GET_SOURCE_DATA(source_value);
296
+ Check_Type(source_value, T_STRING);
231
297
  Check_Type(options, T_HASH);
298
+ LZWS_EXT_GET_SIZE_OPTION(options, destination_buffer_length);
299
+ LZWS_EXT_GET_BOOL_OPTION(options, gvl);
232
300
  LZWS_EXT_GET_DECOMPRESSOR_OPTIONS(options);
233
- LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
234
301
 
235
302
  lzws_decompressor_state_t* state_ptr;
236
303
 
237
- lzws_result_t result = lzws_decompressor_get_initial_state(
238
- &state_ptr,
239
- without_magic_header, msb, unaligned_bit_groups, quiet);
240
-
304
+ lzws_result_t result = lzws_decompressor_get_initial_state(&state_ptr, &decompressor_options);
241
305
  if (result != 0) {
242
306
  switch (result) {
243
307
  case LZWS_DECOMPRESSOR_ALLOCATE_FAILED:
@@ -259,10 +323,11 @@ VALUE lzws_ext_decompress_string(VALUE LZWS_EXT_UNUSED(self), VALUE source_value
259
323
  lzws_ext_raise_error(LZWS_EXT_ERROR_ALLOCATE_FAILED);
260
324
  }
261
325
 
262
- lzws_ext_result_t ext_result = decompress(
263
- state_ptr,
264
- source, source_length,
265
- destination_value, destination_buffer_length);
326
+ const char* source = RSTRING_PTR(source_value);
327
+ size_t source_length = RSTRING_LEN(source_value);
328
+
329
+ lzws_ext_result_t ext_result =
330
+ decompress(state_ptr, source, source_length, destination_value, destination_buffer_length, gvl);
266
331
 
267
332
  lzws_decompressor_free_state(state_ptr);
268
333
 
@@ -273,6 +338,8 @@ VALUE lzws_ext_decompress_string(VALUE LZWS_EXT_UNUSED(self), VALUE source_value
273
338
  return destination_value;
274
339
  }
275
340
 
341
+ // -- exports --
342
+
276
343
  void lzws_ext_string_exports(VALUE root_module)
277
344
  {
278
345
  rb_define_module_function(root_module, "_native_compress_string", RUBY_METHOD_FUNC(lzws_ext_compress_string), 2);