ruby-lzws 1.0.0 → 1.1.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 +176 -27
- data/ext/extconf.rb +11 -17
- data/ext/lzws_ext/buffer.c +18 -0
- data/ext/lzws_ext/buffer.h +11 -0
- data/ext/lzws_ext/common.h +4 -0
- data/ext/lzws_ext/error.c +33 -3
- data/ext/lzws_ext/error.h +20 -1
- data/ext/lzws_ext/io.c +60 -47
- data/ext/lzws_ext/io.h +2 -0
- data/ext/lzws_ext/macro.h +0 -2
- data/ext/lzws_ext/main.c +8 -29
- data/ext/lzws_ext/option.c +23 -10
- data/ext/lzws_ext/option.h +27 -50
- data/ext/lzws_ext/stream/compressor.c +71 -84
- data/ext/lzws_ext/stream/compressor.h +5 -2
- data/ext/lzws_ext/stream/decompressor.c +67 -84
- data/ext/lzws_ext/stream/decompressor.h +4 -1
- data/ext/lzws_ext/string.c +261 -44
- data/ext/lzws_ext/string.h +2 -0
- data/lib/lzws/error.rb +8 -7
- data/lib/lzws/file.rb +6 -18
- data/lib/lzws/option.rb +10 -7
- data/lib/lzws/stream/abstract.rb +2 -2
- data/lib/lzws/stream/raw/abstract.rb +24 -9
- data/lib/lzws/stream/raw/compressor.rb +7 -31
- data/lib/lzws/stream/raw/decompressor.rb +6 -24
- data/lib/lzws/stream/reader.rb +14 -11
- data/lib/lzws/stream/reader_helpers.rb +3 -3
- data/lib/lzws/stream/writer_helpers.rb +2 -2
- data/lib/lzws/string.rb +4 -2
- data/lib/lzws/version.rb +1 -1
- data/lib/lzws.rb +4 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '08551ca534634f131621d9bea42ec6d06bf7b1be6f3f7f3cb33bd11f9744ec1a'
|
4
|
+
data.tar.gz: db0b8c35c381df919bb9b21b9064abd4d88bdc28a82cdead9365f97c4e698b96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0063ee032bf5b6cac9d7e16e696e235c18acec9a6ae48a66c5516906ca290b1c30fb6a0867d371b7b2404706a7523130e00e3b7bb17c1484017a0862a0c7c03f
|
7
|
+
data.tar.gz: eb1905eb2a128c716ffec1693b5be4ce94fb52894ea60adcb446ae03cc3263d8b51b62092e7e164085e875dac752a328b110c68bfdcfc631356d294ec3c50bd6
|
data/README.md
CHANGED
@@ -38,7 +38,7 @@ puts LZWS::Stream::Reader.open("file.txt.Z") { |reader| reader.read }
|
|
38
38
|
```
|
39
39
|
|
40
40
|
You can create and read `tar.Z` archives with `minitar` for example.
|
41
|
-
LZWS is
|
41
|
+
LZWS is compatible with UNIX compress (with default options).
|
42
42
|
|
43
43
|
```ruby
|
44
44
|
require "lzws"
|
@@ -60,30 +60,86 @@ LZWS::Stream::Reader.open "file.tar.Z" do |reader|
|
|
60
60
|
end
|
61
61
|
```
|
62
62
|
|
63
|
-
|
63
|
+
## Options
|
64
64
|
|
65
|
-
|
65
|
+
Each API supports several options:
|
66
|
+
|
67
|
+
```
|
68
|
+
:source_buffer_length
|
69
|
+
:destination_buffer_length
|
70
|
+
```
|
71
|
+
|
72
|
+
There are internal buffers for compressed and decompressed data.
|
73
|
+
For example you want to use 1 KB as source buffer length for compressor - please use 256 B as destination buffer length.
|
74
|
+
You want to use 256 B as source buffer length for decompressor - please use 1 KB as destination buffer length.
|
75
|
+
|
76
|
+
Values: 0, 2 - infinity, default value: 0.
|
77
|
+
0 means automatic buffer length selection.
|
78
|
+
1 byte is not enough, 2 bytes is minimal buffer length.
|
66
79
|
|
67
80
|
```
|
68
81
|
:max_code_bit_length
|
82
|
+
```
|
83
|
+
|
84
|
+
Values: 9 - 16, default value: 16.
|
85
|
+
|
86
|
+
```
|
69
87
|
:block_mode
|
70
|
-
|
88
|
+
```
|
89
|
+
|
90
|
+
Values: true/false, default value: true.
|
91
|
+
|
92
|
+
```
|
71
93
|
:without_magic_header
|
94
|
+
```
|
95
|
+
|
96
|
+
Values: true/false, default value: false.
|
97
|
+
|
98
|
+
```
|
72
99
|
:msb
|
100
|
+
```
|
101
|
+
|
102
|
+
Values: true/false, default value: false.
|
103
|
+
|
104
|
+
```
|
73
105
|
:unaligned_bit_groups
|
106
|
+
```
|
107
|
+
|
108
|
+
Values: true/false, default value: false.
|
109
|
+
|
110
|
+
```
|
74
111
|
:quiet
|
75
112
|
```
|
76
113
|
|
77
|
-
|
114
|
+
Values: true/false, default value: false.
|
115
|
+
Disables lzws library logging.
|
116
|
+
|
117
|
+
Please read lzws docs for more info about options.
|
118
|
+
|
119
|
+
Possible compressor options:
|
120
|
+
```
|
121
|
+
:source_buffer_length
|
122
|
+
:destination_buffer_length
|
123
|
+
:max_code_bit_length
|
124
|
+
:block_mode
|
125
|
+
:without_magic_header
|
126
|
+
:msb
|
127
|
+
:unaligned_bit_groups
|
128
|
+
:quiet
|
129
|
+
```
|
78
130
|
|
131
|
+
Possible decompressor options:
|
79
132
|
```
|
80
|
-
:
|
133
|
+
:source_buffer_length
|
134
|
+
:destination_buffer_length
|
81
135
|
:without_magic_header
|
82
136
|
:msb
|
83
137
|
:unaligned_bit_groups
|
84
138
|
:quiet
|
85
139
|
```
|
86
140
|
|
141
|
+
Example:
|
142
|
+
|
87
143
|
```ruby
|
88
144
|
require "lzws"
|
89
145
|
|
@@ -91,7 +147,7 @@ data = LZWS::String.compress "TOBEORNOTTOBEORTOBEORNOT", :msb => true
|
|
91
147
|
puts LZWS::String.decompress(data, :msb => true)
|
92
148
|
```
|
93
149
|
|
94
|
-
|
150
|
+
Default options are compatible with UNIX compress (`Content-Encoding: compress`):
|
95
151
|
|
96
152
|
```ruby
|
97
153
|
require "lzws"
|
@@ -103,50 +159,91 @@ get "/" do
|
|
103
159
|
end
|
104
160
|
```
|
105
161
|
|
106
|
-
|
162
|
+
Please read more about compatibility in lzws docs.
|
163
|
+
|
164
|
+
## String
|
107
165
|
|
108
|
-
`
|
166
|
+
String maintains destination buffer only, so it accepts `destination_buffer_length` option only.
|
109
167
|
|
110
168
|
```
|
111
169
|
::compress(source, options = {})
|
112
170
|
::decompress(source, options = {})
|
113
171
|
```
|
114
172
|
|
115
|
-
`
|
173
|
+
`source` is a source string.
|
174
|
+
|
175
|
+
## File
|
176
|
+
|
177
|
+
File maintains both source and destination buffers, it accepts both `source_buffer_length` and `destination_buffer_length` options.
|
116
178
|
|
117
179
|
```
|
118
180
|
::compress(source, destination, options = {})
|
119
181
|
::decompress(source, destination, options = {})
|
120
182
|
```
|
121
183
|
|
122
|
-
`
|
184
|
+
`source` and `destination` are file pathes.
|
185
|
+
|
186
|
+
## Stream::Writer
|
187
|
+
|
188
|
+
Its behaviour is similar to builtin [`Zlib::GzipWriter`](https://ruby-doc.org/stdlib-2.6.1/libdoc/zlib/rdoc/Zlib/GzipWriter.html).
|
189
|
+
|
190
|
+
Writer maintains destination buffer only, so it accepts `destination_buffer_length` option only.
|
191
|
+
|
192
|
+
```
|
193
|
+
::open(file_path, options = {}, :external_encoding => nil, :transcode_options => {}, &block)
|
194
|
+
```
|
195
|
+
|
196
|
+
Open file path and create stream writer associated with opened file.
|
197
|
+
Data will be transcoded to `:external_encoding` using `:transcode_options` before compressing.
|
198
|
+
|
199
|
+
```
|
200
|
+
::new(destination_io, options = {}, :external_encoding => nil, :transcode_options => {})
|
201
|
+
```
|
202
|
+
|
203
|
+
Create stream writer associated with destination io.
|
204
|
+
Data will be transcoded to `:external_encoding` using `:transcode_options` before compressing.
|
205
|
+
|
206
|
+
```
|
207
|
+
#set_encoding(external_encoding, nil, transcode_options)
|
208
|
+
```
|
209
|
+
|
210
|
+
Set another encodings, `nil` is just for compatibility with `IO`.
|
123
211
|
|
124
212
|
```
|
125
|
-
::open(file_path, options = {}, :external_encoding => nil, :internal_encoding => nil, &block)
|
126
213
|
#io
|
214
|
+
#to_io
|
127
215
|
#stat
|
128
216
|
#external_encoding
|
129
|
-
#
|
217
|
+
#transcode_options
|
130
218
|
#pos
|
131
219
|
#tell
|
132
|
-
|
133
|
-
|
220
|
+
```
|
221
|
+
|
222
|
+
See [`IO`](https://ruby-doc.org/core-2.6.1/IO.html) docs.
|
223
|
+
|
224
|
+
```
|
225
|
+
#write(*objects)
|
226
|
+
#flush
|
134
227
|
#rewind
|
135
228
|
#close
|
136
229
|
#closed?
|
137
|
-
#to_io
|
138
230
|
```
|
139
231
|
|
140
|
-
`
|
232
|
+
See [`Zlib::GzipWriter`](https://ruby-doc.org/stdlib-2.6.1/libdoc/zlib/rdoc/Zlib/GzipWriter.html) docs.
|
141
233
|
|
142
234
|
```
|
143
|
-
::new(destination_io, options = {}, :external_encoding => nil)
|
144
|
-
#write(*objects)
|
145
|
-
#flush
|
146
235
|
#write_nonblock(object, *options)
|
147
236
|
#flush_nonblock(*options)
|
148
237
|
#rewind_nonblock(*options)
|
149
238
|
#close_nonblock(*options)
|
239
|
+
```
|
240
|
+
|
241
|
+
Special asynchronous methods missing in `Zlib::GzipWriter`.
|
242
|
+
`rewind` wants to `close`, `close` wants to `write` something and `flush`, `flush` want to `write` something.
|
243
|
+
So it is possible to have asynchronous variants for these synchronous methods.
|
244
|
+
Behaviour is the same as `IO#write_nonblock` method.
|
245
|
+
|
246
|
+
```
|
150
247
|
#<<(object)
|
151
248
|
#print(*objects)
|
152
249
|
#printf(*args)
|
@@ -154,24 +251,77 @@ end
|
|
154
251
|
#puts(*objects)
|
155
252
|
```
|
156
253
|
|
157
|
-
`
|
254
|
+
Typical helpers, see [`Zlib::GzipWriter`](https://ruby-doc.org/stdlib-2.6.1/libdoc/zlib/rdoc/Zlib/GzipWriter.html) docs.
|
255
|
+
|
256
|
+
## Stream::Reader
|
257
|
+
|
258
|
+
Its behaviour is similar to builtin [`Zlib::GzipReader`](https://ruby-doc.org/stdlib-2.6.1/libdoc/zlib/rdoc/Zlib/GzipReader.html).
|
259
|
+
|
260
|
+
Reader maintains both source and destination buffers, it accepts both `source_buffer_length` and `destination_buffer_length` options.
|
261
|
+
|
262
|
+
```
|
263
|
+
::open(file_path, options = {}, :external_encoding => nil, :internal_encoding => nil, :transcode_options => {}, &block)
|
264
|
+
```
|
265
|
+
|
266
|
+
Open file path and create stream reader associated with opened file.
|
267
|
+
Data will be force encoded to `:external_encoding` and transcoded to `:internal_encoding` using `:transcode_options` after decompressing.
|
268
|
+
|
269
|
+
```
|
270
|
+
::new(source_io, options = {}, :external_encoding => nil, :internal_encoding => nil, :transcode_options => {})
|
271
|
+
```
|
272
|
+
|
273
|
+
Create stream reader associated with source io.
|
274
|
+
Data will be force encoded to `:external_encoding` and transcoded to `:internal_encoding` using `:transcode_options` after decompressing.
|
275
|
+
|
276
|
+
```
|
277
|
+
#set_encoding(external_encoding, internal_encoding, transcode_options)
|
278
|
+
```
|
279
|
+
|
280
|
+
Set another encodings.
|
281
|
+
|
282
|
+
```
|
283
|
+
#io
|
284
|
+
#to_io
|
285
|
+
#stat
|
286
|
+
#external_encoding
|
287
|
+
#internal_encoding
|
288
|
+
#transcode_options
|
289
|
+
#pos
|
290
|
+
#tell
|
291
|
+
```
|
292
|
+
|
293
|
+
See [`IO`](https://ruby-doc.org/core-2.6.1/IO.html) docs.
|
158
294
|
|
159
295
|
```
|
160
|
-
::new(source_io, options = {}, :external_encoding => nil, :internal_encoding => nil)
|
161
|
-
#lineno
|
162
|
-
#lineno=
|
163
296
|
#read(bytes_to_read = nil, out_buffer = nil)
|
297
|
+
#eof?
|
298
|
+
#rewind
|
299
|
+
#close
|
300
|
+
#closed?
|
301
|
+
```
|
302
|
+
|
303
|
+
See [`Zlib::GzipReader`](https://ruby-doc.org/stdlib-2.6.1/libdoc/zlib/rdoc/Zlib/GzipReader.html) docs.
|
304
|
+
|
305
|
+
```
|
164
306
|
#readpartial(bytes_to_read = nil, out_buffer = nil)
|
165
307
|
#read_nonblock(bytes_to_read, out_buffer = nil, *options)
|
166
|
-
|
308
|
+
```
|
309
|
+
|
310
|
+
See [`IO`](https://ruby-doc.org/core-2.6.1/IO.html) docs.
|
311
|
+
|
312
|
+
```
|
167
313
|
#getbyte
|
168
314
|
#each_byte(&block)
|
169
315
|
#readbyte
|
170
316
|
#ungetbyte(byte)
|
317
|
+
|
171
318
|
#getc
|
172
319
|
#readchar
|
173
320
|
#each_char(&block)
|
174
321
|
#ungetc(char)
|
322
|
+
|
323
|
+
#lineno
|
324
|
+
#lineno=
|
175
325
|
#gets(separator = $OUTPUT_RECORD_SEPARATOR, limit = nil)
|
176
326
|
#readline
|
177
327
|
#readlines
|
@@ -180,8 +330,7 @@ end
|
|
180
330
|
#ungetline(line)
|
181
331
|
```
|
182
332
|
|
183
|
-
|
184
|
-
Please read these method descriptions in ruby doc.
|
333
|
+
Typical helpers, see [`Zlib::GzipReader`](https://ruby-doc.org/stdlib-2.6.1/libdoc/zlib/rdoc/Zlib/GzipReader.html) docs.
|
185
334
|
|
186
335
|
## License
|
187
336
|
|
data/ext/extconf.rb
CHANGED
@@ -9,15 +9,12 @@ end
|
|
9
9
|
|
10
10
|
require_header "lzws/buffer.h"
|
11
11
|
require_header "lzws/compressor/common.h"
|
12
|
-
require_header "lzws/compressor/header.h"
|
13
12
|
require_header "lzws/compressor/main.h"
|
14
13
|
require_header "lzws/compressor/state.h"
|
15
14
|
require_header "lzws/decompressor/common.h"
|
16
|
-
require_header "lzws/decompressor/header.h"
|
17
15
|
require_header "lzws/decompressor/main.h"
|
18
16
|
require_header "lzws/decompressor/state.h"
|
19
17
|
require_header "lzws/file.h"
|
20
|
-
require_header "lzws/string.h"
|
21
18
|
|
22
19
|
def require_library(name, functions)
|
23
20
|
functions.each do |function|
|
@@ -26,26 +23,22 @@ def require_library(name, functions)
|
|
26
23
|
end
|
27
24
|
|
28
25
|
functions = %w[
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
lzws_create_source_buffer_for_compressor
|
27
|
+
lzws_create_destination_buffer_for_compressor
|
28
|
+
lzws_create_source_buffer_for_decompressor
|
29
|
+
lzws_create_destination_buffer_for_decompressor
|
32
30
|
|
33
|
-
lzws_compress_string
|
34
|
-
lzws_decompress_string
|
35
|
-
|
36
|
-
lzws_compress_file
|
37
|
-
lzws_decompress_file
|
38
|
-
|
39
|
-
lzws_compressor_write_magic_header
|
40
31
|
lzws_compressor_get_initial_state
|
41
|
-
lzws_compress
|
42
|
-
lzws_flush_compressor
|
43
32
|
lzws_compressor_free_state
|
33
|
+
lzws_compress
|
34
|
+
lzws_compressor_finish
|
44
35
|
|
45
|
-
lzws_decompressor_read_magic_header
|
46
36
|
lzws_decompressor_get_initial_state
|
47
|
-
lzws_decompress
|
48
37
|
lzws_decompressor_free_state
|
38
|
+
lzws_decompress
|
39
|
+
|
40
|
+
lzws_compress_file
|
41
|
+
lzws_decompress_file
|
49
42
|
]
|
50
43
|
.freeze
|
51
44
|
|
@@ -57,6 +50,7 @@ dir_config extension_name
|
|
57
50
|
sources = %w[
|
58
51
|
stream/compressor
|
59
52
|
stream/decompressor
|
53
|
+
buffer
|
60
54
|
error
|
61
55
|
io
|
62
56
|
main
|
@@ -0,0 +1,18 @@
|
|
1
|
+
// Ruby bindings for lzws library.
|
2
|
+
// Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#include "lzws_ext/buffer.h"
|
5
|
+
|
6
|
+
#include <lzws/buffer.h>
|
7
|
+
|
8
|
+
#include "ruby.h"
|
9
|
+
|
10
|
+
void lzws_ext_buffer_exports(VALUE root_module)
|
11
|
+
{
|
12
|
+
VALUE option = rb_define_module_under(root_module, "Buffer");
|
13
|
+
|
14
|
+
rb_define_const(option, "DEFAULT_SOURCE_BUFFER_LENGTH_FOR_COMPRESSOR", UINT2NUM(LZWS_DEFAULT_SOURCE_BUFFER_LENGTH_FOR_COMPRESSOR));
|
15
|
+
rb_define_const(option, "DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_COMPRESSOR", UINT2NUM(LZWS_DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_COMPRESSOR));
|
16
|
+
rb_define_const(option, "DEFAULT_SOURCE_BUFFER_LENGTH_FOR_DECOMPRESSOR", UINT2NUM(LZWS_DEFAULT_SOURCE_BUFFER_LENGTH_FOR_DECOMPRESSOR));
|
17
|
+
rb_define_const(option, "DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_DECOMPRESSOR", UINT2NUM(LZWS_DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_DECOMPRESSOR));
|
18
|
+
}
|
data/ext/lzws_ext/common.h
CHANGED
data/ext/lzws_ext/error.c
CHANGED
@@ -1,14 +1,44 @@
|
|
1
1
|
// Ruby bindings for lzws library.
|
2
2
|
// Copyright (c) 2019 AUTHORS, MIT License.
|
3
3
|
|
4
|
-
#include "
|
4
|
+
#include "lzws_ext/error.h"
|
5
5
|
|
6
6
|
#include "lzws_ext/common.h"
|
7
|
-
#include "
|
7
|
+
#include "ruby.h"
|
8
8
|
|
9
|
-
void
|
9
|
+
static inline NORETURN(void raise(const char* name, const char* description))
|
10
10
|
{
|
11
11
|
VALUE module = rb_define_module(LZWS_EXT_MODULE_NAME);
|
12
12
|
VALUE error = rb_const_get(module, rb_intern(name));
|
13
13
|
rb_raise(error, "%s", description);
|
14
14
|
}
|
15
|
+
|
16
|
+
void lzws_ext_raise_error(lzws_ext_result_t result)
|
17
|
+
{
|
18
|
+
switch (result) {
|
19
|
+
case LZWS_EXT_ERROR_ALLOCATE_FAILED:
|
20
|
+
raise("AllocateError", "allocate error");
|
21
|
+
case LZWS_EXT_ERROR_VALIDATE_FAILED:
|
22
|
+
raise("ValidateError", "validate error");
|
23
|
+
|
24
|
+
case LZWS_EXT_ERROR_USED_AFTER_CLOSE:
|
25
|
+
raise("UsedAfterCloseError", "used after closed");
|
26
|
+
case LZWS_EXT_ERROR_NOT_ENOUGH_SOURCE_BUFFER:
|
27
|
+
raise("NotEnoughSourceBufferError", "not enough source buffer");
|
28
|
+
case LZWS_EXT_ERROR_NOT_ENOUGH_DESTINATION_BUFFER:
|
29
|
+
raise("NotEnoughDestinationBufferError", "not enough destination buffer");
|
30
|
+
case LZWS_EXT_ERROR_DECOMPRESSOR_CORRUPTED_SOURCE:
|
31
|
+
raise("DecompressorCorruptedSourceError", "decompressor received corrupted source");
|
32
|
+
|
33
|
+
case LZWS_EXT_ERROR_ACCESS_IO:
|
34
|
+
raise("AccessIOError", "failed to access IO");
|
35
|
+
case LZWS_EXT_ERROR_READ_IO:
|
36
|
+
raise("ReadIOError", "failed to read IO");
|
37
|
+
case LZWS_EXT_ERROR_WRITE_IO:
|
38
|
+
raise("WriteIOError", "failed to write IO");
|
39
|
+
|
40
|
+
default:
|
41
|
+
// LZWS_EXT_ERROR_UNEXPECTED
|
42
|
+
raise("UnexpectedError", "unexpected error");
|
43
|
+
}
|
44
|
+
}
|
data/ext/lzws_ext/error.h
CHANGED
@@ -4,8 +4,27 @@
|
|
4
4
|
#if !defined(LZWS_EXT_ERROR_H)
|
5
5
|
#define LZWS_EXT_ERROR_H
|
6
6
|
|
7
|
+
#include "lzws_ext/common.h"
|
7
8
|
#include "ruby.h"
|
8
9
|
|
9
|
-
|
10
|
+
// Results for errors listed in "lib/lzws/error" used in c extension.
|
11
|
+
|
12
|
+
enum {
|
13
|
+
LZWS_EXT_ERROR_ALLOCATE_FAILED = 1,
|
14
|
+
LZWS_EXT_ERROR_VALIDATE_FAILED,
|
15
|
+
|
16
|
+
LZWS_EXT_ERROR_USED_AFTER_CLOSE,
|
17
|
+
LZWS_EXT_ERROR_NOT_ENOUGH_SOURCE_BUFFER,
|
18
|
+
LZWS_EXT_ERROR_NOT_ENOUGH_DESTINATION_BUFFER,
|
19
|
+
LZWS_EXT_ERROR_DECOMPRESSOR_CORRUPTED_SOURCE,
|
20
|
+
|
21
|
+
LZWS_EXT_ERROR_ACCESS_IO,
|
22
|
+
LZWS_EXT_ERROR_READ_IO,
|
23
|
+
LZWS_EXT_ERROR_WRITE_IO,
|
24
|
+
|
25
|
+
LZWS_EXT_ERROR_UNEXPECTED
|
26
|
+
};
|
27
|
+
|
28
|
+
NORETURN(void lzws_ext_raise_error(lzws_ext_result_t result));
|
10
29
|
|
11
30
|
#endif // LZWS_EXT_ERROR_H
|
data/ext/lzws_ext/io.c
CHANGED
@@ -1,52 +1,70 @@
|
|
1
1
|
// Ruby bindings for lzws library.
|
2
2
|
// Copyright (c) 2019 AUTHORS, MIT License.
|
3
3
|
|
4
|
-
#include <lzws/file.h>
|
5
|
-
|
6
|
-
#include "ruby.h"
|
7
4
|
#include "ruby/io.h"
|
8
5
|
|
6
|
+
#include <lzws/file.h>
|
7
|
+
|
8
|
+
#include "lzws_ext/common.h"
|
9
9
|
#include "lzws_ext/error.h"
|
10
10
|
#include "lzws_ext/io.h"
|
11
11
|
#include "lzws_ext/macro.h"
|
12
12
|
#include "lzws_ext/option.h"
|
13
|
+
#include "ruby.h"
|
13
14
|
|
14
|
-
#define GET_FILE(target)
|
15
|
-
Check_Type(target, T_FILE);
|
16
|
-
|
17
|
-
rb_io_t
|
18
|
-
GetOpenFile(target, target##_io);
|
19
|
-
|
20
|
-
FILE
|
21
|
-
if (target##_file == NULL) {
|
22
|
-
lzws_ext_raise_error(
|
15
|
+
#define GET_FILE(target) \
|
16
|
+
Check_Type(target, T_FILE); \
|
17
|
+
\
|
18
|
+
rb_io_t* target##_io; \
|
19
|
+
GetOpenFile(target, target##_io); \
|
20
|
+
\
|
21
|
+
FILE* target##_file = rb_io_stdio_file(target##_io); \
|
22
|
+
if (target##_file == NULL) { \
|
23
|
+
lzws_ext_raise_error(LZWS_EXT_ERROR_ACCESS_IO); \
|
23
24
|
}
|
24
25
|
|
26
|
+
static inline lzws_ext_result_t get_file_error(lzws_result_t result)
|
27
|
+
{
|
28
|
+
switch (result) {
|
29
|
+
case LZWS_FILE_ALLOCATE_FAILED:
|
30
|
+
return LZWS_EXT_ERROR_ALLOCATE_FAILED;
|
31
|
+
case LZWS_FILE_VALIDATE_FAILED:
|
32
|
+
return LZWS_EXT_ERROR_VALIDATE_FAILED;
|
33
|
+
|
34
|
+
case LZWS_FILE_NOT_ENOUGH_SOURCE_BUFFER:
|
35
|
+
return LZWS_EXT_ERROR_NOT_ENOUGH_SOURCE_BUFFER;
|
36
|
+
case LZWS_FILE_NOT_ENOUGH_DESTINATION_BUFFER:
|
37
|
+
return LZWS_EXT_ERROR_NOT_ENOUGH_DESTINATION_BUFFER;
|
38
|
+
case LZWS_FILE_DECOMPRESSOR_CORRUPTED_SOURCE:
|
39
|
+
return LZWS_EXT_ERROR_DECOMPRESSOR_CORRUPTED_SOURCE;
|
40
|
+
|
41
|
+
case LZWS_FILE_READ_FAILED:
|
42
|
+
return LZWS_EXT_ERROR_READ_IO;
|
43
|
+
case LZWS_FILE_WRITE_FAILED:
|
44
|
+
return LZWS_EXT_ERROR_WRITE_IO;
|
45
|
+
|
46
|
+
default:
|
47
|
+
return LZWS_EXT_ERROR_UNEXPECTED;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
25
51
|
VALUE lzws_ext_compress_io(VALUE LZWS_EXT_UNUSED(self), VALUE source, VALUE destination, VALUE options)
|
26
52
|
{
|
27
53
|
GET_FILE(source);
|
28
54
|
GET_FILE(destination);
|
55
|
+
Check_Type(options, T_HASH);
|
29
56
|
LZWS_EXT_GET_COMPRESSOR_OPTIONS(options);
|
57
|
+
LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, source_buffer_length);
|
58
|
+
LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
|
30
59
|
|
31
60
|
lzws_result_t result = lzws_compress_file(
|
32
|
-
source_file,
|
33
|
-
destination_file,
|
61
|
+
source_file, source_buffer_length,
|
62
|
+
destination_file, destination_buffer_length,
|
34
63
|
without_magic_header, max_code_bit_length, block_mode, msb, unaligned_bit_groups, quiet);
|
35
64
|
|
36
|
-
if (result
|
37
|
-
|
38
|
-
|
39
|
-
else if (result == LZWS_FILE_VALIDATE_FAILED) {
|
40
|
-
lzws_ext_raise_error("ValidateError", "validate error");
|
41
|
-
}
|
42
|
-
else if (result == LZWS_FILE_READ_FAILED) {
|
43
|
-
lzws_ext_raise_error("ReadIOError", "failed to read IO");
|
44
|
-
}
|
45
|
-
else if (result == LZWS_FILE_WRITE_FAILED) {
|
46
|
-
lzws_ext_raise_error("WriteIOError", "failed to write IO");
|
47
|
-
}
|
48
|
-
else if (result != 0) {
|
49
|
-
lzws_ext_raise_error("UnexpectedError", "unexpected error");
|
65
|
+
if (result != 0) {
|
66
|
+
lzws_ext_result_t ext_result = get_file_error(result);
|
67
|
+
lzws_ext_raise_error(ext_result);
|
50
68
|
}
|
51
69
|
|
52
70
|
// Ruby itself won't flush stdio file before closing fd, flush is required.
|
@@ -59,30 +77,19 @@ VALUE lzws_ext_decompress_io(VALUE LZWS_EXT_UNUSED(self), VALUE source, VALUE de
|
|
59
77
|
{
|
60
78
|
GET_FILE(source);
|
61
79
|
GET_FILE(destination);
|
80
|
+
Check_Type(options, T_HASH);
|
62
81
|
LZWS_EXT_GET_DECOMPRESSOR_OPTIONS(options);
|
82
|
+
LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, source_buffer_length);
|
83
|
+
LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
|
63
84
|
|
64
85
|
lzws_result_t result = lzws_decompress_file(
|
65
|
-
source_file,
|
66
|
-
destination_file,
|
86
|
+
source_file, source_buffer_length,
|
87
|
+
destination_file, destination_buffer_length,
|
67
88
|
without_magic_header, msb, unaligned_bit_groups, quiet);
|
68
89
|
|
69
|
-
if (result
|
70
|
-
|
71
|
-
|
72
|
-
else if (result == LZWS_FILE_VALIDATE_FAILED) {
|
73
|
-
lzws_ext_raise_error("ValidateError", "validate error");
|
74
|
-
}
|
75
|
-
else if (result == LZWS_FILE_DECOMPRESSOR_CORRUPTED_SOURCE) {
|
76
|
-
lzws_ext_raise_error("DecompressorCorruptedSourceError", "decompressor received corrupted source");
|
77
|
-
}
|
78
|
-
else if (result == LZWS_FILE_READ_FAILED) {
|
79
|
-
lzws_ext_raise_error("ReadIOError", "failed to read IO");
|
80
|
-
}
|
81
|
-
else if (result == LZWS_FILE_WRITE_FAILED) {
|
82
|
-
lzws_ext_raise_error("WriteIOError", "failed to write IO");
|
83
|
-
}
|
84
|
-
else if (result != 0) {
|
85
|
-
lzws_ext_raise_error("UnexpectedError", "unexpected error");
|
90
|
+
if (result != 0) {
|
91
|
+
lzws_ext_result_t ext_result = get_file_error(result);
|
92
|
+
lzws_ext_raise_error(ext_result);
|
86
93
|
}
|
87
94
|
|
88
95
|
// Ruby itself won't flush stdio file before closing fd, flush is required.
|
@@ -90,3 +97,9 @@ VALUE lzws_ext_decompress_io(VALUE LZWS_EXT_UNUSED(self), VALUE source, VALUE de
|
|
90
97
|
|
91
98
|
return Qnil;
|
92
99
|
}
|
100
|
+
|
101
|
+
void lzws_ext_io_exports(VALUE root_module)
|
102
|
+
{
|
103
|
+
rb_define_module_function(root_module, "_native_compress_io", RUBY_METHOD_FUNC(lzws_ext_compress_io), 3);
|
104
|
+
rb_define_module_function(root_module, "_native_decompress_io", RUBY_METHOD_FUNC(lzws_ext_decompress_io), 3);
|
105
|
+
}
|
data/ext/lzws_ext/io.h
CHANGED