ruby-lzws 1.2.0 → 1.4.1

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.
@@ -4,51 +4,68 @@
4
4
  #include "lzws_ext/option.h"
5
5
 
6
6
  #include "lzws_ext/error.h"
7
- #include "ruby.h"
8
7
 
9
8
  // -- values --
10
9
 
11
- static inline VALUE get_raw_option_value(VALUE options, const char* name)
10
+ static inline VALUE get_raw_value(VALUE options, const char* name)
12
11
  {
13
12
  return rb_funcall(options, rb_intern("[]"), 1, ID2SYM(rb_intern(name)));
14
13
  }
15
14
 
16
- void lzws_ext_get_bool_option(VALUE options, bool* option, const char* name)
15
+ static inline bool get_bool_value(VALUE raw_value)
17
16
  {
18
- VALUE raw_value = get_raw_option_value(options, name);
19
- if (raw_value == Qnil) {
20
- return;
21
- }
22
-
23
17
  int raw_type = TYPE(raw_value);
24
18
  if (raw_type != T_TRUE && raw_type != T_FALSE) {
25
19
  lzws_ext_raise_error(LZWS_EXT_ERROR_VALIDATE_FAILED);
26
20
  }
27
21
 
28
- *option = raw_type == T_TRUE;
22
+ return raw_type == T_TRUE;
29
23
  }
30
24
 
31
- void lzws_ext_get_max_code_bit_length_option(VALUE options, lzws_byte_fast_t* option, const char* name)
25
+ static inline unsigned int get_uint_value(VALUE raw_value)
32
26
  {
33
- VALUE raw_value = get_raw_option_value(options, name);
34
- if (raw_value == Qnil) {
35
- return;
36
- }
37
-
38
27
  Check_Type(raw_value, T_FIXNUM);
39
28
 
40
- *option = NUM2UINT(raw_value);
29
+ return NUM2UINT(raw_value);
41
30
  }
42
31
 
43
- size_t lzws_ext_get_size_option_value(VALUE options, const char* name)
32
+ static inline size_t get_size_value(VALUE raw_value)
44
33
  {
45
- VALUE raw_value = get_raw_option_value(options, name);
46
-
47
34
  Check_Type(raw_value, T_FIXNUM);
48
35
 
49
36
  return NUM2SIZET(raw_value);
50
37
  }
51
38
 
39
+ void lzws_ext_resolve_bool_option(VALUE options, bool* option, const char* name)
40
+ {
41
+ VALUE raw_value = get_raw_value(options, name);
42
+ if (raw_value != Qnil) {
43
+ *option = get_bool_value(raw_value);
44
+ }
45
+ }
46
+
47
+ void lzws_ext_resolve_max_code_bit_length_option(VALUE options, lzws_byte_fast_t* option, const char* name)
48
+ {
49
+ VALUE raw_value = get_raw_value(options, name);
50
+ if (raw_value != Qnil) {
51
+ *option = get_uint_value(raw_value);
52
+ }
53
+ }
54
+
55
+ bool lzws_ext_get_bool_option_value(VALUE options, const char* name)
56
+ {
57
+ VALUE raw_value = get_raw_value(options, name);
58
+
59
+ return get_bool_value(raw_value);
60
+ }
61
+
62
+ size_t lzws_ext_get_size_option_value(VALUE options, const char* name)
63
+ {
64
+ VALUE raw_value = get_raw_value(options, name);
65
+
66
+ return get_size_value(raw_value);
67
+ }
68
+
52
69
  // -- exports --
53
70
 
54
71
  void lzws_ext_option_exports(VALUE root_module)
@@ -11,36 +11,38 @@
11
11
 
12
12
  #include "ruby.h"
13
13
 
14
- void lzws_ext_get_bool_option(VALUE options, bool* option, const char* name);
15
- void lzws_ext_get_max_code_bit_length_option(VALUE options, lzws_byte_fast_t* option, const char* name);
14
+ void lzws_ext_resolve_bool_option(VALUE options, bool* option, const char* name);
15
+ void lzws_ext_resolve_max_code_bit_length_option(VALUE options, lzws_byte_fast_t* option, const char* name);
16
16
 
