ruby-lzws 1.1.4 → 1.3.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 +70 -69
- data/ext/extconf.rb +11 -2
- data/ext/lzws_ext/buffer.c +21 -7
- data/ext/lzws_ext/buffer.h +5 -5
- 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 +4 -0
- data/lib/lzws/option.rb +50 -27
- data/lib/lzws/stream/abstract.rb +1 -6
- data/lib/lzws/stream/raw/abstract.rb +4 -2
- data/lib/lzws/stream/raw/compressor.rb +2 -4
- data/lib/lzws/stream/raw/decompressor.rb +1 -3
- data/lib/lzws/stream/reader.rb +70 -51
- data/lib/lzws/stream/writer.rb +9 -4
- data/lib/lzws/stream/writer_helpers.rb +3 -2
- data/lib/lzws/validation.rb +1 -1
- data/lib/lzws/version.rb +1 -1
- metadata +21 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46de1059ebc7e81a3c93869a70801e20571e99631a0a9a8acc0cad9b06e9c21f
|
4
|
+
data.tar.gz: c4d1d3859bd374404b496b9ae393f34b08b49bf94655e420862545fd8949cc12
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88f2f3627fb6f98fffc6c1289301a9362c6ab22edc7de42732a90c85b1065bd2e3ee73547dbab0ee1c40d14c3490053f43d36d7b67abb25aa6ec2e938211e95e
|
7
|
+
data.tar.gz: e6b97fea5d39bd2ee8b4e9ad43d16453f0640536c86dd9e0d425443c3a48a5bb3bf99c5bb452e4065f3c21489572a4bf05a9809b1eccfd7ef39773a1eea0d05d
|
data/README.md
CHANGED
@@ -1,14 +1,14 @@
|
|
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) | [](https://rubygems.org/gems/ruby-lzws) |
|
6
6
|
|
7
7
|
See [lzws library](https://github.com/andrew-aladev/lzws).
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
11
|
-
Please install lzws library first, use latest 1.
|
11
|
+
Please install lzws library first, use latest 1.4.0+ version.
|
12
12
|
|
13
13
|
```sh
|
14
14
|
gem install ruby-lzws
|
@@ -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,10 +38,31 @@ 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
|
-
You can create and read `tar.Z` archives with
|
42
|
-
LZWS is compatible with UNIX compress (with default options).
|
64
|
+
You can create and read `tar.Z` archives with [minitar](https://github.com/halostatue/minitar) for example.
|
65
|
+
LZWS is compatible with [UNIX compress](https://en.wikipedia.org/wiki/Compress) (with default options).
|
43
66
|
|
44
67
|
```ruby
|
45
68
|
require "lzws"
|
@@ -61,66 +84,51 @@ LZWS::Stream::Reader.open "file.tar.Z" do |reader|
|
|
61
84
|
end
|
62
85
|
```
|
63
86
|
|
64
|
-
|
65
|
-
|
66
|
-
Each API supports several options:
|
67
|
-
|
68
|
-
```
|
69
|
-
:source_buffer_length
|
70
|
-
:destination_buffer_length
|
71
|
-
```
|
72
|
-
|
73
|
-
There are internal buffers for compressed and decompressed data.
|
74
|
-
For example you want to use 1 KB as source buffer length for compressor - please use 256 B as destination buffer length.
|
75
|
-
You want to use 256 B as source buffer length for decompressor - please use 1 KB as destination buffer length.
|
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.
|
87
|
+
You can also use `Content-Encoding: compress` with [sinatra](http://sinatrarb.com):
|
80
88
|
|
81
|
-
```
|
82
|
-
|
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.
|
89
|
+
```ruby
|
90
|
+
require "lzws"
|
91
|
+
require "sinatra"
|
98
92
|
|
99
|
-
|
100
|
-
|
93
|
+
get "/" do
|
94
|
+
headers["Content-Encoding"] = "compress"
|
95
|
+
LZWS::String.compress "TOBEORNOTTOBEORTOBEORNOT"
|
96
|
+
end
|
101
97
|
```
|
102
98
|
|
103
|
-
|
99
|
+
## Options
|
104
100
|
|
105
|
-
|
106
|
-
|
107
|
-
|
101
|
+
| Option | Values | Default | Description |
|
102
|
+
|-----------------------------|------------|----------|-------------|
|
103
|
+
| `source_buffer_length` | 0, 2 - inf | 0 (auto) | internal buffer length for source data |
|
104
|
+
| `destination_buffer_length` | 0, 2 - inf | 0 (auto) | internal buffer length for description data |
|
105
|
+
| `gvl` | true/false | false | enables global VM lock where possible |
|
106
|
+
| `max_code_bit_length` | 9 - 16 | 16 | max code bit length |
|
107
|
+
| `block_mode` | true/false | true | enables block mode |
|
108
|
+
| `without_magic_header` | true/false | false | disables magic header |
|
109
|
+
| `msb` | true/false | false | enables most significant bit mode |
|
110
|
+
| `unaligned_bit_groups` | true/false | false | enables unaligned bit groups |
|
111
|
+
| `quiet` | true/false | false | disables lzws library logging |
|
108
112
|
|
109
|
-
|
113
|
+
There are internal buffers for compressed and decompressed data.
|
114
|
+
For example you want to use 1 KB as `source_buffer_length` for compressor - please use 256 B as `destination_buffer_length`.
|
115
|
+
You want to use 256 B as `source_buffer_length` for decompressor - please use 1 KB as `destination_buffer_length`.
|
110
116
|
|
111
|
-
|
112
|
-
|
113
|
-
|
117
|
+
`gvl` is disabled by default, this mode allows running multiple compressors/decompressors in different threads simultaneously.
|
118
|
+
Please consider enabling `gvl` if you don't want to launch processors in separate threads.
|
119
|
+
If `gvl` is enabled ruby won't waste time on acquiring/releasing VM lock.
|
114
120
|
|
115
|
-
|
116
|
-
Disables lzws library logging.
|
121
|
+
You can also read lzws docs for more info about options.
|
117
122
|
|
118
|
-
|
123
|
+
| Option | Related constants |
|
124
|
+
|-----------------------|-------------------|
|
125
|
+
| `max_code_bit_length` | `LZWS::Option::LOWEST_MAX_CODE_BIT_LENGTH` = 9, `LZWS::Option::BIGGEST_MAX_CODE_BIT_LENGTH` = 16 |
|
119
126
|
|
120
127
|
Possible compressor options:
|
121
128
|
```
|
122
129
|
:source_buffer_length
|
123
130
|
:destination_buffer_length
|
131
|
+
:gvl
|
124
132
|
:max_code_bit_length
|
125
133
|
:block_mode
|
126
134
|
:without_magic_header
|
@@ -133,6 +141,7 @@ Possible decompressor options:
|
|
133
141
|
```
|
134
142
|
:source_buffer_length
|
135
143
|
:destination_buffer_length
|
144
|
+
:gvl
|
136
145
|
:without_magic_header
|
137
146
|
:msb
|
138
147
|
:unaligned_bit_groups
|
@@ -148,18 +157,6 @@ data = LZWS::String.compress "TOBEORNOTTOBEORTOBEORNOT", :msb => true
|
|
148
157
|
puts LZWS::String.decompress(data, :msb => true)
|
149
158
|
```
|
150
159
|
|
151
|
-
Default options are compatible with UNIX compress (`Content-Encoding: compress`):
|
152
|
-
|
153
|
-
```ruby
|
154
|
-
require "lzws"
|
155
|
-
require "sinatra"
|
156
|
-
|
157
|
-
get "/" do
|
158
|
-
headers["Content-Encoding"] = "compress"
|
159
|
-
LZWS::String.compress "TOBEORNOTTOBEORTOBEORNOT"
|
160
|
-
end
|
161
|
-
```
|
162
|
-
|
163
160
|
Please read more about compatibility in lzws docs.
|
164
161
|
|
165
162
|
## String
|
@@ -333,14 +330,18 @@ See [`IO`](https://ruby-doc.org/core-2.7.0/IO.html) docs.
|
|
333
330
|
|
334
331
|
Typical helpers, see [`Zlib::GzipReader`](https://ruby-doc.org/stdlib-2.7.0/libdoc/zlib/rdoc/Zlib/GzipReader.html) docs.
|
335
332
|
|
333
|
+
## Thread safety
|
334
|
+
|
335
|
+
`:gvl` option is disabled by default, you can use bindings effectively in multiple threads.
|
336
|
+
Please be careful: bindings are not thread safe.
|
337
|
+
You should lock all shared data between threads.
|
338
|
+
|
336
339
|
## CI
|
337
340
|
|
338
|
-
See universal test script [scripts/ci_test.sh](scripts/ci_test.sh) for CI.
|
339
341
|
Please visit [scripts/test-images](scripts/test-images).
|
340
|
-
|
341
|
-
|
342
|
-
Cirrus CI uses `x86_64-pc-linux-gnu` image, Circle CI - `x86_64-gentoo-linux-musl` image.
|
342
|
+
See universal test script [scripts/ci_test.sh](scripts/ci_test.sh) for CI.
|
343
|
+
You can run this script using many native and cross images.
|
343
344
|
|
344
345
|
## License
|
345
346
|
|
346
|
-
MIT license, see LICENSE and AUTHORS.
|
347
|
+
MIT license, see [LICENSE](LICENSE) and [AUTHORS](AUTHORS).
|
data/ext/extconf.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
|
4
4
|
require "mkmf"
|
5
5
|
|
6
|
+
have_func "rb_thread_call_without_gvl", "ruby/thread.h"
|
7
|
+
|
6
8
|
def require_header(name, types = [])
|
7
9
|
abort "Can't find #{name} header" unless find_header name
|
8
10
|
|
@@ -13,10 +15,10 @@ end
|
|
13
15
|
|
14
16
|
require_header "lzws/buffer.h"
|
15
17
|
require_header "lzws/common.h", %w[lzws_result_t]
|
16
|
-
require_header "lzws/compressor/common.h"
|
18
|
+
require_header "lzws/compressor/common.h", %w[lzws_compressor_options_t]
|
17
19
|
require_header "lzws/compressor/main.h"
|
18
20
|
require_header "lzws/compressor/state.h", %w[lzws_compressor_state_t]
|
19
|
-
require_header "lzws/decompressor/common.h"
|
21
|
+
require_header "lzws/decompressor/common.h", %w[lzws_decompressor_options_t]
|
20
22
|
require_header "lzws/decompressor/main.h"
|
21
23
|
require_header "lzws/decompressor/state.h", %w[lzws_decompressor_state_t]
|
22
24
|
require_header "lzws/file.h"
|
@@ -66,6 +68,13 @@ $srcs = %w[
|
|
66
68
|
.map { |name| "src/#{extension_name}/#{name}.c" }
|
67
69
|
.freeze
|
68
70
|
|
71
|
+
# Removing library duplicates.
|
72
|
+
$libs = $libs.split(%r{\s})
|
73
|
+
.reject(&:empty?)
|
74
|
+
.sort
|
75
|
+
.uniq
|
76
|
+
.join " "
|
77
|
+
|
69
78
|
if ENV["CI"] || ENV["COVERAGE"]
|
70
79
|
$CFLAGS << " --coverage"
|
71
80
|
$LDFLAGS << " --coverage"
|
data/ext/lzws_ext/buffer.c
CHANGED
@@ -12,10 +12,11 @@ VALUE lzws_ext_create_string_buffer(VALUE length)
|
|
12
12
|
return rb_str_new(NULL, NUM2SIZET(length));
|
13
13
|
}
|
14
14
|
|
15
|
-
VALUE lzws_ext_resize_string_buffer(VALUE
|
15
|
+
VALUE lzws_ext_resize_string_buffer(VALUE buffer_args)
|
16
16
|
{
|
17
|
-
VALUE buffer = rb_ary_entry(
|
18
|
-
VALUE length = rb_ary_entry(
|
17
|
+
VALUE buffer = rb_ary_entry(buffer_args, 0);
|
18
|
+
VALUE length = rb_ary_entry(buffer_args, 1);
|
19
|
+
|
19
20
|
return rb_str_resize(buffer, NUM2SIZET(length));
|
20
21
|
}
|
21
22
|
|
@@ -23,8 +24,21 @@ void lzws_ext_buffer_exports(VALUE root_module)
|
|
23
24
|
{
|
24
25
|
VALUE module = rb_define_module_under(root_module, "Buffer");
|
25
26
|
|
26
|
-
rb_define_const(
|
27
|
-
|
28
|
-
|
29
|
-
rb_define_const(
|
27
|
+
rb_define_const(
|
28
|
+
module, "DEFAULT_SOURCE_BUFFER_LENGTH_FOR_COMPRESSOR", SIZET2NUM(LZWS_DEFAULT_SOURCE_BUFFER_LENGTH_FOR_COMPRESSOR));
|
29
|
+
|
30
|
+
rb_define_const(
|
31
|
+
module,
|
32
|
+
"DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_COMPRESSOR",
|
33
|
+
SIZET2NUM(LZWS_DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_COMPRESSOR));
|
34
|
+
|
35
|
+
rb_define_const(
|
36
|
+
module,
|
37
|
+
"DEFAULT_SOURCE_BUFFER_LENGTH_FOR_DECOMPRESSOR",
|
38
|
+
SIZET2NUM(LZWS_DEFAULT_SOURCE_BUFFER_LENGTH_FOR_DECOMPRESSOR));
|
39
|
+
|
40
|
+
rb_define_const(
|
41
|
+
module,
|
42
|
+
"DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_DECOMPRESSOR",
|
43
|
+
SIZET2NUM(LZWS_DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_DECOMPRESSOR));
|
30
44
|
}
|
data/ext/lzws_ext/buffer.h
CHANGED
@@ -11,12 +11,12 @@ VALUE lzws_ext_create_string_buffer(VALUE length);
|
|
11
11
|
#define LZWS_EXT_CREATE_STRING_BUFFER(buffer, length, exception) \
|
12
12
|
VALUE buffer = rb_protect(lzws_ext_create_string_buffer, SIZET2NUM(length), &exception);
|
13
13
|
|
14
|
-
VALUE lzws_ext_resize_string_buffer(VALUE
|
14
|
+
VALUE lzws_ext_resize_string_buffer(VALUE buffer_args);
|
15
15
|
|
16
|
-
#define LZWS_EXT_RESIZE_STRING_BUFFER(buffer, length, exception)
|
17
|
-
VALUE
|
18
|
-
buffer
|
19
|
-
RB_GC_GUARD(
|
16
|
+
#define LZWS_EXT_RESIZE_STRING_BUFFER(buffer, length, exception) \
|
17
|
+
VALUE buffer_args = rb_ary_new_from_args(2, buffer, SIZET2NUM(length)); \
|
18
|
+
buffer = rb_protect(lzws_ext_resize_string_buffer, buffer_args, &exception); \
|
19
|
+
RB_GC_GUARD(buffer_args);
|
20
20
|
|
21
21
|
void lzws_ext_buffer_exports(VALUE root_module);
|
22
22
|
|
data/ext/lzws_ext/error.h
CHANGED
data/ext/lzws_ext/gvl.h
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
// Ruby bindings for lzws library.
|
2
|
+
// Copyright (c) 2019 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#if !defined(LZWS_EXT_GVL_H)
|
5
|
+
#define LZWS_EXT_GVL_H
|
6
|
+
|
7
|
+
#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
8
|
+
|
9
|
+
#include "ruby/thread.h"
|
10
|
+
|
11
|
+
#define LZWS_EXT_GVL_WRAP(gvl, function, data) \
|
12
|
+
if (gvl) { \
|
13
|
+
function((void*) data); \
|
14
|
+
} else { \
|
15
|
+
rb_thread_call_without_gvl(function, (void*) data, RUBY_UBF_IO, NULL); \
|
16
|
+
}
|
17
|
+
|
18
|
+
#else
|
19
|
+
|
20
|
+
#define LZWS_EXT_GVL_WRAP(_gvl, function, data) function((void*) data);
|
21
|
+
|
22
|
+
#endif
|
23
|
+
|
24
|
+
#endif // LZWS_EXT_GVL_H
|
data/ext/lzws_ext/io.c
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
// Ruby bindings for lzws library.
|
2
2
|
// Copyright (c) 2019 AUTHORS, MIT License.
|
3
3
|
|
4
|
-
#include "
|
4
|
+
#include "lzws_ext/io.h"
|
5
5
|
|
6
|
-
#include <lzws/common.h>
|
7
6
|
#include <lzws/file.h>
|
8
7
|
|
9
8
|
#include "lzws_ext/error.h"
|
10
|
-
#include "lzws_ext/
|
9
|
+
#include "lzws_ext/gvl.h"
|
11
10
|
#include "lzws_ext/macro.h"
|
12
11
|
#include "lzws_ext/option.h"
|
13
12
|
#include "ruby.h"
|
13
|
+
#include "ruby/io.h"
|
14
|
+
|
15
|
+
// -- utils --
|
14
16
|
|
15
17
|
#define GET_FILE(target) \
|
16
18
|
Check_Type(target, T_FILE); \
|
@@ -48,22 +50,52 @@ static inline lzws_ext_result_t get_file_error(lzws_result_t result)
|
|
48
50
|
}
|
49
51
|
}
|
50
52
|
|
53
|
+
// -- compress --
|
54
|
+
|
55
|
+
typedef struct
|
56
|
+
{
|
57
|
+
FILE* source_file;
|
58
|
+
size_t source_buffer_length;
|
59
|
+
FILE* destination_file;
|
60
|
+
size_t destination_buffer_length;
|
61
|
+
lzws_compressor_options_t* compressor_options_ptr;
|
62
|
+
lzws_result_t result;
|
63
|
+
} compress_args_t;
|
64
|
+
|
65
|
+
static inline void* compress_wrapper(void* data)
|
66
|
+
{
|
67
|
+
compress_args_t* args = data;
|
68
|
+
|
69
|
+
args->result = lzws_compress_file(
|
70
|
+
args->source_file,
|
71
|
+
args->source_buffer_length,
|
72
|
+
args->destination_file,
|
73
|
+
args->destination_buffer_length,
|
74
|
+
args->compressor_options_ptr);
|
75
|
+
|
76
|
+
return NULL;
|
77
|
+
}
|
78
|
+
|
51
79
|
VALUE lzws_ext_compress_io(VALUE LZWS_EXT_UNUSED(self), VALUE source, VALUE destination, VALUE options)
|
52
80
|
{
|
53
81
|
GET_FILE(source);
|
54
82
|
GET_FILE(destination);
|
55
83
|
Check_Type(options, T_HASH);
|
84
|
+
LZWS_EXT_GET_SIZE_OPTION(options, source_buffer_length);
|
85
|
+
LZWS_EXT_GET_SIZE_OPTION(options, destination_buffer_length);
|
86
|
+
LZWS_EXT_GET_BOOL_OPTION(options, gvl);
|
56
87
|
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);
|
59
88
|
|
60
|
-
|
61
|
-
source_file
|
62
|
-
|
63
|
-
|
89
|
+
compress_args_t args = {
|
90
|
+
.source_file = source_file,
|
91
|
+
.source_buffer_length = source_buffer_length,
|
92
|
+
.destination_file = destination_file,
|
93
|
+
.destination_buffer_length = destination_buffer_length,
|
94
|
+
.compressor_options_ptr = &compressor_options};
|
64
95
|
|
65
|
-
|
66
|
-
|
96
|
+
LZWS_EXT_GVL_WRAP(gvl, compress_wrapper, &args);
|
97
|
+
if (args.result != 0) {
|
98
|
+
lzws_ext_raise_error(get_file_error(args.result));
|
67
99
|
}
|
68
100
|
|
69
101
|
// Ruby itself won't flush stdio file before closing fd, flush is required.
|
@@ -72,22 +104,52 @@ VALUE lzws_ext_compress_io(VALUE LZWS_EXT_UNUSED(self), VALUE source, VALUE dest
|
|
72
104
|
return Qnil;
|
73
105
|
}
|
74
106
|
|
107
|
+
// -- decompress --
|
108
|
+
|
109
|
+
typedef struct
|
110
|
+
{
|
111
|
+
FILE* source_file;
|
112
|
+
size_t source_buffer_length;
|
113
|
+
FILE* destination_file;
|
114
|
+
size_t destination_buffer_length;
|
115
|
+
lzws_decompressor_options_t* decompressor_options_ptr;
|
116
|
+
lzws_result_t result;
|
117
|
+
} decompress_args_t;
|
118
|
+
|
119
|
+
static inline void* decompress_wrapper(void* data)
|
120
|
+
{
|
121
|
+
decompress_args_t* args = data;
|
122
|
+
|
123
|
+
args->result = lzws_decompress_file(
|
124
|
+
args->source_file,
|
125
|
+
args->source_buffer_length,
|
126
|
+
args->destination_file,
|
127
|
+
args->destination_buffer_length,
|
128
|
+
args->decompressor_options_ptr);
|
129
|
+
|
130
|
+
return NULL;
|
131
|
+
}
|
132
|
+
|
75
133
|
VALUE lzws_ext_decompress_io(VALUE LZWS_EXT_UNUSED(self), VALUE source, VALUE destination, VALUE options)
|
76
134
|
{
|
77
135
|
GET_FILE(source);
|
78
136
|
GET_FILE(destination);
|
79
137
|
Check_Type(options, T_HASH);
|
138
|
+
LZWS_EXT_GET_SIZE_OPTION(options, source_buffer_length);
|
139
|
+
LZWS_EXT_GET_SIZE_OPTION(options, destination_buffer_length);
|
140
|
+
LZWS_EXT_GET_BOOL_OPTION(options, gvl);
|
80
141
|
LZWS_EXT_GET_DECOMPRESSOR_OPTIONS(options);
|
81
|
-
LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, source_buffer_length);
|
82
|
-
LZWS_EXT_GET_BUFFER_LENGTH_OPTION(options, destination_buffer_length);
|
83
142
|
|
84
|
-
|
85
|
-
source_file
|
86
|
-
|
87
|
-
|
143
|
+
decompress_args_t args = {
|
144
|
+
.source_file = source_file,
|
145
|
+
.source_buffer_length = source_buffer_length,
|
146
|
+
.destination_file = destination_file,
|
147
|
+
.destination_buffer_length = destination_buffer_length,
|
148
|
+
.decompressor_options_ptr = &decompressor_options};
|
88
149
|
|
89
|
-
|
90
|
-
|
150
|
+
LZWS_EXT_GVL_WRAP(gvl, decompress_wrapper, &args);
|
151
|
+
if (args.result != 0) {
|
152
|
+
lzws_ext_raise_error(get_file_error(args.result));
|
91
153
|
}
|
92
154
|
|
93
155
|
// Ruby itself won't flush stdio file before closing fd, flush is required.
|
@@ -96,6 +158,8 @@ VALUE lzws_ext_decompress_io(VALUE LZWS_EXT_UNUSED(self), VALUE source, VALUE de
|
|
96
158
|
return Qnil;
|
97
159
|
}
|
98
160
|
|
161
|
+
// -- exports --
|
162
|
+
|
99
163
|
void lzws_ext_io_exports(VALUE root_module)
|
100
164
|
{
|
101
165
|
rb_define_module_function(root_module, "_native_compress_io", RUBY_METHOD_FUNC(lzws_ext_compress_io), 3);
|