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.
- checksums.yaml +4 -4
- data/README.md +63 -29
- data/ext/extconf.rb +90 -20
- data/ext/lzws_ext/buffer.c +3 -5
- data/ext/lzws_ext/buffer.h +5 -5
- data/ext/lzws_ext/error.c +11 -13
- data/ext/lzws_ext/gvl.h +24 -0
- data/ext/lzws_ext/io.c +81 -13
- data/ext/lzws_ext/main.c +5 -1
- data/ext/lzws_ext/option.c +36 -19
- data/ext/lzws_ext/option.h +22 -20
- data/ext/lzws_ext/stream/compressor.c +77 -27
- data/ext/lzws_ext/stream/compressor.h +2 -0
- data/ext/lzws_ext/stream/decompressor.c +50 -20
- data/ext/lzws_ext/stream/decompressor.h +2 -0
- data/ext/lzws_ext/string.c +113 -33
- data/lib/lzws/file.rb +2 -2
- data/lib/lzws/option.rb +34 -4
- data/lib/lzws/stream/abstract.rb +5 -3
- data/lib/lzws/stream/reader.rb +3 -2
- data/lib/lzws/stream/reader_helpers.rb +1 -1
- data/lib/lzws/validation.rb +3 -1
- data/lib/lzws/version.rb +1 -1
- metadata +75 -17
data/ext/lzws_ext/option.c
CHANGED
@@ -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
|
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
|
-
|
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
|
-
|
22
|
+
return raw_type == T_TRUE;
|
29
23
|
}
|
30
24
|
|
31
|
-
|
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
|
-
|
29
|
+
return NUM2UINT(raw_value);
|
41
30
|
}
|
42
31
|
|
43
|
-
size_t
|
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)
|
data/ext/lzws_ext/option.h
CHANGED
@@ -11,36 +11,38 @@
|
|
11
11
|
|
12
12
|
#include "ruby.h"
|
13
13
|
|
14
|
-
void
|
15
|
-
void
|
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
|
18
|
-
|
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
|
21
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
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
|
-
|
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
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
size_t
|
97
|
-
|
98
|
-
|
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
|
-
|
106
|
+
static inline void* compress_wrapper(void* data)
|
101
107
|
{
|
102
|
-
|
103
|
-
|
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
|
-
|
111
|
+
args->result = lzws_compress(
|
107
112
|
compressor_ptr->state_ptr,
|
108
|
-
&remaining_source,
|
109
|
-
|
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
|
-
|
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
|
-
|
148
|
+
// -- compressor finish --
|
149
|
+
|
150
|
+
typedef struct
|
124
151
|
{
|
125
|
-
|
126
|
-
|
152
|
+
lzws_ext_compressor_t* compressor_ptr;
|
153
|
+
lzws_result_t result;
|
154
|
+
} compressor_finish_args_t;
|
127
155
|
|
128
|
-
|
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
|
-
|
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 "
|
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
|
-
|
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
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
size_t
|
95
|
-
|
96
|
-
|
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
|
-
|
103
|
+
static inline void* decompress_wrapper(void* data)
|
99
104
|
{
|
100
|
-
|
101
|
-
|
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
|
-
|
108
|
+
args->result = lzws_decompress(
|
105
109
|
decompressor_ptr->state_ptr,
|
106
|
-
&remaining_source,
|
107
|
-
|
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
|
-
|
112
|
-
|
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);
|