ruby-bzs 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ | [![AppVeyor test status](https://ci.appveyor.com/api/projects/status/github/andrew-aladev/ruby-bzs?branch=main&svg=true)](https://ci.appveyor.com/project/andrew-aladev/ruby-bzs/branch/main) | [![Jenkins test status](http://37.187.122.190:58182/buildStatus/icon?job=ruby-bzs)](http://37.187.122.190:58182/job/ruby-bzs) | [![Github Actions test status](https://github.com/andrew-aladev/ruby-bzs/workflows/test/badge.svg?branch=main)](https://github.com/andrew-aladev/ruby-bzs/actions) | [![Codecov](https://codecov.io/gh/andrew-aladev/ruby-bzs/branch/main/graph/badge.svg)](https://codecov.io/gh/andrew-aladev/ruby-bzs) | [![Gem](https://img.shields.io/gem/v/ruby-bzs.svg)](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
@@ -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
+ }
@@ -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