ruby-lzws 1.1.5 → 1.3.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 +75 -74
- data/ext/extconf.rb +12 -3
- data/ext/lzws_ext/buffer.c +21 -7
- data/ext/lzws_ext/buffer.h +5 -5
- data/ext/lzws_ext/error.c +11 -11
- data/ext/lzws_ext/error.h +2 -1
- data/ext/lzws_ext/gvl.h +24 -0
- data/ext/lzws_ext/io.c +83 -19
- data/ext/lzws_ext/main.c +2 -0
- data/ext/lzws_ext/option.c +46 -10
- data/ext/lzws_ext/option.h +30 -24
- data/ext/lzws_ext/stream/compressor.c +84 -40
- data/ext/lzws_ext/stream/compressor.h +4 -1
- data/ext/lzws_ext/stream/decompressor.c +56 -29
- data/ext/lzws_ext/stream/decompressor.h +4 -1
- data/ext/lzws_ext/string.c +159 -92
- 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 +74 -17
@@ -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(
|
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
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
size_t
|
99
|
-
|
100
|
-
|
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
|
-
|
124
|
+
Check_Type(source_value, T_STRING);
|
107
125
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
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
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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);
|
data/ext/lzws_ext/string.c
CHANGED
@@ -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
|
26
|
-
size_t
|
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
|
-
// --
|
45
|
+
// -- compress --
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
size_t
|
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
|
-
|
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
|
-
|
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
|
-
|
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*
|
88
|
-
|
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
|
-
|
94
|
-
|
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
|
-
|
97
|
-
size_t remaining_destination_buffer_length = destination_buffer_length;
|
138
|
+
BUFFERED_COMPRESS(gvl, compress_wrapper, args);
|
98
139
|
|
99
|
-
|
100
|
-
BUFFERED_COMPRESS(
|
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
|
-
|
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
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
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*
|
167
|
-
|
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
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
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
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
if (
|
188
|
-
result
|
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
|
-
|
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
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
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);
|