ruby-lzws 1.1.2 → 1.1.7
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 +54 -64
- data/ext/extconf.rb +13 -0
- data/ext/lzws_ext/common.h +3 -0
- data/ext/lzws_ext/error.c +0 -1
- data/ext/lzws_ext/io.c +0 -1
- data/ext/lzws_ext/main.c +0 -1
- data/ext/lzws_ext/option.c +0 -3
- data/ext/lzws_ext/option.h +7 -6
- data/ext/lzws_ext/stream/compressor.c +13 -15
- data/ext/lzws_ext/stream/compressor.h +3 -3
- data/ext/lzws_ext/stream/decompressor.c +13 -15
- data/ext/lzws_ext/stream/decompressor.h +3 -3
- data/ext/lzws_ext/string.c +34 -35
- data/lib/lzws/file.rb +4 -0
- data/lib/lzws/stream/abstract.rb +9 -12
- data/lib/lzws/stream/raw/abstract.rb +4 -2
- data/lib/lzws/stream/raw/compressor.rb +4 -4
- data/lib/lzws/stream/raw/decompressor.rb +1 -3
- data/lib/lzws/stream/reader.rb +71 -52
- data/lib/lzws/stream/reader_helpers.rb +2 -0
- data/lib/lzws/stream/writer.rb +10 -5
- data/lib/lzws/stream/writer_helpers.rb +8 -10
- data/lib/lzws/validation.rb +15 -2
- data/lib/lzws/version.rb +1 -1
- metadata +41 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45c0c7f35addf83d5ba03c70c375c22ffa77033b0e324cda2a30548bfb91a579
|
4
|
+
data.tar.gz: 99d7cb5a5465ce8f6d82e1d727e63eac94be05db3546f3fd6c445769dd1c7cb7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a8ccf1146d380093e028f40453f2747e6f67e64e308eac8ee4bb5a0bd8abd6d572d42b4a537813c3edcdb46170292740d52b61e8384b47cac2a92895ec1f0d3
|
7
|
+
data.tar.gz: 2b6deed0dfb579fc16637fab9bb82fe3889e100644b80219aa5dc4a59ab00681f17b59a64b5d1930bcf92551f03f04cff9dc714231ec38dcc3856eaf5aa43b5a
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# Ruby bindings for lzws library
|
2
2
|
|
3
|
-
| Travis | AppVeyor |
|
4
|
-
| :---: | :---: | :---: | :---:
|
5
|
-
| [](https://travis-ci.com/andrew-aladev/ruby-lzws) | [](https://ci.appveyor.com/project/andrew-aladev/ruby-lzws/branch/master) | [](https://travis-ci.com/andrew-aladev/ruby-lzws) | [](https://ci.appveyor.com/project/andrew-aladev/ruby-lzws/branch/master) | [](https://circleci.com/gh/andrew-aladev/ruby-lzws/tree/master) | [](https://codecov.io/gh/andrew-aladev/ruby-lzws) |
|
6
6
|
|
7
7
|
See [lzws library](https://github.com/andrew-aladev/lzws).
|
8
8
|
|
@@ -21,6 +21,8 @@ rake gem
|
|
21
21
|
gem install pkg/ruby-lzws-*.gem
|
22
22
|
```
|
23
23
|
|
24
|
+
You can also use [overlay](https://github.com/andrew-aladev/overlay) for gentoo.
|
25
|
+
|
24
26
|
## Usage
|
25
27
|
|
26
28
|
There are simple APIs: `String` and `File`. Also you can use generic streaming API: `Stream::Writer` and `Stream::Reader`.
|
@@ -36,6 +38,27 @@ LZWS::File.decompress "file.txt.Z", "file.txt"
|
|
36
38
|
|
37
39
|
LZWS::Stream::Writer.open("file.txt.Z") { |writer| writer << "TOBEORNOTTOBEORTOBEORNOT" }
|
38
40
|
puts LZWS::Stream::Reader.open("file.txt.Z") { |reader| reader.read }
|
41
|
+
|
42
|
+
writer = LZWS::Stream::Writer.new output_socket
|
43
|
+
begin
|
44
|
+
bytes_written = writer.write_nonblock "TOBEORNOTTOBEORTOBEORNOT"
|
45
|
+
# handle "bytes_written"
|
46
|
+
rescue IO::WaitWritable
|
47
|
+
# handle wait
|
48
|
+
ensure
|
49
|
+
writer.close
|
50
|
+
end
|
51
|
+
|
52
|
+
reader = LZWS::Stream::Reader.new input_socket
|
53
|
+
begin
|
54
|
+
puts reader.read_nonblock(512)
|
55
|
+
rescue IO::WaitReadable
|
56
|
+
# handle wait
|
57
|
+
rescue ::EOFError
|
58
|
+
# handle eof
|
59
|
+
ensure
|
60
|
+
reader.close
|
61
|
+
end
|
39
62
|
```
|
40
63
|
|
41
64
|
You can create and read `tar.Z` archives with `minitar` for example.
|
@@ -63,59 +86,26 @@ end
|
|
63
86
|
|
64
87
|
## Options
|
65
88
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
89
|
+
| Option | Values | Default | Description |
|
90
|
+
|-----------------------------|------------|----------|-------------|
|
91
|
+
| `source_buffer_length` | 0, 2 - inf | 0 (auto) | internal buffer length for source data |
|
92
|
+
| `destination_buffer_length` | 0, 2 - inf | 0 (auto) | internal buffer length for description data |
|
93
|
+
| `max_code_bit_length` | 9 - 16 | 16 | max code bit length |
|
94
|
+
| `block_mode` | true/false | true | enables block mode |
|
95
|
+
| `without_magic_header` | true/false | false | disables magic header |
|
96
|
+
| `msb` | true/false | false | enables most significant bit mode |
|
97
|
+
| `unaligned_bit_groups` | true/false | false | enables unaligned bit groups |
|
98
|
+
| `quiet` | true/false | false | disables lzws library logging |
|
72
99
|
|
73
100
|
There are internal buffers for compressed and decompressed data.
|
74
|
-
For example you want to use 1 KB as
|
75
|
-
You want to use 256 B as
|
76
|
-
|
77
|
-
Values: 0, 2 - infinity, default value: 0.
|
78
|
-
0 means automatic buffer length selection.
|
79
|
-
1 byte is not enough, 2 bytes is minimal buffer length.
|
80
|
-
|
81
|
-
```
|
82
|
-
:max_code_bit_length
|
83
|
-
```
|
84
|
-
|
85
|
-
Values: `LZWS::Option::LOWEST_MAX_CODE_BIT_LENGTH` - `LZWS::Option::BIGGEST_MAX_CODE_BIT_LENGTH`, default value: `LZWS::Option::BIGGEST_MAX_CODE_BIT_LENGTH`.
|
86
|
-
|
87
|
-
```
|
88
|
-
:block_mode
|
89
|
-
```
|
90
|
-
|
91
|
-
Values: true/false, default value: true.
|
92
|
-
|
93
|
-
```
|
94
|
-
:without_magic_header
|
95
|
-
```
|
96
|
-
|
97
|
-
Values: true/false, default value: false.
|
98
|
-
|
99
|
-
```
|
100
|
-
:msb
|
101
|
-
```
|
102
|
-
|
103
|
-
Values: true/false, default value: false.
|
104
|
-
|
105
|
-
```
|
106
|
-
:unaligned_bit_groups
|
107
|
-
```
|
108
|
-
|
109
|
-
Values: true/false, default value: false.
|
110
|
-
|
111
|
-
```
|
112
|
-
:quiet
|
113
|
-
```
|
101
|
+
For example you want to use 1 KB as `source_buffer_length` for compressor - please use 256 B as `destination_buffer_length`.
|
102
|
+
You want to use 256 B as `source_buffer_length` for decompressor - please use 1 KB as `destination_buffer_length`.
|
114
103
|
|
115
|
-
|
116
|
-
Disables lzws library logging.
|
104
|
+
You can also read lzws docs for more info about options.
|
117
105
|
|
118
|
-
|
106
|
+
| Option | Related constants |
|
107
|
+
|-----------------------|-------------------|
|
108
|
+
| `max_code_bit_length` | `LZWS::Option::LOWEST_MAX_CODE_BIT_LENGTH` = 9, `LZWS::Option::BIGGEST_MAX_CODE_BIT_LENGTH` = 16 |
|
119
109
|
|
120
110
|
Possible compressor options:
|
121
111
|
```
|
@@ -186,7 +176,7 @@ File maintains both source and destination buffers, it accepts both `source_buff
|
|
186
176
|
|
187
177
|
## Stream::Writer
|
188
178
|
|
189
|
-
Its behaviour is similar to builtin [`Zlib::GzipWriter`](https://ruby-doc.org/stdlib-2.
|
179
|
+
Its behaviour is similar to builtin [`Zlib::GzipWriter`](https://ruby-doc.org/stdlib-2.7.0/libdoc/zlib/rdoc/Zlib/GzipWriter.html).
|
190
180
|
|
191
181
|
Writer maintains destination buffer only, so it accepts `destination_buffer_length` option only.
|
192
182
|
|
@@ -220,7 +210,7 @@ Set another encodings, `nil` is just for compatibility with `IO`.
|
|
220
210
|
#tell
|
221
211
|
```
|
222
212
|
|
223
|
-
See [`IO`](https://ruby-doc.org/core-2.
|
213
|
+
See [`IO`](https://ruby-doc.org/core-2.7.0/IO.html) docs.
|
224
214
|
|
225
215
|
```
|
226
216
|
#write(*objects)
|
@@ -230,7 +220,7 @@ See [`IO`](https://ruby-doc.org/core-2.6.1/IO.html) docs.
|
|
230
220
|
#closed?
|
231
221
|
```
|
232
222
|
|
233
|
-
See [`Zlib::GzipWriter`](https://ruby-doc.org/stdlib-2.
|
223
|
+
See [`Zlib::GzipWriter`](https://ruby-doc.org/stdlib-2.7.0/libdoc/zlib/rdoc/Zlib/GzipWriter.html) docs.
|
234
224
|
|
235
225
|
```
|
236
226
|
#write_nonblock(object, *options)
|
@@ -252,11 +242,11 @@ Behaviour is the same as `IO#write_nonblock` method.
|
|
252
242
|
#puts(*objects)
|
253
243
|
```
|
254
244
|
|
255
|
-
Typical helpers, see [`Zlib::GzipWriter`](https://ruby-doc.org/stdlib-2.
|
245
|
+
Typical helpers, see [`Zlib::GzipWriter`](https://ruby-doc.org/stdlib-2.7.0/libdoc/zlib/rdoc/Zlib/GzipWriter.html) docs.
|
256
246
|
|
257
247
|
## Stream::Reader
|
258
248
|
|
259
|
-
Its behaviour is similar to builtin [`Zlib::GzipReader`](https://ruby-doc.org/stdlib-2.
|
249
|
+
Its behaviour is similar to builtin [`Zlib::GzipReader`](https://ruby-doc.org/stdlib-2.7.0/libdoc/zlib/rdoc/Zlib/GzipReader.html).
|
260
250
|
|
261
251
|
Reader maintains both source and destination buffers, it accepts both `source_buffer_length` and `destination_buffer_length` options.
|
262
252
|
|
@@ -291,7 +281,7 @@ Set another encodings.
|
|
291
281
|
#tell
|
292
282
|
```
|
293
283
|
|
294
|
-
See [`IO`](https://ruby-doc.org/core-2.
|
284
|
+
See [`IO`](https://ruby-doc.org/core-2.7.0/IO.html) docs.
|
295
285
|
|
296
286
|
```
|
297
287
|
#read(bytes_to_read = nil, out_buffer = nil)
|
@@ -301,14 +291,14 @@ See [`IO`](https://ruby-doc.org/core-2.6.1/IO.html) docs.
|
|
301
291
|
#closed?
|
302
292
|
```
|
303
293
|
|
304
|
-
See [`Zlib::GzipReader`](https://ruby-doc.org/stdlib-2.
|
294
|
+
See [`Zlib::GzipReader`](https://ruby-doc.org/stdlib-2.7.0/libdoc/zlib/rdoc/Zlib/GzipReader.html) docs.
|
305
295
|
|
306
296
|
```
|
307
297
|
#readpartial(bytes_to_read = nil, out_buffer = nil)
|
308
298
|
#read_nonblock(bytes_to_read, out_buffer = nil, *options)
|
309
299
|
```
|
310
300
|
|
311
|
-
See [`IO`](https://ruby-doc.org/core-2.
|
301
|
+
See [`IO`](https://ruby-doc.org/core-2.7.0/IO.html) docs.
|
312
302
|
|
313
303
|
```
|
314
304
|
#getbyte
|
@@ -331,13 +321,13 @@ See [`IO`](https://ruby-doc.org/core-2.6.1/IO.html) docs.
|
|
331
321
|
#ungetline(line)
|
332
322
|
```
|
333
323
|
|
334
|
-
Typical helpers, see [`Zlib::GzipReader`](https://ruby-doc.org/stdlib-2.
|
324
|
+
Typical helpers, see [`Zlib::GzipReader`](https://ruby-doc.org/stdlib-2.7.0/libdoc/zlib/rdoc/Zlib/GzipReader.html) docs.
|
335
325
|
|
336
326
|
## CI
|
337
327
|
|
338
|
-
|
339
|
-
|
340
|
-
|
328
|
+
See universal test script [scripts/ci_test.sh](scripts/ci_test.sh) for CI.
|
329
|
+
Please visit [scripts/test-images](scripts/test-images).
|
330
|
+
You can run this test script using many native and cross images.
|
341
331
|
|
342
332
|
## License
|
343
333
|
|
data/ext/extconf.rb
CHANGED
@@ -66,7 +66,20 @@ $srcs = %w[
|
|
66
66
|
.map { |name| "src/#{extension_name}/#{name}.c" }
|
67
67
|
.freeze
|
68
68
|
|
69
|
+
# Removing library duplicates.
|
70
|
+
$libs = $libs.split(%r{\s})
|
71
|
+
.reject(&:empty?)
|
72
|
+
.sort
|
73
|
+
.uniq
|
74
|
+
.join " "
|
75
|
+
|
76
|
+
if ENV["CI"] || ENV["COVERAGE"]
|
77
|
+
$CFLAGS << " --coverage"
|
78
|
+
$LDFLAGS << " --coverage"
|
79
|
+
end
|
80
|
+
|
69
81
|
$CFLAGS << " -Wno-declaration-after-statement"
|
82
|
+
|
70
83
|
$VPATH << "$(srcdir)/#{extension_name}:$(srcdir)/#{extension_name}/stream"
|
71
84
|
# rubocop:enable Style/GlobalVars
|
72
85
|
|
data/ext/lzws_ext/common.h
CHANGED
data/ext/lzws_ext/error.c
CHANGED
data/ext/lzws_ext/io.c
CHANGED
data/ext/lzws_ext/main.c
CHANGED
data/ext/lzws_ext/option.c
CHANGED
data/ext/lzws_ext/option.h
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
#include <stdbool.h>
|
8
8
|
#include <stdlib.h>
|
9
9
|
|
10
|
+
#include "lzws_ext/common.h"
|
10
11
|
#include "ruby.h"
|
11
12
|
|
12
13
|
bool lzws_ext_get_bool_option_value(VALUE options, const char* name);
|
@@ -22,12 +23,12 @@ size_t lzws_ext_get_size_option_value(VALUE options, const char* name);
|
|
22
23
|
#define LZWS_EXT_GET_SIZE_OPTION(options, name) \
|
23
24
|
size_t name = lzws_ext_get_size_option_value(options, #name);
|
24
25
|
|
25
|
-
#define LZWS_EXT_GET_COMPRESSOR_OPTIONS(options)
|
26
|
-
LZWS_EXT_GET_BOOL_OPTION(options, without_magic_header);
|
27
|
-
LZWS_EXT_GET_UINT_OPTION(options,
|
28
|
-
LZWS_EXT_GET_BOOL_OPTION(options, block_mode);
|
29
|
-
LZWS_EXT_GET_BOOL_OPTION(options, msb);
|
30
|
-
LZWS_EXT_GET_BOOL_OPTION(options, unaligned_bit_groups);
|
26
|
+
#define LZWS_EXT_GET_COMPRESSOR_OPTIONS(options) \
|
27
|
+
LZWS_EXT_GET_BOOL_OPTION(options, without_magic_header); \
|
28
|
+
LZWS_EXT_GET_UINT_OPTION(options, lzws_ext_byte_fast_t, max_code_bit_length); \
|
29
|
+
LZWS_EXT_GET_BOOL_OPTION(options, block_mode); \
|
30
|
+
LZWS_EXT_GET_BOOL_OPTION(options, msb); \
|
31
|
+
LZWS_EXT_GET_BOOL_OPTION(options, unaligned_bit_groups); \
|
31
32
|
LZWS_EXT_GET_BOOL_OPTION(options, quiet);
|
32
33
|
|
33
34
|
#define LZWS_EXT_GET_DECOMPRESSOR_OPTIONS(options) \
|
@@ -8,8 +8,6 @@
|
|
8
8
|
#include <lzws/compressor/common.h>
|
9
9
|
#include <lzws/compressor/main.h>
|
10
10
|
#include <lzws/compressor/state.h>
|
11
|
-
#include <stdint.h>
|
12
|
-
#include <stdlib.h>
|
13
11
|
|
14
12
|
#include "lzws_ext/error.h"
|
15
13
|
#include "lzws_ext/option.h"
|
@@ -22,7 +20,7 @@ static void free_compressor(lzws_ext_compressor_t* compressor_ptr)
|
|
22
20
|
lzws_compressor_free_state(state_ptr);
|
23
21
|
}
|
24
22
|
|
25
|
-
|
23
|
+
lzws_ext_byte_t* destination_buffer = compressor_ptr->destination_buffer;
|
26
24
|
if (destination_buffer != NULL) {
|
27
25
|
free(destination_buffer);
|
28
26
|
}
|
@@ -73,7 +71,7 @@ VALUE lzws_ext_initialize_compressor(VALUE self, VALUE options)
|
|
73
71
|
}
|
74
72
|
}
|
75
73
|
|
76
|
-
|
74
|
+
lzws_ext_byte_t* destination_buffer;
|
77
75
|
|
78
76
|
result = lzws_create_destination_buffer_for_compressor(&destination_buffer, &destination_buffer_length, quiet);
|
79
77
|
if (result != 0) {
|
@@ -95,13 +93,13 @@ VALUE lzws_ext_initialize_compressor(VALUE self, VALUE options)
|
|
95
93
|
lzws_ext_raise_error(LZWS_EXT_ERROR_USED_AFTER_CLOSE); \
|
96
94
|
}
|
97
95
|
|
98
|
-
#define GET_SOURCE_DATA(source_value)
|
99
|
-
Check_Type(source_value, T_STRING);
|
100
|
-
|
101
|
-
const char*
|
102
|
-
size_t
|
103
|
-
|
104
|
-
size_t
|
96
|
+
#define GET_SOURCE_DATA(source_value) \
|
97
|
+
Check_Type(source_value, T_STRING); \
|
98
|
+
\
|
99
|
+
const char* source = RSTRING_PTR(source_value); \
|
100
|
+
size_t source_length = RSTRING_LEN(source_value); \
|
101
|
+
lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*)source; \
|
102
|
+
size_t remaining_source_length = source_length;
|
105
103
|
|
106
104
|
VALUE lzws_ext_compress(VALUE self, VALUE source_value)
|
107
105
|
{
|
@@ -151,9 +149,9 @@ VALUE lzws_ext_compressor_read_result(VALUE self)
|
|
151
149
|
GET_COMPRESSOR(self);
|
152
150
|
DO_NOT_USE_AFTER_CLOSE(compressor_ptr);
|
153
151
|
|
154
|
-
|
155
|
-
size_t
|
156
|
-
size_t
|
152
|
+
lzws_ext_byte_t* destination_buffer = compressor_ptr->destination_buffer;
|
153
|
+
size_t destination_buffer_length = compressor_ptr->destination_buffer_length;
|
154
|
+
size_t remaining_destination_buffer_length = compressor_ptr->remaining_destination_buffer_length;
|
157
155
|
|
158
156
|
const char* result = (const char*)destination_buffer;
|
159
157
|
size_t result_length = destination_buffer_length - remaining_destination_buffer_length;
|
@@ -178,7 +176,7 @@ VALUE lzws_ext_compressor_close(VALUE self)
|
|
178
176
|
compressor_ptr->state_ptr = NULL;
|
179
177
|
}
|
180
178
|
|
181
|
-
|
179
|
+
lzws_ext_byte_t* destination_buffer = compressor_ptr->destination_buffer;
|
182
180
|
if (destination_buffer != NULL) {
|
183
181
|
free(destination_buffer);
|
184
182
|
|
@@ -5,16 +5,16 @@
|
|
5
5
|
#define LZWS_EXT_STREAM_COMPRESSOR_H
|
6
6
|
|
7
7
|
#include <lzws/compressor/state.h>
|
8
|
-
#include <stdint.h>
|
9
8
|
#include <stdlib.h>
|
10
9
|
|
10
|
+
#include "lzws_ext/common.h"
|
11
11
|
#include "ruby.h"
|
12
12
|
|
13
13
|
typedef struct {
|
14
14
|
lzws_compressor_state_t* state_ptr;
|
15
|
-
|
15
|
+
lzws_ext_byte_t* destination_buffer;
|
16
16
|
size_t destination_buffer_length;
|
17
|
-
|
17
|
+
lzws_ext_byte_t* remaining_destination_buffer;
|
18
18
|
size_t remaining_destination_buffer_length;
|
19
19
|
} lzws_ext_compressor_t;
|
20
20
|
|
@@ -8,8 +8,6 @@
|
|
8
8
|
#include <lzws/decompressor/common.h>
|
9
9
|
#include <lzws/decompressor/main.h>
|
10
10
|
#include <lzws/decompressor/state.h>
|
11
|
-
#include <stdint.h>
|
12
|
-
#include <stdlib.h>
|
13
11
|
|
14
12
|
#include "lzws_ext/error.h"
|
15
13
|
#include "lzws_ext/option.h"
|
@@ -22,7 +20,7 @@ static void free_decompressor(lzws_ext_decompressor_t* decompressor_ptr)
|
|
22
20
|
lzws_decompressor_free_state(state_ptr);
|
23
21
|
}
|
24
22
|
|
25
|
-
|
23
|
+
lzws_ext_byte_t* destination_buffer = decompressor_ptr->destination_buffer;
|
26
24
|
if (destination_buffer != NULL) {
|
27
25
|
free(destination_buffer);
|
28
26
|
}
|
@@ -71,7 +69,7 @@ VALUE lzws_ext_initialize_decompressor(VALUE self, VALUE options)
|
|
71
69
|
}
|
72
70
|
}
|
73
71
|
|
74
|
-
|
72
|
+
lzws_ext_byte_t* destination_buffer;
|
75
73
|
|
76
74
|
result = lzws_create_destination_buffer_for_decompressor(&destination_buffer, &destination_buffer_length, quiet);
|
77
75
|
if (result != 0) {
|
@@ -93,13 +91,13 @@ VALUE lzws_ext_initialize_decompressor(VALUE self, VALUE options)
|
|
93
91
|
lzws_ext_raise_error(LZWS_EXT_ERROR_USED_AFTER_CLOSE); \
|
94
92
|
}
|
95
93
|
|
96
|
-
#define GET_SOURCE_DATA(source_value)
|
97
|
-
Check_Type(source_value, T_STRING);
|
98
|
-
|
99
|
-
const char*
|
100
|
-
size_t
|
101
|
-
|
102
|
-
size_t
|
94
|
+
#define GET_SOURCE_DATA(source_value) \
|
95
|
+
Check_Type(source_value, T_STRING); \
|
96
|
+
\
|
97
|
+
const char* source = RSTRING_PTR(source_value); \
|
98
|
+
size_t source_length = RSTRING_LEN(source_value); \
|
99
|
+
lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*)source; \
|
100
|
+
size_t remaining_source_length = source_length;
|
103
101
|
|
104
102
|
VALUE lzws_ext_decompress(VALUE self, VALUE source_value)
|
105
103
|
{
|
@@ -137,9 +135,9 @@ VALUE lzws_ext_decompressor_read_result(VALUE self)
|
|
137
135
|
GET_DECOMPRESSOR(self);
|
138
136
|
DO_NOT_USE_AFTER_CLOSE(decompressor_ptr);
|
139
137
|
|
140
|
-
|
141
|
-
size_t
|
142
|
-
size_t
|
138
|
+
lzws_ext_byte_t* destination_buffer = decompressor_ptr->destination_buffer;
|
139
|
+
size_t destination_buffer_length = decompressor_ptr->destination_buffer_length;
|
140
|
+
size_t remaining_destination_buffer_length = decompressor_ptr->remaining_destination_buffer_length;
|
143
141
|
|
144
142
|
const char* result = (const char*)destination_buffer;
|
145
143
|
size_t result_length = destination_buffer_length - remaining_destination_buffer_length;
|
@@ -164,7 +162,7 @@ VALUE lzws_ext_decompressor_close(VALUE self)
|
|
164
162
|
decompressor_ptr->state_ptr = NULL;
|
165
163
|
}
|
166
164
|
|
167
|
-
|
165
|
+
lzws_ext_byte_t* destination_buffer = decompressor_ptr->destination_buffer;
|
168
166
|
if (destination_buffer != NULL) {
|
169
167
|
free(destination_buffer);
|
170
168
|
|
@@ -5,16 +5,16 @@
|
|
5
5
|
#define LZWS_EXT_STREAM_DECOMPRESSOR_H
|
6
6
|
|
7
7
|
#include <lzws/decompressor/state.h>
|
8
|
-
#include <stdint.h>
|
9
8
|
#include <stdlib.h>
|
10
9
|
|
10
|
+
#include "lzws_ext/common.h"
|
11
11
|
#include "ruby.h"
|
12
12
|
|
13
13
|
typedef struct {
|
14
14
|
lzws_decompressor_state_t* state_ptr;
|
15
|
-
|
15
|
+
lzws_ext_byte_t* destination_buffer;
|
16
16
|
size_t destination_buffer_length;
|
17
|
-
|
17
|
+
lzws_ext_byte_t* remaining_destination_buffer;
|
18
18
|
size_t remaining_destination_buffer_length;
|
19
19
|
} lzws_ext_decompressor_t;
|
20
20
|
|
data/ext/lzws_ext/string.c
CHANGED
@@ -11,7 +11,6 @@
|
|
11
11
|
#include <lzws/decompressor/common.h>
|
12
12
|
#include <lzws/decompressor/main.h>
|
13
13
|
#include <lzws/decompressor/state.h>
|
14
|
-
#include <stdint.h>
|
15
14
|
#include <stdlib.h>
|
16
15
|
|
17
16
|
#include "lzws_ext/buffer.h"
|
@@ -53,34 +52,34 @@ static inline lzws_ext_result_t increase_destination_buffer(
|
|
53
52
|
|
54
53
|
// -- compress --
|
55
54
|
|
56
|
-
#define BUFFERED_COMPRESS(function, ...)
|
57
|
-
while (true) {
|
58
|
-
|
59
|
-
size_t
|
60
|
-
|
61
|
-
result = function(__VA_ARGS__, &remaining_destination_buffer, &remaining_destination_buffer_length);
|
62
|
-
|
63
|
-
if (
|
64
|
-
result != 0 &&
|
65
|
-
result != LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) {
|
66
|
-
return LZWS_EXT_ERROR_UNEXPECTED;
|
67
|
-
}
|
68
|
-
|
69
|
-
destination_length += prev_remaining_destination_buffer_length - remaining_destination_buffer_length;
|
70
|
-
|
71
|
-
if (result == LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) {
|
72
|
-
ext_result = increase_destination_buffer(
|
73
|
-
destination_value, destination_length,
|
74
|
-
&remaining_destination_buffer_length, destination_buffer_length);
|
75
|
-
|
76
|
-
if (ext_result != 0) {
|
77
|
-
return ext_result;
|
78
|
-
}
|
79
|
-
|
80
|
-
continue;
|
81
|
-
}
|
82
|
-
|
83
|
-
break;
|
55
|
+
#define BUFFERED_COMPRESS(function, ...) \
|
56
|
+
while (true) { \
|
57
|
+
lzws_ext_byte_t* remaining_destination_buffer = (lzws_ext_byte_t*)RSTRING_PTR(destination_value) + destination_length; \
|
58
|
+
size_t prev_remaining_destination_buffer_length = remaining_destination_buffer_length; \
|
59
|
+
\
|
60
|
+
result = function(__VA_ARGS__, &remaining_destination_buffer, &remaining_destination_buffer_length); \
|
61
|
+
\
|
62
|
+
if ( \
|
63
|
+
result != 0 && \
|
64
|
+
result != LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) { \
|
65
|
+
return LZWS_EXT_ERROR_UNEXPECTED; \
|
66
|
+
} \
|
67
|
+
\
|
68
|
+
destination_length += prev_remaining_destination_buffer_length - remaining_destination_buffer_length; \
|
69
|
+
\
|
70
|
+
if (result == LZWS_COMPRESSOR_NEEDS_MORE_DESTINATION) { \
|
71
|
+
ext_result = increase_destination_buffer( \
|
72
|
+
destination_value, destination_length, \
|
73
|
+
&remaining_destination_buffer_length, destination_buffer_length); \
|
74
|
+
\
|
75
|
+
if (ext_result != 0) { \
|
76
|
+
return ext_result; \
|
77
|
+
} \
|
78
|
+
\
|
79
|
+
continue; \
|
80
|
+
} \
|
81
|
+
\
|
82
|
+
break; \
|
84
83
|
}
|
85
84
|
|
86
85
|
static inline lzws_ext_result_t compress(
|
@@ -91,8 +90,8 @@ static inline lzws_ext_result_t compress(
|
|
91
90
|
lzws_result_t result;
|
92
91
|
lzws_ext_result_t ext_result;
|
93
92
|
|
94
|
-
|
95
|
-
size_t
|
93
|
+
lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*)source;
|
94
|
+
size_t remaining_source_length = source_length;
|
96
95
|
|
97
96
|
size_t destination_length = 0;
|
98
97
|
size_t remaining_destination_buffer_length = destination_buffer_length;
|
@@ -170,15 +169,15 @@ static inline lzws_ext_result_t decompress(
|
|
170
169
|
lzws_result_t result;
|
171
170
|
lzws_ext_result_t ext_result;
|
172
171
|
|
173
|
-
|
174
|
-
size_t
|
172
|
+
lzws_ext_byte_t* remaining_source = (lzws_ext_byte_t*)source;
|
173
|
+
size_t remaining_source_length = source_length;
|
175
174
|
|
176
175
|
size_t destination_length = 0;
|
177
176
|
size_t remaining_destination_buffer_length = destination_buffer_length;
|
178
177
|
|
179
178
|
while (true) {
|
180
|
-
|
181
|
-
size_t
|
179
|
+
lzws_ext_byte_t* remaining_destination_buffer = (lzws_ext_byte_t*)RSTRING_PTR(destination_value) + destination_length;
|
180
|
+
size_t prev_remaining_destination_buffer_length = remaining_destination_buffer_length;
|
182
181
|
|
183
182
|
result = lzws_decompress(
|
184
183
|
state_ptr,
|
data/lib/lzws/file.rb
CHANGED
@@ -20,6 +20,8 @@ module LZWS
|
|
20
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
|
+
|
24
|
+
nil
|
23
25
|
end
|
24
26
|
|
25
27
|
def self.decompress(source, destination, options = {})
|
@@ -31,6 +33,8 @@ module LZWS
|
|
31
33
|
open_files(source, destination) do |source_io, destination_io|
|
32
34
|
LZWS._native_decompress_io source_io, destination_io, options
|
33
35
|
end
|
36
|
+
|
37
|
+
nil
|
34
38
|
end
|
35
39
|
|
36
40
|
private_class_method def self.open_files(source, destination, &_block)
|
data/lib/lzws/stream/abstract.rb
CHANGED
@@ -17,23 +17,19 @@ module LZWS
|
|
17
17
|
|
18
18
|
include Delegates
|
19
19
|
|
20
|
-
attr_reader :io
|
21
|
-
|
22
|
-
attr_reader :external_encoding
|
23
|
-
attr_reader :internal_encoding
|
24
|
-
attr_reader :transcode_options
|
25
|
-
attr_reader :pos
|
20
|
+
attr_reader :io, :stat, :external_encoding, :internal_encoding, :transcode_options, :pos
|
21
|
+
|
26
22
|
alias tell pos
|
27
23
|
|
28
|
-
def initialize(io,
|
24
|
+
def initialize(io, options = {})
|
29
25
|
@raw_stream = create_raw_stream
|
30
26
|
|
31
27
|
Validation.validate_io io
|
32
28
|
@io = io
|
33
29
|
|
34
|
-
@stat = Stat.new @io.stat
|
30
|
+
@stat = Stat.new @io.stat if @io.respond_to? :stat
|
35
31
|
|
36
|
-
set_encoding external_encoding, internal_encoding, transcode_options
|
32
|
+
set_encoding options[:external_encoding], options[:internal_encoding], options[:transcode_options]
|
37
33
|
reset_buffer
|
38
34
|
reset_io_advise
|
39
35
|
|
@@ -50,8 +46,8 @@ module LZWS
|
|
50
46
|
|
51
47
|
protected def reset_io_advise
|
52
48
|
# Both compressor and decompressor need sequential io access.
|
53
|
-
@io.advise :sequential
|
54
|
-
rescue ::Errno::ESPIPE
|
49
|
+
@io.advise :sequential if @io.respond_to? :advise
|
50
|
+
rescue ::Errno::ESPIPE
|
55
51
|
# ok
|
56
52
|
end
|
57
53
|
|
@@ -126,7 +122,8 @@ module LZWS
|
|
126
122
|
def rewind
|
127
123
|
@raw_stream = create_raw_stream
|
128
124
|
|
129
|
-
@io.rewind
|
125
|
+
@io.rewind if @io.respond_to? :rewind
|
126
|
+
|
130
127
|
reset_buffer
|
131
128
|
reset_io_advise
|
132
129
|
|
@@ -27,9 +27,9 @@ module LZWS
|
|
27
27
|
nil
|
28
28
|
end
|
29
29
|
|
30
|
-
protected def
|
30
|
+
protected def more_destination(&writer)
|
31
31
|
result_bytesize = write_result(&writer)
|
32
|
-
raise NotEnoughDestinationError, "not enough destination" if result_bytesize
|
32
|
+
raise NotEnoughDestinationError, "not enough destination" if result_bytesize.zero?
|
33
33
|
end
|
34
34
|
|
35
35
|
protected def write_result(&_writer)
|
@@ -50,6 +50,8 @@ module LZWS
|
|
50
50
|
|
51
51
|
@native_stream.close
|
52
52
|
@is_closed = true
|
53
|
+
|
54
|
+
nil
|
53
55
|
end
|
54
56
|
|
55
57
|
def closed?
|
@@ -35,13 +35,15 @@ module LZWS
|
|
35
35
|
|
36
36
|
if need_more_destination
|
37
37
|
source = source.byteslice bytes_written, source.bytesize - bytes_written
|
38
|
-
|
38
|
+
more_destination(&writer)
|
39
39
|
next
|
40
40
|
end
|
41
41
|
|
42
42
|
unless bytes_written == source.bytesize
|
43
|
+
# :nocov:
|
43
44
|
# Compressor write should eat all provided "source" without remainder.
|
44
45
|
raise UnexpectedError, "unexpected error"
|
46
|
+
# :nocov:
|
45
47
|
end
|
46
48
|
|
47
49
|
break
|
@@ -59,7 +61,7 @@ module LZWS
|
|
59
61
|
need_more_destination = @native_stream.finish
|
60
62
|
|
61
63
|
if need_more_destination
|
62
|
-
|
64
|
+
more_destination(&writer)
|
63
65
|
next
|
64
66
|
end
|
65
67
|
|
@@ -67,8 +69,6 @@ module LZWS
|
|
67
69
|
end
|
68
70
|
|
69
71
|
super
|
70
|
-
|
71
|
-
nil
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -34,7 +34,7 @@ module LZWS
|
|
34
34
|
|
35
35
|
if need_more_destination
|
36
36
|
source = source.byteslice bytes_read, source.bytesize - bytes_read
|
37
|
-
|
37
|
+
more_destination(&writer)
|
38
38
|
next
|
39
39
|
end
|
40
40
|
|
@@ -51,8 +51,6 @@ module LZWS
|
|
51
51
|
Validation.validate_proc writer
|
52
52
|
|
53
53
|
super
|
54
|
-
|
55
|
-
nil
|
56
54
|
end
|
57
55
|
end
|
58
56
|
end
|
data/lib/lzws/stream/reader.rb
CHANGED
@@ -20,79 +20,60 @@ module LZWS
|
|
20
20
|
|
21
21
|
initialize_source_buffer_length
|
22
22
|
reset_io_remainder
|
23
|
+
reset_need_to_flush
|
23
24
|
|
24
25
|
@lineno = 0
|
25
26
|
end
|
26
27
|
|
28
|
+
protected def create_raw_stream
|
29
|
+
Raw::Decompressor.new @options
|
30
|
+
end
|
31
|
+
|
27
32
|
protected def initialize_source_buffer_length
|
28
33
|
source_buffer_length = @options[:source_buffer_length]
|
29
34
|
Validation.validate_not_negative_integer source_buffer_length unless source_buffer_length.nil?
|
30
35
|
|
31
36
|
source_buffer_length = Buffer::DEFAULT_SOURCE_BUFFER_LENGTH_FOR_DECOMPRESSOR \
|
32
|
-
if source_buffer_length
|
37
|
+
if source_buffer_length.nil? || source_buffer_length.zero?
|
33
38
|
|
34
39
|
@source_buffer_length = source_buffer_length
|
35
40
|
end
|
36
41
|
|
37
|
-
protected def create_raw_stream
|
38
|
-
Raw::Decompressor.new @options
|
39
|
-
end
|
40
|
-
|
41
42
|
protected def reset_io_remainder
|
42
43
|
@io_remainder = ::String.new :encoding => ::Encoding::BINARY
|
43
44
|
end
|
44
45
|
|
46
|
+
protected def reset_need_to_flush
|
47
|
+
@need_to_flush = false
|
48
|
+
end
|
49
|
+
|
45
50
|
# -- synchronous --
|
46
51
|
|
47
52
|
def read(bytes_to_read = nil, out_buffer = nil)
|
48
53
|
Validation.validate_not_negative_integer bytes_to_read unless bytes_to_read.nil?
|
49
54
|
Validation.validate_string out_buffer unless out_buffer.nil?
|
50
55
|
|
51
|
-
return ::String.new :encoding => ::Encoding::BINARY if bytes_to_read == 0
|
52
|
-
|
53
56
|
unless bytes_to_read.nil?
|
57
|
+
return ::String.new :encoding => ::Encoding::BINARY if bytes_to_read.zero?
|
54
58
|
return nil if eof?
|
55
59
|
|
56
|
-
|
60
|
+
append_io_data @io.read(@source_buffer_length) while @buffer.bytesize < bytes_to_read && !@io.eof?
|
61
|
+
flush_io_data if @buffer.bytesize < bytes_to_read
|
57
62
|
|
58
63
|
return read_bytes_from_buffer bytes_to_read, out_buffer
|
59
64
|
end
|
60
65
|
|
61
|
-
|
62
|
-
|
63
|
-
result = @buffer
|
64
|
-
reset_buffer
|
65
|
-
@pos += result.bytesize
|
66
|
+
append_io_data @io.read(@source_buffer_length) until @io.eof?
|
67
|
+
flush_io_data
|
66
68
|
|
67
|
-
|
68
|
-
result = transcode_to_internal result
|
69
|
-
result = out_buffer.replace result unless out_buffer.nil?
|
70
|
-
|
71
|
-
result
|
72
|
-
end
|
73
|
-
|
74
|
-
protected def read_more_from_buffer
|
75
|
-
io_data = @io.read @source_buffer_length
|
76
|
-
append_io_data_to_buffer io_data
|
77
|
-
end
|
78
|
-
|
79
|
-
def readpartial(bytes_to_read = nil, out_buffer = nil)
|
80
|
-
raise ::EOFError if eof?
|
81
|
-
|
82
|
-
readpartial_from_buffer until @buffer.bytesize >= bytes_to_read || @io.eof?
|
83
|
-
|
84
|
-
read_bytes_from_buffer bytes_to_read, out_buffer
|
85
|
-
end
|
86
|
-
|
87
|
-
protected def readpartial_from_buffer
|
88
|
-
io_data = @io.readpartial @source_buffer_length
|
89
|
-
append_io_data_to_buffer io_data
|
69
|
+
read_buffer out_buffer
|
90
70
|
end
|
91
71
|
|
92
72
|
def rewind
|
93
73
|
raw_wrapper :close
|
94
74
|
|
95
75
|
reset_io_remainder
|
76
|
+
reset_need_to_flush
|
96
77
|
|
97
78
|
super
|
98
79
|
end
|
@@ -103,25 +84,61 @@ module LZWS
|
|
103
84
|
super
|
104
85
|
end
|
105
86
|
|
87
|
+
def eof?
|
88
|
+
empty? && @io.eof?
|
89
|
+
end
|
90
|
+
|
106
91
|
# -- asynchronous --
|
107
92
|
|
93
|
+
def readpartial(bytes_to_read, out_buffer = nil)
|
94
|
+
read_more_nonblock(bytes_to_read, out_buffer) { @io.readpartial @source_buffer_length }
|
95
|
+
end
|
96
|
+
|
108
97
|
def read_nonblock(bytes_to_read, out_buffer = nil, *options)
|
109
|
-
|
98
|
+
read_more_nonblock(bytes_to_read, out_buffer) { @io.read_nonblock(@source_buffer_length, *options) }
|
99
|
+
end
|
100
|
+
|
101
|
+
protected def read_more_nonblock(bytes_to_read, out_buffer, &_block)
|
102
|
+
Validation.validate_not_negative_integer bytes_to_read
|
103
|
+
Validation.validate_string out_buffer unless out_buffer.nil?
|
104
|
+
|
105
|
+
return ::String.new :encoding => ::Encoding::BINARY if bytes_to_read.zero?
|
106
|
+
|
107
|
+
io_provided_eof_error = false
|
110
108
|
|
111
|
-
|
109
|
+
if @buffer.bytesize < bytes_to_read
|
110
|
+
begin
|
111
|
+
append_io_data yield
|
112
|
+
rescue ::EOFError
|
113
|
+
io_provided_eof_error = true
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
flush_io_data if @buffer.bytesize < bytes_to_read
|
118
|
+
raise ::EOFError if empty? && io_provided_eof_error
|
112
119
|
|
113
120
|
read_bytes_from_buffer bytes_to_read, out_buffer
|
114
121
|
end
|
115
122
|
|
116
|
-
|
117
|
-
|
118
|
-
|
123
|
+
# -- common --
|
124
|
+
|
125
|
+
protected def append_io_data(io_data)
|
126
|
+
io_portion = @io_remainder + io_data
|
127
|
+
bytes_read = raw_wrapper :read, io_portion
|
128
|
+
@io_remainder = io_portion.byteslice bytes_read, io_portion.bytesize - bytes_read
|
129
|
+
|
130
|
+
# Even empty io data may require flush.
|
131
|
+
@need_to_flush = true
|
119
132
|
end
|
120
133
|
|
121
|
-
|
134
|
+
protected def flush_io_data
|
135
|
+
raw_wrapper :flush
|
122
136
|
|
123
|
-
|
124
|
-
|
137
|
+
@need_to_flush = false
|
138
|
+
end
|
139
|
+
|
140
|
+
protected def empty?
|
141
|
+
!@need_to_flush && @buffer.bytesize.zero?
|
125
142
|
end
|
126
143
|
|
127
144
|
protected def read_bytes_from_buffer(bytes_to_read, out_buffer)
|
@@ -136,18 +153,20 @@ module LZWS
|
|
136
153
|
result
|
137
154
|
end
|
138
155
|
|
139
|
-
protected def
|
140
|
-
|
141
|
-
|
142
|
-
@
|
156
|
+
protected def read_buffer(out_buffer)
|
157
|
+
result = @buffer
|
158
|
+
reset_buffer
|
159
|
+
@pos += result.bytesize
|
143
160
|
|
144
|
-
|
145
|
-
|
146
|
-
|
161
|
+
result.force_encoding @external_encoding unless @external_encoding.nil?
|
162
|
+
result = transcode_to_internal result
|
163
|
+
|
164
|
+
result = out_buffer.replace result unless out_buffer.nil?
|
165
|
+
result
|
147
166
|
end
|
148
167
|
|
149
168
|
protected def transcode_to_internal(data)
|
150
|
-
data = data.encode @internal_encoding,
|
169
|
+
data = data.encode @internal_encoding, **@transcode_options unless @internal_encoding.nil?
|
151
170
|
data
|
152
171
|
end
|
153
172
|
|
data/lib/lzws/stream/writer.rb
CHANGED
@@ -64,7 +64,7 @@ module LZWS
|
|
64
64
|
end
|
65
65
|
|
66
66
|
protected def write_remaining_buffer
|
67
|
-
return nil if @buffer.bytesize
|
67
|
+
return nil if @buffer.bytesize.zero?
|
68
68
|
|
69
69
|
@io.write @buffer
|
70
70
|
|
@@ -77,6 +77,11 @@ module LZWS
|
|
77
77
|
|
78
78
|
# -- asynchronous --
|
79
79
|
|
80
|
+
# IO write nonblock can raise wait writable error.
|
81
|
+
# After resolving this error user may provide same content again.
|
82
|
+
# It is not possible to revert accepted content after error.
|
83
|
+
# So we have to accept content after processing IO write nonblock.
|
84
|
+
# It means that first write nonblock won't call IO write nonblock.
|
80
85
|
def write_nonblock(object, *options)
|
81
86
|
return 0 unless write_remaining_buffer_nonblock(*options)
|
82
87
|
|
@@ -120,14 +125,14 @@ module LZWS
|
|
120
125
|
end
|
121
126
|
|
122
127
|
protected def write_remaining_buffer_nonblock(*options)
|
123
|
-
return true if @buffer.bytesize
|
128
|
+
return true if @buffer.bytesize.zero?
|
124
129
|
|
125
130
|
bytes_written = @io.write_nonblock @buffer, *options
|
126
|
-
return false if bytes_written
|
131
|
+
return false if bytes_written.zero?
|
127
132
|
|
128
133
|
@buffer = @buffer.byteslice bytes_written, @buffer.bytesize - bytes_written
|
129
134
|
|
130
|
-
@buffer.bytesize
|
135
|
+
@buffer.bytesize.zero?
|
131
136
|
end
|
132
137
|
|
133
138
|
protected def raw_nonblock_wrapper(method_name, *args)
|
@@ -137,7 +142,7 @@ module LZWS
|
|
137
142
|
# -- common --
|
138
143
|
|
139
144
|
protected def transcode(data)
|
140
|
-
data = data.encode @external_encoding,
|
145
|
+
data = data.encode @external_encoding, **@transcode_options unless @external_encoding.nil?
|
141
146
|
data
|
142
147
|
end
|
143
148
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# Ruby bindings for lzws library.
|
2
2
|
# Copyright (c) 2019 AUTHORS, MIT License.
|
3
3
|
|
4
|
+
require "English"
|
5
|
+
|
4
6
|
require_relative "../error"
|
5
7
|
require_relative "../validation"
|
6
8
|
|
@@ -11,18 +13,13 @@ module LZWS
|
|
11
13
|
write object
|
12
14
|
end
|
13
15
|
|
14
|
-
def print(*objects)
|
15
|
-
if objects.empty?
|
16
|
-
write $LAST_READ_LINE unless $LAST_READ_LINE.nil?
|
17
|
-
return nil
|
18
|
-
end
|
19
|
-
|
16
|
+
def print(*objects, field_separator: $OUTPUT_FIELD_SEPARATOR, record_separator: $OUTPUT_RECORD_SEPARATOR)
|
20
17
|
objects.each do |object|
|
21
18
|
write object
|
22
|
-
write
|
19
|
+
write field_separator unless field_separator.nil?
|
23
20
|
end
|
24
21
|
|
25
|
-
write
|
22
|
+
write record_separator unless record_separator.nil?
|
26
23
|
|
27
24
|
nil
|
28
25
|
end
|
@@ -34,9 +31,10 @@ module LZWS
|
|
34
31
|
end
|
35
32
|
|
36
33
|
def putc(object, encoding: ::Encoding::BINARY)
|
37
|
-
|
34
|
+
case object
|
35
|
+
when ::Numeric
|
38
36
|
write object.chr(encoding)
|
39
|
-
|
37
|
+
when ::String
|
40
38
|
write object[0]
|
41
39
|
else
|
42
40
|
raise ValidateError, "invalid object: \"#{object}\" for putc"
|
data/lib/lzws/validation.rb
CHANGED
@@ -5,12 +5,25 @@ require_relative "error"
|
|
5
5
|
|
6
6
|
module LZWS
|
7
7
|
module Validation
|
8
|
+
IO_METHODS = %i[
|
9
|
+
read
|
10
|
+
write
|
11
|
+
readpartial
|
12
|
+
read_nonblock
|
13
|
+
write_nonblock
|
14
|
+
eof?
|
15
|
+
flush
|
16
|
+
close
|
17
|
+
closed?
|
18
|
+
]
|
19
|
+
.freeze
|
20
|
+
|
8
21
|
def self.validate_bool(value)
|
9
22
|
raise ValidateError, "invalid bool" unless value.is_a?(::TrueClass) || value.is_a?(::FalseClass)
|
10
23
|
end
|
11
24
|
|
12
25
|
def self.validate_positive_integer(value)
|
13
|
-
raise ValidateError, "invalid positive integer" unless value.is_a?(::Integer) && value
|
26
|
+
raise ValidateError, "invalid positive integer" unless value.is_a?(::Integer) && value.positive?
|
14
27
|
end
|
15
28
|
|
16
29
|
def self.validate_not_negative_integer(value)
|
@@ -22,7 +35,7 @@ module LZWS
|
|
22
35
|
end
|
23
36
|
|
24
37
|
def self.validate_io(value)
|
25
|
-
raise ValidateError, "invalid io" unless value.
|
38
|
+
raise ValidateError, "invalid io" unless IO_METHODS.all? { |method| value.respond_to? method }
|
26
39
|
end
|
27
40
|
|
28
41
|
def self.validate_hash(value)
|
data/lib/lzws/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-lzws
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Aladjev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-10-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: codecov
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: minitar
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,20 +66,34 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '1.1'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rake-compiler
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
|
-
- - "
|
87
|
+
- - ">="
|
60
88
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
89
|
+
version: '0'
|
62
90
|
type: :development
|
63
91
|
prerelease: false
|
64
92
|
version_requirements: !ruby/object:Gem::Requirement
|
65
93
|
requirements:
|
66
|
-
- - "
|
94
|
+
- - ">="
|
67
95
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
96
|
+
version: '0'
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: rubocop
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,19 +123,19 @@ dependencies:
|
|
95
123
|
- !ruby/object:Gem::Version
|
96
124
|
version: '1.5'
|
97
125
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
126
|
+
name: simplecov
|
99
127
|
requirement: !ruby/object:Gem::Requirement
|
100
128
|
requirements:
|
101
|
-
- - "
|
129
|
+
- - ">="
|
102
130
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
131
|
+
version: '0'
|
104
132
|
type: :development
|
105
133
|
prerelease: false
|
106
134
|
version_requirements: !ruby/object:Gem::Requirement
|
107
135
|
requirements:
|
108
|
-
- - "
|
136
|
+
- - ">="
|
109
137
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
138
|
+
version: '0'
|
111
139
|
description:
|
112
140
|
email: aladjev.andrew@gmail.com
|
113
141
|
executables: []
|
@@ -165,14 +193,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
165
193
|
requirements:
|
166
194
|
- - ">="
|
167
195
|
- !ruby/object:Gem::Version
|
168
|
-
version: '
|
196
|
+
version: '2.5'
|
169
197
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
198
|
requirements:
|
171
199
|
- - ">="
|
172
200
|
- !ruby/object:Gem::Version
|
173
201
|
version: '0'
|
174
202
|
requirements: []
|
175
|
-
rubygems_version: 3.
|
203
|
+
rubygems_version: 3.1.4
|
176
204
|
signing_key:
|
177
205
|
specification_version: 4
|
178
206
|
summary: Ruby bindings for lzws library.
|