ruby-lzws 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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