ruby-brs 1.3.0 → 1.3.3
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/AUTHORS +1 -0
- data/README.md +36 -14
- data/ext/brs_ext/gvl.h +2 -2
- data/ext/brs_ext/macro.h +1 -1
- data/lib/brs/error.rb +9 -4
- data/lib/brs/file.rb +17 -27
- data/lib/brs/option.rb +36 -0
- data/lib/brs/stream/raw/compressor.rb +12 -76
- data/lib/brs/stream/raw/decompressor.rb +7 -51
- data/lib/brs/stream/reader.rb +6 -176
- data/lib/brs/stream/writer.rb +6 -140
- data/lib/brs/string.rb +18 -9
- data/lib/brs/validation.rb +4 -45
- data/lib/brs/version.rb +1 -1
- metadata +43 -19
- data/lib/brs/stream/abstract.rb +0 -152
- data/lib/brs/stream/delegates.rb +0 -36
- data/lib/brs/stream/raw/abstract.rb +0 -59
- data/lib/brs/stream/reader_helpers.rb +0 -194
- data/lib/brs/stream/stat.rb +0 -78
- data/lib/brs/stream/writer_helpers.rb +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6acc107214aae47c21bea586f3281f3b16ad01e03a5f13990667603b625ebd3
|
4
|
+
data.tar.gz: 7cf0a0aacb4bb52457f009a1ceffc6a6c9b6fb80bdf289b86efaabeed261de3f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 703c614f49408c3aeb4203aa6f1a5f6abd341d3e0f88275d6c88d52e66e0f1a2f49e00908675e9a4bebcefd0851b33b3f7a115b7e3577d2718acb90d6d2ae551
|
7
|
+
data.tar.gz: d4984cf3b656386c7ab0dfecaebed8be95e5b2b0a24c48a21413e4908fd50d9862883baf887dddb980378f9604346b3da2bc5a9b09c0b430882247ec72a22a87
|
data/AUTHORS
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,23 @@
|
|
1
1
|
# Ruby bindings for brotli library
|
2
2
|
|
3
|
-
| AppVeyor |
|
4
|
-
| :------: |
|
5
|
-
| [](https://ci.appveyor.com/project/andrew-aladev/ruby-brs/branch/master) | [](https://ci.appveyor.com/project/andrew-aladev/ruby-brs/branch/master) | [](http://37.187.122.190:58182/job/ruby-brs) | [](https://github.com/andrew-aladev/ruby-brs/actions) | [](https://codecov.io/gh/andrew-aladev/ruby-brs) | [](https://rubygems.org/gems/ruby-brs) |
|
6
6
|
|
7
7
|
See [brotli library](https://github.com/google/brotli).
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
11
|
-
|
11
|
+
Operating systems: GNU/Linux, FreeBSD, OSX.
|
12
|
+
|
13
|
+
Dependencies: [brotli](https://github.com/google/brotli) 1.0.0+ version.
|
14
|
+
|
15
|
+
| Popular OS | Dependencies |
|
16
|
+
|------------|---------------------------|
|
17
|
+
| Ubuntu | `libbrotli-dev` |
|
18
|
+
| CentOS | `brotli-devel` |
|
19
|
+
| ArchLinux | `brotli` |
|
20
|
+
| OSX | `brotli` |
|
12
21
|
|
13
22
|
```sh
|
14
23
|
gem install ruby-brs
|
@@ -23,6 +32,22 @@ gem install pkg/ruby-brs-*.gem
|
|
23
32
|
|
24
33
|
You can also use [overlay](https://github.com/andrew-aladev/overlay) for gentoo.
|
25
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 brotli.
|
39
|
+
|
40
|
+
```sh
|
41
|
+
brew install brotli
|
42
|
+
gem install ruby-brs -- --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-brs "--with-opt-include=/opt/homebrew/include --with-opt-lib=/opt/homebrew/lib"
|
49
|
+
```
|
50
|
+
|
26
51
|
## Usage
|
27
52
|
|
28
53
|
There are simple APIs: `String` and `File`. Also you can use generic streaming API: `Stream::Writer` and `Stream::Reader`.
|
@@ -107,6 +132,10 @@ Parallel.each large_datas do |large_data|
|
|
107
132
|
end
|
108
133
|
```
|
109
134
|
|
135
|
+
# Docs
|
136
|
+
|
137
|
+
Please review [rdoc generated docs](https://andrew-aladev.github.io/ruby-brs).
|
138
|
+
|
110
139
|
## Options
|
111
140
|
|
112
141
|
| Option | Values | Default | Description |
|
@@ -118,8 +147,8 @@ end
|
|
118
147
|
| `quality` | 0 - 11 | 11 | compression level |
|
119
148
|
| `lgwin` | 10 - 24 | 22 | compressor window size |
|
120
149
|
| `lgblock` | 16 - 24 | nil (auto) | compressor input block size |
|
121
|
-
| `npostfix` | 0 - 3 | nil (auto) |
|
122
|
-
| `ndirect` | 0 - 120 | nil (auto) |
|
150
|
+
| `npostfix` | 0 - 3 | nil (auto) | recommended number of postfix bits |
|
151
|
+
| `ndirect` | 0 - 120 | nil (auto) | recommended number of direct distance codes (step 1 << npostfix, max 15 << npostfix) |
|
123
152
|
| `disable_literal_context_modeling` | true/false | false | disables literal context modeling format |
|
124
153
|
| `disable_ring_buffer_reallocation` | true/false | false | disables ring buffer reallocation |
|
125
154
|
| `size_hint` | 0 - inf | 0 (auto) | size of input (if known) |
|
@@ -266,14 +295,11 @@ Special asynchronous methods missing in `Zlib::GzipWriter`.
|
|
266
295
|
So it is possible to have asynchronous variants for these synchronous methods.
|
267
296
|
Behaviour is the same as `IO#write_nonblock` method.
|
268
297
|
|
269
|
-
All nonblock operations for file will raise `EBADF` error on Windows.
|
270
|
-
Setting file into nonblocking mode is [not available on Windows](https://github.com/ruby/ruby/blob/master/win32/win32.c#L4388).
|
271
|
-
|
272
298
|
```
|
273
299
|
#<<(object)
|
274
300
|
#print(*objects)
|
275
301
|
#printf(*args)
|
276
|
-
#putc(object, encoding
|
302
|
+
#putc(object, :encoding => 'ASCII-8BIT')
|
277
303
|
#puts(*objects)
|
278
304
|
```
|
279
305
|
|
@@ -367,10 +393,6 @@ You should lock all shared data between threads.
|
|
367
393
|
For example: you should not use same compressor/decompressor inside multiple threads.
|
368
394
|
Please verify that you are using each processor inside single thread at the same time.
|
369
395
|
|
370
|
-
## Operating systems
|
371
|
-
|
372
|
-
GNU/Linux, FreeBSD, OSX, Windows (MinGW).
|
373
|
-
|
374
396
|
## CI
|
375
397
|
|
376
398
|
Please visit [scripts/test-images](scripts/test-images).
|
data/ext/brs_ext/gvl.h
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
#if !defined(BRS_EXT_GVL_H)
|
5
5
|
#define BRS_EXT_GVL_H
|
6
6
|
|
7
|
-
#
|
7
|
+
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
8
8
|
|
9
9
|
#include "ruby/thread.h"
|
10
10
|
|
@@ -19,6 +19,6 @@
|
|
19
19
|
|
20
20
|
#define BRS_EXT_GVL_WRAP(_gvl, function, data) function((void*) data);
|
21
21
|
|
22
|
-
#endif
|
22
|
+
#endif // HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
23
23
|
|
24
24
|
#endif // BRS_EXT_GVL_H
|
data/ext/brs_ext/macro.h
CHANGED
data/lib/brs/error.rb
CHANGED
@@ -1,21 +1,26 @@
|
|
1
1
|
# Ruby bindings for brotli library.
|
2
2
|
# Copyright (c) 2019 AUTHORS, MIT License.
|
3
3
|
|
4
|
+
require "adsp"
|
5
|
+
|
4
6
|
module BRS
|
5
7
|
class BaseError < ::StandardError; end
|
6
8
|
|
7
9
|
class AllocateError < BaseError; end
|
8
|
-
class ValidateError < BaseError; end
|
9
10
|
|
10
|
-
class UsedAfterCloseError < BaseError; end
|
11
11
|
class NotEnoughSourceBufferError < BaseError; end
|
12
12
|
class NotEnoughDestinationBufferError < BaseError; end
|
13
|
-
class NotEnoughDestinationError < BaseError; end
|
14
13
|
class DecompressorCorruptedSourceError < BaseError; end
|
15
14
|
|
16
15
|
class AccessIOError < BaseError; end
|
17
16
|
class ReadIOError < BaseError; end
|
18
17
|
class WriteIOError < BaseError; end
|
19
18
|
|
20
|
-
|
19
|
+
ValidateError = ADSP::ValidateError
|
20
|
+
|
21
|
+
NotEnoughDestinationError = ADSP::NotEnoughDestinationError
|
22
|
+
UsedAfterCloseError = ADSP::UsedAfterCloseError
|
23
|
+
|
24
|
+
NotImplementedError = ADSP::NotImplementedError
|
25
|
+
UnexpectedError = ADSP::UnexpectedError
|
21
26
|
end
|
data/lib/brs/file.rb
CHANGED
@@ -1,50 +1,40 @@
|
|
1
1
|
# Ruby bindings for brotli library.
|
2
2
|
# Copyright (c) 2019 AUTHORS, MIT License.
|
3
3
|
|
4
|
+
require "adsp/file"
|
4
5
|
require "brs_ext"
|
5
6
|
|
6
|
-
require_relative "error"
|
7
7
|
require_relative "option"
|
8
8
|
require_relative "validation"
|
9
9
|
|
10
10
|
module BRS
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
# BRS::File class.
|
12
|
+
class File < ADSP::File
|
13
|
+
# Current option class.
|
14
|
+
Option = BRS::Option
|
15
|
+
|
16
|
+
# Compresses data from +source+ file path to +destination+ file path.
|
17
|
+
# Option: +:source_buffer_length+ source buffer length.
|
18
|
+
# Option: +:destination_buffer_length+ destination buffer length.
|
19
|
+
# Option: +:size_hint+ source bytesize.
|
14
20
|
def self.compress(source, destination, options = {})
|
15
21
|
Validation.validate_string source
|
16
|
-
Validation.validate_string destination
|
17
22
|
|
18
23
|
options = Option.get_compressor_options options, BUFFER_LENGTH_NAMES
|
19
24
|
|
20
25
|
options[:size_hint] = ::File.size source
|
21
26
|
|
22
|
-
|
23
|
-
BRS._native_compress_io source_io, destination_io, options
|
24
|
-
end
|
25
|
-
|
26
|
-
nil
|
27
|
+
super source, destination, options
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
options = Option.get_decompressor_options options, BUFFER_LENGTH_NAMES
|
34
|
-
|
35
|
-
open_files source, destination do |source_io, destination_io|
|
36
|
-
BRS._native_decompress_io source_io, destination_io, options
|
37
|
-
end
|
38
|
-
|
39
|
-
nil
|
30
|
+
# Bypass native compress.
|
31
|
+
def self.native_compress_io(*args)
|
32
|
+
BRS._native_compress_io(*args)
|
40
33
|
end
|
41
34
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
yield source_io, destination_io
|
46
|
-
end
|
47
|
-
end
|
35
|
+
# Bypass native decompress.
|
36
|
+
def self.native_decompress_io(*args)
|
37
|
+
BRS._native_decompress_io(*args)
|
48
38
|
end
|
49
39
|
end
|
50
40
|
end
|
data/lib/brs/option.rb
CHANGED
@@ -7,29 +7,58 @@ require_relative "error"
|
|
7
7
|
require_relative "validation"
|
8
8
|
|
9
9
|
module BRS
|
10
|
+
# BRS::Option module.
|
10
11
|
module Option
|
12
|
+
# Current default buffer length.
|
11
13
|
DEFAULT_BUFFER_LENGTH = 0
|
12
14
|
|
15
|
+
# Current compressor defaults.
|
13
16
|
COMPRESSOR_DEFAULTS = {
|
17
|
+
# Enables global VM lock where possible.
|
14
18
|
:gvl => false,
|
19
|
+
# Compressor mode.
|
15
20
|
:mode => nil,
|
21
|
+
# Compression level.
|
16
22
|
:quality => nil,
|
23
|
+
# Compressor window size.
|
17
24
|
:lgwin => nil,
|
25
|
+
# Compressor input block size.
|
18
26
|
:lgblock => nil,
|
27
|
+
# Recommended number of postfix bits.
|
19
28
|
:npostfix => nil,
|
29
|
+
# Recommended number of direct distance codes (step 1 << npostfix, max 15 << npostfix).
|
20
30
|
:ndirect => nil,
|
31
|
+
# Disables literal context modeling format.
|
21
32
|
:disable_literal_context_modeling => nil,
|
33
|
+
# Enables large window.
|
22
34
|
:large_window => nil
|
23
35
|
}
|
24
36
|
.freeze
|
25
37
|
|
38
|
+
# Current decompressor defaults.
|
26
39
|
DECOMPRESSOR_DEFAULTS = {
|
40
|
+
# Enables global VM lock where possible.
|
27
41
|
:gvl => false,
|
42
|
+
# Disables ring buffer reallocation.
|
28
43
|
:disable_ring_buffer_reallocation => nil,
|
44
|
+
# Enables large window.
|
29
45
|
:large_window => nil
|
30
46
|
}
|
31
47
|
.freeze
|
32
48
|
|
49
|
+
# Processes compressor +options+ and +buffer_length_names+.
|
50
|
+
# Option: +:source_buffer_length+ source buffer length.
|
51
|
+
# Option: +:destination_buffer_length+ destination buffer length.
|
52
|
+
# Option: +:gvl+ enables global VM lock where possible.
|
53
|
+
# Option: +:mode+ compressor mode.
|
54
|
+
# Option: +:quality+ compression level.
|
55
|
+
# Option: +:lgwin+ compressor window size.
|
56
|
+
# Option: +:lgblock+ compressor input block size.
|
57
|
+
# Option: +:npostfix+ recommended number of postfix bits.
|
58
|
+
# Option: +:ndirect+ recommended number of direct distance codes (step 1 << npostfix, max 15 << npostfix).
|
59
|
+
# Option: +:disable_literal_context_modeling+ Disables literal context modeling format.
|
60
|
+
# Option: +:large_window+ enables large window.
|
61
|
+
# Returns processed compressor options.
|
33
62
|
def self.get_compressor_options(options, buffer_length_names)
|
34
63
|
Validation.validate_hash options
|
35
64
|
|
@@ -94,6 +123,13 @@ module BRS
|
|
94
123
|
options
|
95
124
|
end
|
96
125
|
|
126
|
+
# Processes decompressor +options+ and +buffer_length_names+.
|
127
|
+
# Option: +:source_buffer_length+ source buffer length.
|
128
|
+
# Option: +:destination_buffer_length+ destination buffer length.
|
129
|
+
# Option: +:gvl+ enables global VM lock where possible.
|
130
|
+
# Option: +:disable_ring_buffer_reallocation+ disables ring buffer reallocation.
|
131
|
+
# Option: +:large_window+ enables large window.
|
132
|
+
# Returns processed decompressor options.
|
97
133
|
def self.get_decompressor_options(options, buffer_length_names)
|
98
134
|
Validation.validate_hash options
|
99
135
|
|
@@ -1,97 +1,33 @@
|
|
1
1
|
# Ruby bindings for brotli library.
|
2
2
|
# Copyright (c) 2019 AUTHORS, MIT License.
|
3
3
|
|
4
|
+
require "adsp/stream/raw/compressor"
|
4
5
|
require "brs_ext"
|
5
6
|
|
6
|
-
require_relative "abstract"
|
7
|
-
require_relative "../../error"
|
8
7
|
require_relative "../../option"
|
9
8
|
require_relative "../../validation"
|
10
9
|
|
11
10
|
module BRS
|
12
11
|
module Stream
|
13
12
|
module Raw
|
14
|
-
|
15
|
-
|
13
|
+
# BRS::Stream::Raw::Compressor class.
|
14
|
+
class Compressor < ADSP::Stream::Raw::Compressor
|
15
|
+
# Current native compressor class.
|
16
|
+
NativeCompressor = Stream::NativeCompressor
|
16
17
|
|
18
|
+
# Current option class.
|
19
|
+
Option = BRS::Option
|
20
|
+
|
21
|
+
# Initializes compressor.
|
22
|
+
# Option: +:destination_buffer_length+ destination buffer length.
|
23
|
+
# Option: +:size_hint+ source bytesize.
|
17
24
|
def initialize(options = {})
|
18
25
|
options = Option.get_compressor_options options, BUFFER_LENGTH_NAMES
|
19
26
|
|
20
27
|
size_hint = options[:size_hint]
|
21
28
|
Validation.validate_not_negative_integer size_hint unless size_hint.nil?
|
22
29
|
|
23
|
-
|
24
|
-
|
25
|
-
super native_stream
|
26
|
-
end
|
27
|
-
|
28
|
-
def write(source, &writer)
|
29
|
-
do_not_use_after_close
|
30
|
-
|
31
|
-
Validation.validate_string source
|
32
|
-
Validation.validate_proc writer
|
33
|
-
|
34
|
-
total_bytes_written = 0
|
35
|
-
|
36
|
-
loop do
|
37
|
-
bytes_written, need_more_destination = @native_stream.write source
|
38
|
-
total_bytes_written += bytes_written
|
39
|
-
|
40
|
-
if need_more_destination
|
41
|
-
source = source.byteslice bytes_written, source.bytesize - bytes_written
|
42
|
-
more_destination(&writer)
|
43
|
-
next
|
44
|
-
end
|
45
|
-
|
46
|
-
unless bytes_written == source.bytesize
|
47
|
-
# :nocov:
|
48
|
-
# Compressor write should eat all provided "source" without remainder.
|
49
|
-
raise UnexpectedError, "unexpected error"
|
50
|
-
# :nocov:
|
51
|
-
end
|
52
|
-
|
53
|
-
break
|
54
|
-
end
|
55
|
-
|
56
|
-
total_bytes_written
|
57
|
-
end
|
58
|
-
|
59
|
-
def flush(&writer)
|
60
|
-
do_not_use_after_close
|
61
|
-
|
62
|
-
Validation.validate_proc writer
|
63
|
-
|
64
|
-
loop do
|
65
|
-
need_more_destination = @native_stream.flush
|
66
|
-
|
67
|
-
if need_more_destination
|
68
|
-
more_destination(&writer)
|
69
|
-
next
|
70
|
-
end
|
71
|
-
|
72
|
-
break
|
73
|
-
end
|
74
|
-
|
75
|
-
super
|
76
|
-
end
|
77
|
-
|
78
|
-
def close(&writer)
|
79
|
-
return nil if closed?
|
80
|
-
|
81
|
-
Validation.validate_proc writer
|
82
|
-
|
83
|
-
loop do
|
84
|
-
need_more_destination = @native_stream.finish
|
85
|
-
|
86
|
-
if need_more_destination
|
87
|
-
more_destination(&writer)
|
88
|
-
next
|
89
|
-
end
|
90
|
-
|
91
|
-
break
|
92
|
-
end
|
93
|
-
|
94
|
-
super
|
30
|
+
super options
|
95
31
|
end
|
96
32
|
end
|
97
33
|
end
|
@@ -1,65 +1,21 @@
|
|
1
1
|
# Ruby bindings for brotli library.
|
2
2
|
# Copyright (c) 2019 AUTHORS, MIT License.
|
3
3
|
|
4
|
+
require "adsp/stream/raw/decompressor"
|
4
5
|
require "brs_ext"
|
5
6
|
|
6
|
-
require_relative "abstract"
|
7
7
|
require_relative "../../option"
|
8
|
-
require_relative "../../validation"
|
9
8
|
|
10
9
|
module BRS
|
11
10
|
module Stream
|
12
11
|
module Raw
|
13
|
-
|
14
|
-
|
12
|
+
# BRS::Stream::Raw::Decompressor class.
|
13
|
+
class Decompressor < ADSP::Stream::Raw::Decompressor
|
14
|
+
# Current native decompressor class.
|
15
|
+
NativeDecompressor = Stream::NativeDecompressor
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
native_stream = NativeDecompressor.new options
|
19
|
-
|
20
|
-
super native_stream
|
21
|
-
end
|
22
|
-
|
23
|
-
def read(source, &writer)
|
24
|
-
do_not_use_after_close
|
25
|
-
|
26
|
-
Validation.validate_string source
|
27
|
-
Validation.validate_proc writer
|
28
|
-
|
29
|
-
total_bytes_read = 0
|
30
|
-
|
31
|
-
loop do
|
32
|
-
bytes_read, need_more_destination = @native_stream.read source
|
33
|
-
total_bytes_read += bytes_read
|
34
|
-
|
35
|
-
if need_more_destination
|
36
|
-
source = source.byteslice bytes_read, source.bytesize - bytes_read
|
37
|
-
more_destination(&writer)
|
38
|
-
next
|
39
|
-
end
|
40
|
-
|
41
|
-
break
|
42
|
-
end
|
43
|
-
|
44
|
-
# Please remember that "total_bytes_read" can not be equal to "source.bytesize".
|
45
|
-
total_bytes_read
|
46
|
-
end
|
47
|
-
|
48
|
-
def flush(&writer)
|
49
|
-
do_not_use_after_close
|
50
|
-
|
51
|
-
Validation.validate_proc writer
|
52
|
-
|
53
|
-
super
|
54
|
-
end
|
55
|
-
|
56
|
-
def close(&writer)
|
57
|
-
return nil if closed?
|
58
|
-
|
59
|
-
Validation.validate_proc writer
|
60
|
-
|
61
|
-
super
|
62
|
-
end
|
17
|
+
# Current option class.
|
18
|
+
Option = BRS::Option
|
63
19
|
end
|
64
20
|
end
|
65
21
|
end
|