ruby-bzs 1.0.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 +7 -0
- data/AUTHORS +1 -0
- data/LICENSE +21 -0
- data/README.md +368 -0
- data/ext/bzs_ext/buffer.c +40 -0
- data/ext/bzs_ext/buffer.h +29 -0
- data/ext/bzs_ext/common.h +16 -0
- data/ext/bzs_ext/error.c +62 -0
- data/ext/bzs_ext/error.h +34 -0
- data/ext/bzs_ext/gvl.h +24 -0
- data/ext/bzs_ext/io.c +592 -0
- data/ext/bzs_ext/io.h +14 -0
- data/ext/bzs_ext/macro.h +13 -0
- data/ext/bzs_ext/main.c +27 -0
- data/ext/bzs_ext/option.c +98 -0
- data/ext/bzs_ext/option.h +62 -0
- data/ext/bzs_ext/stream/compressor.c +285 -0
- data/ext/bzs_ext/stream/compressor.h +33 -0
- data/ext/bzs_ext/stream/decompressor.c +221 -0
- data/ext/bzs_ext/stream/decompressor.h +31 -0
- data/ext/bzs_ext/string.c +340 -0
- data/ext/bzs_ext/string.h +14 -0
- data/ext/bzs_ext/utils.c +15 -0
- data/ext/bzs_ext/utils.h +13 -0
- data/ext/extconf.rb +94 -0
- data/lib/bzs/error.rb +26 -0
- data/lib/bzs/file.rb +25 -0
- data/lib/bzs/option.rb +101 -0
- data/lib/bzs/stream/raw/compressor.rb +22 -0
- data/lib/bzs/stream/raw/decompressor.rb +22 -0
- data/lib/bzs/stream/reader.rb +16 -0
- data/lib/bzs/stream/writer.rb +16 -0
- data/lib/bzs/string.rb +25 -0
- data/lib/bzs/validation.rb +14 -0
- data/lib/bzs/version.rb +6 -0
- data/lib/bzs.rb +8 -0
- metadata +289 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6d373c300f975749d0d050492c8f9d878fd20094e54570309dc9d1b7a55e71f7
|
4
|
+
data.tar.gz: f9c9ff5fd689912ee06405f3bf66ccdc7947f3b97b5bea470ba801ba3514caca
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b34eec93d12fd7c96463568f21f2d9b21f16f7d005b4f86694d30f637ff147ce6639924ed98ed8142d4991b3af65b61f7c5bfb338b66530dc333bf1fdfb4eabd
|
7
|
+
data.tar.gz: 1eb1a9bb30c926971fdd3aa61d0182f1b894ecc8ae6c0fedc32d0e29f1340e08f5cabec30c81edf6a5253d75271e05bba98e8cf0afd8d3e96d23c07f6a651b23
|
data/AUTHORS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Andrew Aladjev
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2022 AUTHORS
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,368 @@
|
|
1
|
+
# Ruby bindings for bzip2 library
|
2
|
+
|
3
|
+
| AppVeyor | Jenkins | Github actions | Codecov | Gem |
|
4
|
+
| :------: | :-----: | :------------: | :-----: | :--: |
|
5
|
+
| [](https://ci.appveyor.com/project/andrew-aladev/ruby-bzs/branch/main) | [](http://37.187.122.190:58182/job/ruby-bzs) | [](https://github.com/andrew-aladev/ruby-bzs/actions) | [](https://codecov.io/gh/andrew-aladev/ruby-bzs) | [](https://rubygems.org/gems/ruby-bzs) |
|
6
|
+
|
7
|
+
See [bzip2 library](https://gitlab.com/bzip2/bzip2).
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Operating systems: GNU/Linux, FreeBSD, OSX.
|
12
|
+
|
13
|
+
Dependencies: [bzip2](https://gitlab.com/bzip2/bzip2) 1.0.0+ version.
|
14
|
+
|
15
|
+
| Popular OS | Dependencies |
|
16
|
+
|------------|---------------------------|
|
17
|
+
| Ubuntu | `libbz2-dev` |
|
18
|
+
| CentOS | `bzip2-devel` |
|
19
|
+
| ArchLinux | `bzip2` |
|
20
|
+
| OSX | `bzip2` |
|
21
|
+
|
22
|
+
```sh
|
23
|
+
gem install ruby-bzs
|
24
|
+
```
|
25
|
+
|
26
|
+
You can build it from source.
|
27
|
+
|
28
|
+
```sh
|
29
|
+
rake gem
|
30
|
+
gem install pkg/ruby-bzs-*.gem
|
31
|
+
```
|
32
|
+
|
33
|
+
You can also use [overlay](https://github.com/andrew-aladev/overlay) for gentoo.
|
34
|
+
|
35
|
+
### Installation in macOS on Apple Silicon
|
36
|
+
|
37
|
+
On M1 Macs, Homebrew installs to /opt/homebrew, so you'll need to specify its
|
38
|
+
include and lib paths when building the native extension for bzip2.
|
39
|
+
|
40
|
+
```sh
|
41
|
+
brew install bzip2
|
42
|
+
gem install ruby-bzs -- --with-opt-include=/opt/homebrew/include --with-opt-lib=/opt/homebrew/lib
|
43
|
+
```
|
44
|
+
|
45
|
+
You can also configure Bundler to use those options when installing:
|
46
|
+
|
47
|
+
```sh
|
48
|
+
bundle config set build.ruby-bzs "--with-opt-include=/opt/homebrew/include --with-opt-lib=/opt/homebrew/lib"
|
49
|
+
```
|
50
|
+
|
51
|
+
## Usage
|
52
|
+
|
53
|
+
There are simple APIs: `String` and `File`. Also you can use generic streaming API: `Stream::Writer` and `Stream::Reader`.
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
require "bzs"
|
57
|
+
|
58
|
+
data = BZS::String.compress "sample string"
|
59
|
+
puts BZS::String.decompress(data)
|
60
|
+
|
61
|
+
BZS::File.compress "file.txt", "file.txt.bz2"
|
62
|
+
BZS::File.decompress "file.txt.bz2", "file.txt"
|
63
|
+
|
64
|
+
BZS::Stream::Writer.open("file.txt.bz2") { |writer| writer << "sample string" }
|
65
|
+
puts BZS::Stream::Reader.open("file.txt.bz2") { |reader| reader.read }
|
66
|
+
|
67
|
+
writer = BZS::Stream::Writer.new output_socket
|
68
|
+
begin
|
69
|
+
bytes_written = writer.write_nonblock "sample string"
|
70
|
+
# handle "bytes_written"
|
71
|
+
rescue IO::WaitWritable
|
72
|
+
# handle wait
|
73
|
+
ensure
|
74
|
+
writer.close
|
75
|
+
end
|
76
|
+
|
77
|
+
reader = BZS::Stream::Reader.new input_socket
|
78
|
+
begin
|
79
|
+
puts reader.read_nonblock(512)
|
80
|
+
rescue IO::WaitReadable
|
81
|
+
# handle wait
|
82
|
+
rescue ::EOFError
|
83
|
+
# handle eof
|
84
|
+
ensure
|
85
|
+
reader.close
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
You can create and read `tar.bz2` archives with [minitar](https://github.com/halostatue/minitar).
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
require "bzs"
|
93
|
+
require "minitar"
|
94
|
+
|
95
|
+
BZS::Stream::Writer.open "file.tar.bz2" do |writer|
|
96
|
+
Minitar::Writer.open writer do |tar|
|
97
|
+
tar.add_file_simple "file", :data => "sample string"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
BZS::Stream::Reader.open "file.tar.bz2" do |reader|
|
102
|
+
Minitar::Reader.open reader do |tar|
|
103
|
+
tar.each_entry do |entry|
|
104
|
+
puts entry.name
|
105
|
+
puts entry.read
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
```
|
110
|
+
|
111
|
+
All functionality (including streaming) can be used inside multiple threads with [parallel](https://github.com/grosser/parallel).
|
112
|
+
This code will provide heavy load for your CPU.
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
require "bzs"
|
116
|
+
require "parallel"
|
117
|
+
|
118
|
+
Parallel.each large_datas do |large_data|
|
119
|
+
BZS::String.compress large_data
|
120
|
+
end
|
121
|
+
```
|
122
|
+
|
123
|
+
# Docs
|
124
|
+
|
125
|
+
Please review [rdoc generated docs](https://andrew-aladev.github.io/ruby-bzs).
|
126
|
+
|
127
|
+
## Options
|
128
|
+
|
129
|
+
| Option | Values | Default | Description |
|
130
|
+
|---------------------------------|----------------|------------|-------------|
|
131
|
+
| `source_buffer_length` | 0 - inf | 0 (auto) | internal buffer length for source data |
|
132
|
+
| `destination_buffer_length` | 0 - inf | 0 (auto) | internal buffer length for description data |
|
133
|
+
| `gvl` | true/false | false | enables global VM lock where possible |
|
134
|
+
| `block_size` | 1 - 9 | 9 | block size to be used for compression |
|
135
|
+
| `work_factor` | 0 - 250 | 0 | controls threshold for switching from standard to fallback algorithm |
|
136
|
+
| `small` | true/false | true | enables alternative decompression algorithm with less memory |
|
137
|
+
| `quiet` | true/false | false | disables bzip2 library logging |
|
138
|
+
|
139
|
+
There are internal buffers for compressed and decompressed data.
|
140
|
+
For example you want to use 1 KB as `source_buffer_length` for compressor - please use 256 B as `destination_buffer_length`.
|
141
|
+
You want to use 256 B as `source_buffer_length` for decompressor - please use 1 KB as `destination_buffer_length`.
|
142
|
+
|
143
|
+
`gvl` is disabled by default, this mode allows running multiple compressors/decompressors in different threads simultaneously.
|
144
|
+
Please consider enabling `gvl` if you don't want to launch processors in separate threads.
|
145
|
+
If `gvl` is enabled ruby won't waste time on acquiring/releasing VM lock.
|
146
|
+
|
147
|
+
You can also read bzs docs for more info about options.
|
148
|
+
|
149
|
+
Possible compressor options:
|
150
|
+
```
|
151
|
+
:source_buffer_length
|
152
|
+
:destination_buffer_length
|
153
|
+
:gvl
|
154
|
+
:block_size
|
155
|
+
:work_factor
|
156
|
+
:quiet
|
157
|
+
```
|
158
|
+
|
159
|
+
Possible decompressor options:
|
160
|
+
```
|
161
|
+
:source_buffer_length
|
162
|
+
:destination_buffer_length
|
163
|
+
:gvl
|
164
|
+
:small
|
165
|
+
:quiet
|
166
|
+
```
|
167
|
+
|
168
|
+
Example:
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
require "bzs"
|
172
|
+
|
173
|
+
data = BZS::String.compress "sample string", :block_size => 1
|
174
|
+
puts BZS::String.decompress(data, :block_size => 1)
|
175
|
+
```
|
176
|
+
|
177
|
+
## String
|
178
|
+
|
179
|
+
String maintains destination buffer only, so it accepts `destination_buffer_length` option only.
|
180
|
+
|
181
|
+
```
|
182
|
+
::compress(source, options = {})
|
183
|
+
::decompress(source, options = {})
|
184
|
+
```
|
185
|
+
|
186
|
+
`source` is a source string.
|
187
|
+
|
188
|
+
## File
|
189
|
+
|
190
|
+
File maintains both source and destination buffers, it accepts both `source_buffer_length` and `destination_buffer_length` options.
|
191
|
+
|
192
|
+
```
|
193
|
+
::compress(source, destination, options = {})
|
194
|
+
::decompress(source, destination, options = {})
|
195
|
+
```
|
196
|
+
|
197
|
+
`source` and `destination` are file pathes.
|
198
|
+
|
199
|
+
## Stream::Writer
|
200
|
+
|
201
|
+
Its behaviour is similar to builtin [`Zlib::GzipWriter`](https://ruby-doc.org/stdlib/libdoc/zlib/rdoc/Zlib/GzipWriter.html).
|
202
|
+
|
203
|
+
Writer maintains destination buffer only, so it accepts `destination_buffer_length` option only.
|
204
|
+
|
205
|
+
```
|
206
|
+
::open(file_path, options = {}, :external_encoding => nil, :transcode_options => {}, &block)
|
207
|
+
```
|
208
|
+
|
209
|
+
Open file path and create stream writer associated with opened file.
|
210
|
+
Data will be transcoded to `:external_encoding` using `:transcode_options` before compressing.
|
211
|
+
|
212
|
+
It may be tricky to use both `:pledged_size` and `:transcode_options`. You have to provide size of transcoded input.
|
213
|
+
|
214
|
+
```
|
215
|
+
::new(destination_io, options = {}, :external_encoding => nil, :transcode_options => {})
|
216
|
+
```
|
217
|
+
|
218
|
+
Create stream writer associated with destination io.
|
219
|
+
Data will be transcoded to `:external_encoding` using `:transcode_options` before compressing.
|
220
|
+
|
221
|
+
It may be tricky to use both `:pledged_size` and `:transcode_options`. You have to provide size of transcoded input.
|
222
|
+
|
223
|
+
```
|
224
|
+
#set_encoding(external_encoding, nil, transcode_options)
|
225
|
+
```
|
226
|
+
|
227
|
+
Set another encodings, `nil` is just for compatibility with `IO`.
|
228
|
+
|
229
|
+
```
|
230
|
+
#io
|
231
|
+
#to_io
|
232
|
+
#stat
|
233
|
+
#external_encoding
|
234
|
+
#transcode_options
|
235
|
+
#pos
|
236
|
+
#tell
|
237
|
+
```
|
238
|
+
|
239
|
+
See [`IO`](https://ruby-doc.org/core/IO.html) docs.
|
240
|
+
|
241
|
+
```
|
242
|
+
#write(*objects)
|
243
|
+
#flush
|
244
|
+
#rewind
|
245
|
+
#close
|
246
|
+
#closed?
|
247
|
+
```
|
248
|
+
|
249
|
+
See [`Zlib::GzipWriter`](https://ruby-doc.org/stdlib/libdoc/zlib/rdoc/Zlib/GzipWriter.html) docs.
|
250
|
+
|
251
|
+
```
|
252
|
+
#write_nonblock(object, *options)
|
253
|
+
#flush_nonblock(*options)
|
254
|
+
#rewind_nonblock(*options)
|
255
|
+
#close_nonblock(*options)
|
256
|
+
```
|
257
|
+
|
258
|
+
Special asynchronous methods missing in `Zlib::GzipWriter`.
|
259
|
+
`rewind` wants to `close`, `close` wants to `write` something and `flush`, `flush` want to `write` something.
|
260
|
+
So it is possible to have asynchronous variants for these synchronous methods.
|
261
|
+
Behaviour is the same as `IO#write_nonblock` method.
|
262
|
+
|
263
|
+
```
|
264
|
+
#<<(object)
|
265
|
+
#print(*objects)
|
266
|
+
#printf(*args)
|
267
|
+
#putc(object, :encoding => 'ASCII-8BIT')
|
268
|
+
#puts(*objects)
|
269
|
+
```
|
270
|
+
|
271
|
+
Typical helpers, see [`Zlib::GzipWriter`](https://ruby-doc.org/stdlib/libdoc/zlib/rdoc/Zlib/GzipWriter.html) docs.
|
272
|
+
|
273
|
+
## Stream::Reader
|
274
|
+
|
275
|
+
Its behaviour is similar to builtin [`Zlib::GzipReader`](https://ruby-doc.org/stdlib/libdoc/zlib/rdoc/Zlib/GzipReader.html).
|
276
|
+
|
277
|
+
Reader maintains both source and destination buffers, it accepts both `source_buffer_length` and `destination_buffer_length` options.
|
278
|
+
|
279
|
+
```
|
280
|
+
::open(file_path, options = {}, :external_encoding => nil, :internal_encoding => nil, :transcode_options => {}, &block)
|
281
|
+
```
|
282
|
+
|
283
|
+
Open file path and create stream reader associated with opened file.
|
284
|
+
Data will be force encoded to `:external_encoding` and transcoded to `:internal_encoding` using `:transcode_options` after decompressing.
|
285
|
+
|
286
|
+
```
|
287
|
+
::new(source_io, options = {}, :external_encoding => nil, :internal_encoding => nil, :transcode_options => {})
|
288
|
+
```
|
289
|
+
|
290
|
+
Create stream reader associated with source io.
|
291
|
+
Data will be force encoded to `:external_encoding` and transcoded to `:internal_encoding` using `:transcode_options` after decompressing.
|
292
|
+
|
293
|
+
```
|
294
|
+
#set_encoding(external_encoding, internal_encoding, transcode_options)
|
295
|
+
```
|
296
|
+
|
297
|
+
Set another encodings.
|
298
|
+
|
299
|
+
```
|
300
|
+
#io
|
301
|
+
#to_io
|
302
|
+
#stat
|
303
|
+
#external_encoding
|
304
|
+
#internal_encoding
|
305
|
+
#transcode_options
|
306
|
+
#pos
|
307
|
+
#tell
|
308
|
+
```
|
309
|
+
|
310
|
+
See [`IO`](https://ruby-doc.org/core/IO.html) docs.
|
311
|
+
|
312
|
+
```
|
313
|
+
#read(bytes_to_read = nil, out_buffer = nil)
|
314
|
+
#eof?
|
315
|
+
#rewind
|
316
|
+
#close
|
317
|
+
#closed?
|
318
|
+
```
|
319
|
+
|
320
|
+
See [`Zlib::GzipReader`](https://ruby-doc.org/stdlib/libdoc/zlib/rdoc/Zlib/GzipReader.html) docs.
|
321
|
+
|
322
|
+
```
|
323
|
+
#readpartial(bytes_to_read = nil, out_buffer = nil)
|
324
|
+
#read_nonblock(bytes_to_read, out_buffer = nil, *options)
|
325
|
+
```
|
326
|
+
|
327
|
+
See [`IO`](https://ruby-doc.org/core/IO.html) docs.
|
328
|
+
|
329
|
+
```
|
330
|
+
#getbyte
|
331
|
+
#each_byte(&block)
|
332
|
+
#readbyte
|
333
|
+
#ungetbyte(byte)
|
334
|
+
|
335
|
+
#getc
|
336
|
+
#readchar
|
337
|
+
#each_char(&block)
|
338
|
+
#ungetc(char)
|
339
|
+
|
340
|
+
#lineno
|
341
|
+
#lineno=
|
342
|
+
#gets(separator = $OUTPUT_RECORD_SEPARATOR, limit = nil)
|
343
|
+
#readline
|
344
|
+
#readlines
|
345
|
+
#each(&block)
|
346
|
+
#each_line(&block)
|
347
|
+
#ungetline(line)
|
348
|
+
```
|
349
|
+
|
350
|
+
Typical helpers, see [`Zlib::GzipReader`](https://ruby-doc.org/stdlib/libdoc/zlib/rdoc/Zlib/GzipReader.html) docs.
|
351
|
+
|
352
|
+
## Thread safety
|
353
|
+
|
354
|
+
`:gvl` option is disabled by default, you can use bindings effectively in multiple threads.
|
355
|
+
Please be careful: bindings are not thread safe.
|
356
|
+
You should lock all shared data between threads.
|
357
|
+
|
358
|
+
For example: you should not use same compressor/decompressor inside multiple threads.
|
359
|
+
Please verify that you are using each processor inside single thread at the same time.
|
360
|
+
|
361
|
+
## CI
|
362
|
+
|
363
|
+
Please visit [scripts/test-images](scripts/test-images).
|
364
|
+
See universal test script [scripts/ci_test.sh](scripts/ci_test.sh) for CI.
|
365
|
+
|
366
|
+
## License
|
367
|
+
|
368
|
+
MIT license, see [LICENSE](LICENSE) and [AUTHORS](AUTHORS).
|
@@ -0,0 +1,40 @@
|
|
1
|
+
// Ruby bindings for bzip2 library.
|
2
|
+
// Copyright (c) 2022 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#include "bzs_ext/buffer.h"
|
5
|
+
|
6
|
+
VALUE bzs_ext_create_string_buffer(VALUE length)
|
7
|
+
{
|
8
|
+
return rb_str_new(NULL, NUM2SIZET(length));
|
9
|
+
}
|
10
|
+
|
11
|
+
VALUE bzs_ext_resize_string_buffer(VALUE buffer_args)
|
12
|
+
{
|
13
|
+
VALUE buffer = rb_ary_entry(buffer_args, 0);
|
14
|
+
VALUE length = rb_ary_entry(buffer_args, 1);
|
15
|
+
|
16
|
+
return rb_str_resize(buffer, NUM2SIZET(length));
|
17
|
+
}
|
18
|
+
|
19
|
+
void bzs_ext_buffer_exports(VALUE root_module)
|
20
|
+
{
|
21
|
+
VALUE module = rb_define_module_under(root_module, "Buffer");
|
22
|
+
|
23
|
+
rb_define_const(
|
24
|
+
module, "DEFAULT_SOURCE_BUFFER_LENGTH_FOR_COMPRESSOR", SIZET2NUM(BZS_DEFAULT_SOURCE_BUFFER_LENGTH_FOR_COMPRESSOR));
|
25
|
+
|
26
|
+
rb_define_const(
|
27
|
+
module,
|
28
|
+
"DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_COMPRESSOR",
|
29
|
+
SIZET2NUM(BZS_DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_COMPRESSOR));
|
30
|
+
|
31
|
+
rb_define_const(
|
32
|
+
module,
|
33
|
+
"DEFAULT_SOURCE_BUFFER_LENGTH_FOR_DECOMPRESSOR",
|
34
|
+
SIZET2NUM(BZS_DEFAULT_SOURCE_BUFFER_LENGTH_FOR_DECOMPRESSOR));
|
35
|
+
|
36
|
+
rb_define_const(
|
37
|
+
module,
|
38
|
+
"DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_DECOMPRESSOR",
|
39
|
+
SIZET2NUM(BZS_DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_DECOMPRESSOR));
|
40
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
// Ruby bindings for bzip2 library.
|
2
|
+
// Copyright (c) 2022 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#if !defined(BZS_EXT_BUFFER_H)
|
5
|
+
#define BZS_EXT_BUFFER_H
|
6
|
+
|
7
|
+
#include "ruby.h"
|
8
|
+
|
9
|
+
#define BZS_DEFAULT_SOURCE_BUFFER_LENGTH_FOR_COMPRESSOR (1 << 18) // 256 KB
|
10
|
+
#define BZS_DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_COMPRESSOR (1 << 16) // 64 KB
|
11
|
+
|
12
|
+
#define BZS_DEFAULT_SOURCE_BUFFER_LENGTH_FOR_DECOMPRESSOR (1 << 16) // 64 KB
|
13
|
+
#define BZS_DEFAULT_DESTINATION_BUFFER_LENGTH_FOR_DECOMPRESSOR (1 << 18) // 256 KB
|
14
|
+
|
15
|
+
VALUE bzs_ext_create_string_buffer(VALUE length);
|
16
|
+
|
17
|
+
#define BZS_EXT_CREATE_STRING_BUFFER(buffer, length, exception) \
|
18
|
+
VALUE buffer = rb_protect(bzs_ext_create_string_buffer, SIZET2NUM(length), &exception);
|
19
|
+
|
20
|
+
VALUE bzs_ext_resize_string_buffer(VALUE buffer_args);
|
21
|
+
|
22
|
+
#define BZS_EXT_RESIZE_STRING_BUFFER(buffer, length, exception) \
|
23
|
+
VALUE buffer_args = rb_ary_new_from_args(2, buffer, SIZET2NUM(length)); \
|
24
|
+
buffer = rb_protect(bzs_ext_resize_string_buffer, buffer_args, &exception); \
|
25
|
+
RB_GC_GUARD(buffer_args);
|
26
|
+
|
27
|
+
void bzs_ext_buffer_exports(VALUE root_module);
|
28
|
+
|
29
|
+
#endif // BZS_EXT_BUFFER_H
|
@@ -0,0 +1,16 @@
|
|
1
|
+
// Ruby bindings for bzip2 library.
|
2
|
+
// Copyright (c) 2022 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#if !defined(BZS_EXT_COMMON_H)
|
5
|
+
#define BZS_EXT_COMMON_H
|
6
|
+
|
7
|
+
#include <stdint.h>
|
8
|
+
|
9
|
+
#define BZS_EXT_MODULE_NAME "BZS"
|
10
|
+
|
11
|
+
typedef uint_fast8_t bzs_ext_result_t;
|
12
|
+
typedef int bzs_result_t;
|
13
|
+
|
14
|
+
typedef uint8_t bzs_ext_byte_t;
|
15
|
+
|
16
|
+
#endif // BZS_EXT_COMMON_H
|
data/ext/bzs_ext/error.c
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
// Ruby bindings for bzip2 library.
|
2
|
+
// Copyright (c) 2022 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#include <bzlib.h>
|
5
|
+
|
6
|
+
#include "bzs_ext/error.h"
|
7
|
+
|
8
|
+
bzs_ext_result_t bzs_ext_get_error(bzs_result_t error_code)
|
9
|
+
{
|
10
|
+
switch (error_code) {
|
11
|
+
case BZ_MEM_ERROR:
|
12
|
+
return BZS_EXT_ERROR_ALLOCATE_FAILED;
|
13
|
+
case BZ_PARAM_ERROR:
|
14
|
+
return BZS_EXT_ERROR_VALIDATE_FAILED;
|
15
|
+
case BZ_DATA_ERROR:
|
16
|
+
case BZ_DATA_ERROR_MAGIC:
|
17
|
+
case BZ_UNEXPECTED_EOF:
|
18
|
+
return BZS_EXT_ERROR_DECOMPRESSOR_CORRUPTED_SOURCE;
|
19
|
+
default:
|
20
|
+
return BZS_EXT_ERROR_UNEXPECTED;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
static inline NORETURN(void raise_error(const char* name, const char* description))
|
25
|
+
{
|
26
|
+
VALUE module = rb_define_module(BZS_EXT_MODULE_NAME);
|
27
|
+
VALUE error = rb_const_get(module, rb_intern(name));
|
28
|
+
rb_raise(error, "%s", description);
|
29
|
+
}
|
30
|
+
|
31
|
+
void bzs_ext_raise_error(bzs_ext_result_t ext_result)
|
32
|
+
{
|
33
|
+
switch (ext_result) {
|
34
|
+
case BZS_EXT_ERROR_ALLOCATE_FAILED:
|
35
|
+
raise_error("AllocateError", "allocate error");
|
36
|
+
case BZS_EXT_ERROR_VALIDATE_FAILED:
|
37
|
+
raise_error("ValidateError", "validate error");
|
38
|
+
|
39
|
+
case BZS_EXT_ERROR_USED_AFTER_CLOSE:
|
40
|
+
raise_error("UsedAfterCloseError", "used after closed");
|
41
|
+
case BZS_EXT_ERROR_NOT_ENOUGH_SOURCE_BUFFER:
|
42
|
+
raise_error("NotEnoughSourceBufferError", "not enough source buffer");
|
43
|
+
case BZS_EXT_ERROR_NOT_ENOUGH_DESTINATION_BUFFER:
|
44
|
+
raise_error("NotEnoughDestinationBufferError", "not enough destination buffer");
|
45
|
+
case BZS_EXT_ERROR_DECOMPRESSOR_CORRUPTED_SOURCE:
|
46
|
+
raise_error("DecompressorCorruptedSourceError", "decompressor received corrupted source");
|
47
|
+
|
48
|
+
case BZS_EXT_ERROR_ACCESS_IO:
|
49
|
+
raise_error("AccessIOError", "failed to access IO");
|
50
|
+
case BZS_EXT_ERROR_READ_IO:
|
51
|
+
raise_error("ReadIOError", "failed to read IO");
|
52
|
+
case BZS_EXT_ERROR_WRITE_IO:
|
53
|
+
raise_error("WriteIOError", "failed to write IO");
|
54
|
+
|
55
|
+
case BZS_EXT_ERROR_NOT_IMPLEMENTED:
|
56
|
+
raise_error("NotImplementedError", "not implemented error");
|
57
|
+
|
58
|
+
default:
|
59
|
+
// BZS_EXT_ERROR_UNEXPECTED
|
60
|
+
raise_error("UnexpectedError", "unexpected error");
|
61
|
+
}
|
62
|
+
}
|
data/ext/bzs_ext/error.h
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
// Ruby bindings for bzip2 library.
|
2
|
+
// Copyright (c) 2022 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#if !defined(BZS_EXT_ERROR_H)
|
5
|
+
#define BZS_EXT_ERROR_H
|
6
|
+
|
7
|
+
#include "bzs_ext/common.h"
|
8
|
+
#include "ruby.h"
|
9
|
+
|
10
|
+
// Results for errors listed in "lib/bzs/error" used in c extension.
|
11
|
+
|
12
|
+
enum
|
13
|
+
{
|
14
|
+
BZS_EXT_ERROR_ALLOCATE_FAILED = 1,
|
15
|
+
BZS_EXT_ERROR_VALIDATE_FAILED,
|
16
|
+
|
17
|
+
BZS_EXT_ERROR_USED_AFTER_CLOSE,
|
18
|
+
BZS_EXT_ERROR_NOT_ENOUGH_SOURCE_BUFFER,
|
19
|
+
BZS_EXT_ERROR_NOT_ENOUGH_DESTINATION_BUFFER,
|
20
|
+
BZS_EXT_ERROR_DECOMPRESSOR_CORRUPTED_SOURCE,
|
21
|
+
|
22
|
+
BZS_EXT_ERROR_ACCESS_IO,
|
23
|
+
BZS_EXT_ERROR_READ_IO,
|
24
|
+
BZS_EXT_ERROR_WRITE_IO,
|
25
|
+
|
26
|
+
BZS_EXT_ERROR_NOT_IMPLEMENTED,
|
27
|
+
BZS_EXT_ERROR_UNEXPECTED
|
28
|
+
};
|
29
|
+
|
30
|
+
bzs_ext_result_t bzs_ext_get_error(bzs_result_t error_code);
|
31
|
+
|
32
|
+
NORETURN(void bzs_ext_raise_error(bzs_ext_result_t ext_result));
|
33
|
+
|
34
|
+
#endif // BZS_EXT_ERROR_H
|
data/ext/bzs_ext/gvl.h
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
// Ruby bindings for bzip2 library.
|
2
|
+
// Copyright (c) 2022 AUTHORS, MIT License.
|
3
|
+
|
4
|
+
#if !defined(BZS_EXT_GVL_H)
|
5
|
+
#define BZS_EXT_GVL_H
|
6
|
+
|
7
|
+
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
8
|
+
|
9
|
+
#include "ruby/thread.h"
|
10
|
+
|
11
|
+
#define BZS_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 BZS_EXT_GVL_WRAP(_gvl, function, data) function((void*) data);
|
21
|
+
|
22
|
+
#endif // HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
23
|
+
|
24
|
+
#endif // BZS_EXT_GVL_H
|