17
- #define LZWS_EXT_GET_BOOL_OPTION(options, target_options, name) \
18
- lzws_ext_get_bool_option(options, &target_options.name, #name);
17
+ #define LZWS_EXT_RESOLVE_BOOL_OPTION(options, target_options, name) \
18
+ lzws_ext_resolve_bool_option(options, &target_options.name, #name);
19
19
 
20
- #define LZWS_EXT_GET_MAX_CODE_BIT_LENGTH_OPTION(options, target_options, name) \
21
- lzws_ext_get_max_code_bit_length_option(options, &target_options.name, #name);
20
+ #define LZWS_EXT_RESOLVE_MAX_CODE_BIT_LENGTH_OPTION(options, target_options, name) \
21
+ lzws_ext_resolve_max_code_bit_length_option(options, &target_options.name, #name);
22
22
 
23
- #define LZWS_EXT_GET_COMPRESSOR_OPTIONS(options) \
24
- lzws_compressor_options_t compressor_options = LZWS_COMPRESSOR_DEFAULT_OPTIONS; \
25
- \
26
- LZWS_EXT_GET_BOOL_OPTION(options, compressor_options, without_magic_header); \
27
- LZWS_EXT_GET_MAX_CODE_BIT_LENGTH_OPTION(options, compressor_options, max_code_bit_length); \
28
- LZWS_EXT_GET_BOOL_OPTION(options, compressor_options, block_mode); \
29
- LZWS_EXT_GET_BOOL_OPTION(options, compressor_options, msb); \
30
- LZWS_EXT_GET_BOOL_OPTION(options, compressor_options, unaligned_bit_groups); \
31
- LZWS_EXT_GET_BOOL_OPTION(options, compressor_options, quiet);
23
+ #define LZWS_EXT_GET_COMPRESSOR_OPTIONS(options) \
24
+ lzws_compressor_options_t compressor_options = LZWS_COMPRESSOR_DEFAULT_OPTIONS; \
25
+ \
26
+ LZWS_EXT_RESOLVE_BOOL_OPTION(options, compressor_options, without_magic_header); \
27
+ LZWS_EXT_RESOLVE_MAX_CODE_BIT_LENGTH_OPTION(options, compressor_options, max_code_bit_length); \
28
+ LZWS_EXT_RESOLVE_BOOL_OPTION(options, compressor_options, block_mode); \
29
+ LZWS_EXT_RESOLVE_BOOL_OPTION(options, compressor_options, msb); \
30
+ LZWS_EXT_RESOLVE_BOOL_OPTION(options, compressor_options, unaligned_bit_groups); \
31
+ LZWS_EXT_RESOLVE_BOOL_OPTION(options, compressor_options, quiet);
32
32
 
33
33
  #define LZWS_EXT_GET_DECOMPRESSOR_OPTIONS(options) \
34
34
  lzws_decompressor_options_t decompressor_options = LZWS_DECOMPRESSOR_DEFAULT_OPTIONS; \
35
35
  \
36
- LZWS_EXT_GET_BOOL_OPTION(options, decompressor_options, without_magic_header); \
37
- LZWS_EXT_GET_BOOL_OPTION(options, decompressor_options, msb); \
38
- LZWS_EXT_GET_BOOL_OPTION(options, decompressor_options, unaligned_bit_groups); \
39
- LZWS_EXT_GET_BOOL_OPTION(options, decompressor_options, quiet);
36
+ LZWS_EXT_RESOLVE_BOOL_OPTION(options, decompressor_options, without_magic_header); \
37
+ LZWS_EXT_RESOLVE_BOOL_OPTION(options, decompressor_options, msb); \
38
+ LZWS_EXT_RESOLVE_BOOL_OPTION(options, decompressor_options, unaligned_bit_groups); \
39
+ LZWS_EXT_RESOLVE_BOOL_OPTION(options, decompressor_options, quiet);
40
40
 
41
+ bool lzws_ext_get_bool_option_value(VALUE options, const char* name);
41
42
  size_t lzws_ext_get_size_option_value(VALUE options, const char* name);
42
43
 
43
- #define LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, name) size_t name = lzws_ext_get_size_option_value(options, #name);
44
+ #define LZWS_EXT_GET_BOOL_OPTION(options, name) bool name = lzws_ext_get_bool_option_value(options, #name);
45
+ #define LZWS_EXT_GET_SIZE_OPTION(options, name) size_t name = lzws_ext_get_size_option_value(options, #name);
44
46
 
45
47
  void lzws_ext_option_exports(VALUE root_module);
46
48
 
@@ -5,11 +5,12 @@
5
5
 
6
6
  #include <lzws/buffer.h>
7
7
  #include <lzws/compressor/main.h>
8
- #include <lzws/compressor/state.h>
9
8
 
10
9
  #include "lzws_ext/error.h"
10
+ #include "lzws_ext/gvl.h"
11
11
  #include "lzws_ext/option.h"
12
- #include "ruby.h"
12
+
13
+ // -- initialization --
13
14
 
14
15
  static void free_compressor(lzws_ext_compressor_t* compressor_ptr)
15
16
  {
@@ -36,6 +37,7 @@ VALUE lzws_ext_allocate_compressor(VALUE klass)
36
37
  compressor_ptr->destination_buffer_length = 0;
37
38
  compressor_ptr->remaining_destination_buffer = NULL;
38
39
  compressor_ptr->remaining_destination_buffer_length = 0;
40
+ compressor_ptr->gvl = false;
39
41
 
40
42
  return self;
41
43
  }
@@ -48,8 +50,9 @@ VALUE lzws_ext_initialize_compressor(VALUE self, VALUE options)
48
50
  {
49
51
  GET_COMPRESSOR(self);
50
52
  Check_Type(options, T_HASH);
53
+ LZWS_EXT_GET_SIZE_OPTION(options, destination_buffer_length);
54
+ LZWS_EXT_GET_BOOL_OPTION(options, gvl);
51
55
  LZWS_EXT_GET_COMPRESSOR_OPTIONS(options);
52
- LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
53
56
 
54
57
  lzws_compressor_state_t* state_ptr;
55
58
 
@@ -80,63 +83,106 @@ VALUE lzws_ext_initialize_compressor(VALUE self, VALUE options)
80
83
  compressor_ptr->destination_buffer_length = destination_buffer_length;
81
84
  compressor_ptr->remaining_destination_buffer = destination_buffer;
82
85
  compressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
86
+ compressor_ptr->gvl = gvl;
83
87
 
84
88
  return Qnil;
85
89
  }
86
90
 
91
+ // -- compress --
92
+
87
93
  #define DO_NOT_USE_AFTER_CLOSE(compressor_ptr) \
88
94
  if (compressor_ptr->state_ptr == NULL || compressor_ptr->destination_buffer == NULL) { \
89
95
  lzws_ext_raise_error(LZWS_EXT_ERROR_USED_AFTER_CLOSE); \
90
96
  }
91
97
 
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
- lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*) source; \
98
- size_t remaining_source_length = source_length;
98
+ typedef struct
99
+ {
100
+ lzws_ext_compressor_t* compressor_ptr;
101
+ lzws_ext_byte_t* remaining_source;
102
+ size_t* remaining_source_length_ptr;
103
+ lzws_result_t result;
104
+ } compress_args_t;
99
105
 
100
- VALUE lzws_ext_compress(VALUE self, VALUE source_value)
106
+ static inline void* compress_wrapper(void* data)
101
107
  {
102
- GET_COMPRESSOR(self);
103
- DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
104
- GET_SOURCE_DATA(source_value);
108
+ compress_args_t* args = data;
109
+ lzws_ext_compressor_t* compressor_ptr = args->compressor_ptr;
105
110
 
106
- lzws_result_t result = lzws_compress(
111
+ args->result = lzws_compress(
107
112
  compressor_ptr->state_ptr,
108
- &remaining_source,
109
- &remaining_source_length,
113
+ &args->remaining_source,
114
+ args->remaining_source_length_ptr,
110
115
  &compressor_ptr->remaining_destination_buffer,
111
116
  &compressor_ptr->remaining_destination_buffer_length);
112
117
 
113
- if (result != 0 && result != LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) {
118
+ return NULL;
119
+ }
120
+
121
+ VALUE lzws_ext_compress(VALUE self, VALUE source_value)
122
+ {
123
+ GET_COMPRESSOR(self);
124
+ DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
125
+ Check_Type(source_value, T_STRING);
126
+
127
+ const char* source = RSTRING_PTR(source_value);
128
+ size_t source_length = RSTRING_LEN(source_value);
129
+ lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*) source;
130
+ size_t remaining_source_length = source_length;
131
+
132
+ compress_args_t args = {
133
+ .compressor_ptr = compressor_ptr,
134
+ .remaining_source = remaining_source,
135
+ .remaining_source_length_ptr = &remaining_source_length};
136
+
137
+ LZWS_EXT_GVL_WRAP(compressor_ptr->gvl, compress_wrapper, &args);
138
+ if (args.result != 0 && args.result != LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) {
114
139
  lzws_ext_raise_error(LZWS_EXT_ERROR_UNEXPECTED);
115
140
  }
116
141
 
117
142
  VALUE bytes_written = SIZET2NUM(source_length - remaining_source_length);
118
- VALUE needs_more_destination = result == LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION ? Qtrue : Qfalse;
143
+ VALUE needs_more_destination = args.result == LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION ? Qtrue : Qfalse;
119
144
 
120
145
  return rb_ary_new_from_args(2, bytes_written, needs_more_destination);
121
146
  }
122
147
 
123
- VALUE lzws_ext_compressor_finish(VALUE self)
148
+ // -- compressor finish --
149
+
150
+ typedef struct
124
151
  {
125
- GET_COMPRESSOR(self);
126
- DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
152
+ lzws_ext_compressor_t* compressor_ptr;
153
+ lzws_result_t result;
154
+ } compressor_finish_args_t;
127
155
 
128
- lzws_result_t result = lzws_compressor_finish(
156
+ static inline void* compressor_finish_wrapper(void* data)
157
+ {
158
+ compressor_finish_args_t* args = data;
159
+ lzws_ext_compressor_t* compressor_ptr = args->compressor_ptr;
160
+
161
+ args->result = lzws_compressor_finish(
129
162
  compressor_ptr->state_ptr,
130
163
  &compressor_ptr->remaining_destination_buffer,
131
164
  &compressor_ptr->remaining_destination_buffer_length);
132
165
 
133
- if (result != 0 && result != LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) {
166
+ return NULL;
167
+ }
168
+
169
+ VALUE lzws_ext_compressor_finish(VALUE self)
170
+ {
171
+ GET_COMPRESSOR(self);
172
+ DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
173
+
174
+ compressor_finish_args_t args = {.compressor_ptr = compressor_ptr};
175
+
176
+ LZWS_EXT_GVL_WRAP(compressor_ptr->gvl, compressor_finish_wrapper, &args);
177
+ if (args.result != 0 && args.result != LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) {
134
178
  lzws_ext_raise_error(LZWS_EXT_ERROR_UNEXPECTED);
135
179
  }
136
180
 
137
- return result == LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION ? Qtrue : Qfalse;
181
+ return args.result == LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION ? Qtrue : Qfalse;
138
182
  }
139
183
 
184
+ // -- other --
185
+
140
186
  VALUE lzws_ext_compressor_read_result(VALUE self)
141
187
  {
142
188
  GET_COMPRESSOR(self);
@@ -156,6 +202,8 @@ VALUE lzws_ext_compressor_read_result(VALUE self)
156
202
  return result_value;
157
203
  }
158
204
 
205
+ // -- cleanup --
206
+
159
207
  VALUE lzws_ext_compressor_close(VALUE self)
160
208
  {
161
209
  GET_COMPRESSOR(self);
@@ -175,12 +223,14 @@ VALUE lzws_ext_compressor_close(VALUE self)
175
223
  compressor_ptr->destination_buffer = NULL;
176
224
  }
177
225
 
178
- // It is possible to keep "destination_buffer_length", "remaining_destination_buffer"
179
- // and "remaining_destination_buffer_length" as is.
226
+ // It is possible to keep "destination_buffer_length", "remaining_destination_buffer",
227
+ // "remaining_destination_buffer_length" and "gvl" as is.
180
228
 
181
229
  return Qnil;
182
230
  }
183
231
 
232
+ // -- exports --
233
+
184
234
  void lzws_ext_compressor_exports(VALUE root_module)
185
235
  {
186
236
  VALUE module = rb_define_module_under(root_module, "Stream");
@@ -5,6 +5,7 @@
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"
@@ -17,6 +18,7 @@ typedef struct
17
18
  size_t destination_buffer_length;
18
19
  lzws_ext_byte_t* remaining_destination_buffer;
19
20
  size_t remaining_destination_buffer_length;
21
+ bool gvl;
20
22
  } lzws_ext_compressor_t;
21
23
 
22
24
  VALUE lzws_ext_allocate_compressor(VALUE klass);
@@ -5,11 +5,12 @@
5
5
 
6
6
  #include <lzws/buffer.h>
7
7
  #include <lzws/decompressor/main.h>
8
- #include <lzws/decompressor/state.h>
9
8
 
10
9
  #include "lzws_ext/error.h"
10
+ #include "lzws_ext/gvl.h"
11
11
  #include "lzws_ext/option.h"
12
- #include "ruby.h"
12
+
13
+ // -- initialization --
13
14
 
14
15
  static void free_decompressor(lzws_ext_decompressor_t* decompressor_ptr)
15
16
  {
@@ -48,8 +49,9 @@ VALUE lzws_ext_initialize_decompressor(VALUE self, VALUE options)
48
49
  {
49
50
  GET_DECOMPRESSOR(self);
50
51
  Check_Type(options, T_HASH);
52
+ LZWS_EXT_GET_SIZE_OPTION(options, destination_buffer_length);
53
+ LZWS_EXT_GET_BOOL_OPTION(options, gvl);
51
54
  LZWS_EXT_GET_DECOMPRESSOR_OPTIONS(options);
52
- LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
53
55
 
54
56
  lzws_decompressor_state_t* state_ptr;
55
57
 
@@ -78,38 +80,60 @@ VALUE lzws_ext_initialize_decompressor(VALUE self, VALUE options)
78
80
  decompressor_ptr->destination_buffer_length = destination_buffer_length;
79
81
  decompressor_ptr->remaining_destination_buffer = destination_buffer;
80
82
  decompressor_ptr->remaining_destination_buffer_length = destination_buffer_length;
83
+ decompressor_ptr->gvl = gvl;
81
84
 
82
85
  return Qnil;
83
86
  }
84
87
 
88
+ // -- decompress --
89
+
85
90
  #define DO_NOT_USE_AFTER_CLOSE(decompressor_ptr) \
86
91
  if (decompressor_ptr->state_ptr == NULL || decompressor_ptr->destination_buffer == NULL) { \
87
92
  lzws_ext_raise_error(LZWS_EXT_ERROR_USED_AFTER_CLOSE); \
88
93
  }
89
94
 
90
- #define GET_SOURCE_DATA(source_value) \
91
- Check_Type(source_value, T_STRING); \
92
- \
93
- const char* source = RSTRING_PTR(source_value); \
94
- size_t source_length = RSTRING_LEN(source_value); \
95
- lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*) source; \
96
- size_t remaining_source_length = source_length;
95
+ typedef struct
96
+ {
97
+ lzws_ext_decompressor_t* decompressor_ptr;
98
+ lzws_ext_byte_t* remaining_source;
99
+ size_t* remaining_source_length_ptr;
100
+ lzws_result_t result;
101
+ } decompress_args_t;
97
102
 
98
- VALUE lzws_ext_decompress(VALUE self, VALUE source_value)
103
+ static inline void* decompress_wrapper(void* data)
99
104
  {
100
- GET_DECOMPRESSOR(self);
101
- DO_NOT_USE_AFTER_CLOSE(decompressor_ptr);
102
- GET_SOURCE_DATA(source_value);
105
+ decompress_args_t* args = data;
106
+ lzws_ext_decompressor_t* decompressor_ptr = args->decompressor_ptr;
103
107
 
104
- lzws_result_t result = lzws_decompress(
108
+ args->result = lzws_decompress(
105
109
  decompressor_ptr->state_ptr,
106
- &remaining_source,
107
- &remaining_source_length,
110
+ &args->remaining_source,
111
+ args->remaining_source_length_ptr,
108
112
  &decompressor_ptr->remaining_destination_buffer,
109
113
  &decompressor_ptr->remaining_destination_buffer_length);
110
114
 
111
- if (result != 0 && result != LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION) {
112
- switch (result) {
115
+ return NULL;
116
+ }
117
+
118
+ VALUE lzws_ext_decompress(VALUE self, VALUE source_value)
119
+ {
120
+ GET_DECOMPRESSOR(self);
121
+ DO_NOT_USE_AFTER_CLOSE(decompressor_ptr);
122
+ Check_Type(source_value, T_STRING);
123
+
124
+ const char* source = RSTRING_PTR(source_value);
125
+ size_t source_length = RSTRING_LEN(source_value);
126
+ lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*) source;
127
+ size_t remaining_source_length = source_length;
128
+
129
+ decompress_args_t args = {
130
+ .decompressor_ptr = decompressor_ptr,
131
+ .remaining_source = remaining_source,
132
+ .remaining_source_length_ptr = &remaining_source_length};
133
+
134
+ LZWS_EXT_GVL_WRAP(decompressor_ptr->gvl, decompress_wrapper, &args);
135
+ if (args.result != 0 && args.result != LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION) {
136
+ switch (args.result) {
113
137
  case LZWS_DECOMPRESSOR_INVALID_MAGIC_HEADER:
114
138
  case LZWS_DECOMPRESSOR_INVALID_MAX_CODE_BIT_LENGTH:
115
139
  lzws_ext_raise_error(LZWS_EXT_ERROR_VALIDATE_FAILED);
@@ -121,11 +145,13 @@ VALUE lzws_ext_decompress(VALUE self, VALUE source_value)
121
145
  }
122
146
 
123
147
  VALUE bytes_read = SIZET2NUM(source_length - remaining_source_length);
124
- VALUE needs_more_destination = result == LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION ? Qtrue : Qfalse;
148
+ VALUE needs_more_destination = args.result == LZWS_DECOMPRESSOR_NEEDS_MORE_DESTINATION ? Qtrue : Qfalse;
125
149
 
126
150
  return rb_ary_new_from_args(2, bytes_read, needs_more_destination);
127
151
  }
128
152
 
153
+ // -- other --
154
+
129
155
  VALUE lzws_ext_decompressor_read_result(VALUE self)
130
156
  {
131
157
  GET_DECOMPRESSOR(self);
@@ -145,6 +171,8 @@ VALUE lzws_ext_decompressor_read_result(VALUE self)
145
171
  return result_value;
146
172
  }
147
173
 
174
+ // -- cleanup --
175
+
148
176
  VALUE lzws_ext_decompressor_close(VALUE self)
149
177
  {
150
178
  GET_DECOMPRESSOR(self);
@@ -170,6 +198,8 @@ VALUE lzws_ext_decompressor_close(VALUE self)
170
198
  return Qnil;
171
199
  }
172
200
 
201
+ // -- exports --
202
+
173
203
  void lzws_ext_decompressor_exports(VALUE root_module)
174
204
  {
175
205
  VALUE module = rb_define_module_under(root_module, "Stream");
@@ -5,6 +5,7 @@
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"
@@ -17,6 +18,7 @@ typedef struct
17
18
  size_t destination_buffer_length;
18
19
  lzws_ext_byte_t* remaining_destination_buffer;
19
20
  size_t remaining_destination_buffer_length;
21
+ bool gvl;
20
22
  } lzws_ext_decompressor_t;
21
23
 
22
24
  VALUE lzws_ext_allocate_decompressor(VALUE klass);