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.
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: []