burli 0.1.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/CHANGELOG.md +11 -0
- data/README.md +29 -0
- data/ext/burli_native/Cargo.toml +25 -0
- data/ext/burli_native/build.rs +24 -0
- data/ext/burli_native/extconf.rb +14 -0
- data/ext/burli_native/src/lib.rs +561 -0
- data/ext/burli_native/src/rb.rs +456 -0
- data/lib/burli/reader.rb +116 -0
- data/lib/burli/version.rb +6 -0
- data/lib/burli/writer.rb +71 -0
- data/lib/burli.rb +137 -0
- metadata +68 -0
data/lib/burli.rb
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "burli/version"
|
|
4
|
+
|
|
5
|
+
# Precompiled gems hold one extension per Ruby minor version.
|
|
6
|
+
begin
|
|
7
|
+
require_relative "burli/#{RUBY_VERSION[/\A\d+\.\d+/]}/burli_native"
|
|
8
|
+
rescue LoadError
|
|
9
|
+
require_relative "burli/burli_native"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Memory-safe Brotli compression and decompression, with the API of the
|
|
13
|
+
# brotli gem. Existing code can switch with:
|
|
14
|
+
#
|
|
15
|
+
# Brotli = Burli
|
|
16
|
+
#
|
|
17
|
+
# Qualities 6 to 11 run as 5.
|
|
18
|
+
module Burli
|
|
19
|
+
# Checks options, with the messages of the brotli gem, for the native
|
|
20
|
+
# methods.
|
|
21
|
+
module Options
|
|
22
|
+
MODES = {generic: 0, text: 1, font: 2}.freeze
|
|
23
|
+
|
|
24
|
+
module_function
|
|
25
|
+
|
|
26
|
+
def merge(options, kwargs)
|
|
27
|
+
Hash(options).merge(kwargs)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @return [Array(Integer, Integer, Integer, Integer)] mode, quality,
|
|
31
|
+
# lgwin, and lgblock
|
|
32
|
+
def encoder(options)
|
|
33
|
+
unless options[:dictionary].nil?
|
|
34
|
+
raise ArgumentError, "burli does not support dictionaries for compression"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
mode = options[:mode].nil? ? 0 : MODES.fetch(options[:mode]) { raise ArgumentError, "invalid mode" }
|
|
38
|
+
[
|
|
39
|
+
mode,
|
|
40
|
+
integer(options[:quality], 5, "invalid quality value. Should be 0 to 11.") { (0..11).cover?(_1) },
|
|
41
|
+
integer(options[:lgwin], 22, "invalid lgwin value. Should be 10 to 24.") { (10..24).cover?(_1) },
|
|
42
|
+
integer(options[:lgblock], 0, "invalid lgblock value. Should be 0 or 16 to 24.") do
|
|
43
|
+
_1.zero? || (16..24).cover?(_1)
|
|
44
|
+
end
|
|
45
|
+
]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def integer(value, default, message)
|
|
49
|
+
return default if value.nil?
|
|
50
|
+
raise ArgumentError, message unless value.is_a?(Integer) && yield(value)
|
|
51
|
+
|
|
52
|
+
value
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @return [String, nil] raw dictionary bytes
|
|
56
|
+
def dictionary(options)
|
|
57
|
+
options[:dictionary]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# @return [Integer] the limit, or 0 for none
|
|
61
|
+
def output_buffer_limit(options)
|
|
62
|
+
limit = options[:output_buffer_limit]
|
|
63
|
+
return 0 if limit.nil?
|
|
64
|
+
raise TypeError, "output_buffer_limit must be an Integer" unless limit.is_a?(Integer)
|
|
65
|
+
raise ArgumentError, "output_buffer_limit must be positive" unless limit.positive?
|
|
66
|
+
|
|
67
|
+
limit
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
private_constant :Options
|
|
71
|
+
|
|
72
|
+
private_class_method :_native_deflate, :_native_inflate
|
|
73
|
+
|
|
74
|
+
class << self
|
|
75
|
+
# Compresses +string+.
|
|
76
|
+
# @param options [Hash, nil] +mode+ (+:generic+, +:text+, or +:font+),
|
|
77
|
+
# +quality+ (0 to 11), +lgwin+ (10 to 24), and +lgblock+ (0 or 16 to 24)
|
|
78
|
+
# @return [String] the Brotli stream
|
|
79
|
+
# @raise [ArgumentError] for invalid options
|
|
80
|
+
def deflate(string, options = nil, **kwargs)
|
|
81
|
+
raise ArgumentError, "input should not be nil" if string.nil?
|
|
82
|
+
|
|
83
|
+
_native_deflate(string, *Options.encoder(Options.merge(options, kwargs)))
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Decompresses a whole Brotli stream, from a String or an IO.
|
|
87
|
+
# @param options [Hash, nil] +dictionary+, a raw dictionary
|
|
88
|
+
# @return [String]
|
|
89
|
+
# @raise [Error] for malformed or truncated streams, and for data after
|
|
90
|
+
# the end of the stream
|
|
91
|
+
def inflate(string, options = nil, **kwargs)
|
|
92
|
+
string = string.read if string.respond_to?(:read)
|
|
93
|
+
_native_inflate(string, Options.dictionary(Options.merge(options, kwargs)))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# @return [String] the gem version
|
|
97
|
+
def version
|
|
98
|
+
VERSION
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Compresses a stream in pieces.
|
|
103
|
+
class Compressor
|
|
104
|
+
private_class_method :_native_new
|
|
105
|
+
|
|
106
|
+
# @param options [Hash, nil] as for {Burli.deflate}
|
|
107
|
+
def self.new(options = nil, **kwargs)
|
|
108
|
+
_native_new(*Options.encoder(Options.merge(options, kwargs)))
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Decompresses a stream in pieces.
|
|
113
|
+
class Decompressor
|
|
114
|
+
private_class_method :_native_new
|
|
115
|
+
private :_native_process
|
|
116
|
+
|
|
117
|
+
# @param options [Hash, nil] +dictionary+, a raw dictionary
|
|
118
|
+
def self.new(options = nil, **kwargs)
|
|
119
|
+
_native_new(Options.dictionary(Options.merge(options, kwargs)))
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Decompresses +input+, returning the output produced so far. With
|
|
123
|
+
# +output_buffer_limit+, returns at most that many bytes; then call with
|
|
124
|
+
# empty input until {#can_accept_more_data} is true before passing more.
|
|
125
|
+
# @raise [Error] for malformed streams, and for input while output is
|
|
126
|
+
# pending or after the end of the stream
|
|
127
|
+
def process(input, options = nil, **kwargs)
|
|
128
|
+
_native_process(input, Options.output_buffer_limit(Options.merge(options, kwargs)))
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
alias_method :is_finished, :finished?
|
|
132
|
+
alias_method :can_accept_more_data?, :can_accept_more_data
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
require_relative "burli/reader"
|
|
137
|
+
require_relative "burli/writer"
|
metadata
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: burli
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Patrik Wenger
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rb_sys
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0.9'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0.9'
|
|
26
|
+
email:
|
|
27
|
+
- paddor@gmail.com
|
|
28
|
+
executables: []
|
|
29
|
+
extensions:
|
|
30
|
+
- ext/burli_native/extconf.rb
|
|
31
|
+
extra_rdoc_files: []
|
|
32
|
+
files:
|
|
33
|
+
- CHANGELOG.md
|
|
34
|
+
- README.md
|
|
35
|
+
- ext/burli_native/Cargo.toml
|
|
36
|
+
- ext/burli_native/build.rs
|
|
37
|
+
- ext/burli_native/extconf.rb
|
|
38
|
+
- ext/burli_native/src/lib.rs
|
|
39
|
+
- ext/burli_native/src/rb.rs
|
|
40
|
+
- lib/burli.rb
|
|
41
|
+
- lib/burli/reader.rb
|
|
42
|
+
- lib/burli/version.rb
|
|
43
|
+
- lib/burli/writer.rb
|
|
44
|
+
homepage: https://github.com/paddor/burli/tree/main/bindings/ruby
|
|
45
|
+
licenses:
|
|
46
|
+
- MIT
|
|
47
|
+
metadata:
|
|
48
|
+
source_code_uri: https://github.com/paddor/burli/tree/main/bindings/ruby
|
|
49
|
+
changelog_uri: https://github.com/paddor/burli/tree/main/bindings/ruby/CHANGELOG.md
|
|
50
|
+
rubygems_mfa_required: 'true'
|
|
51
|
+
rdoc_options: []
|
|
52
|
+
require_paths:
|
|
53
|
+
- lib
|
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: '3.3'
|
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: '0'
|
|
64
|
+
requirements: []
|
|
65
|
+
rubygems_version: 4.0.20
|
|
66
|
+
specification_version: 4
|
|
67
|
+
summary: Memory-safe Brotli compression in Rust, with the API of the brotli gem
|
|
68
|
+
test_files: []
|