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