brotli 0.7.0 → 0.8.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 +4 -4
- data/README.md +113 -1
- data/Rakefile +3 -3
- data/brotli.gemspec +12 -12
- data/ext/brotli/brotli.c +859 -258
- data/ext/brotli/buffer.c +43 -65
- data/ext/brotli/buffer.h +6 -9
- data/ext/brotli/extconf.rb +13 -19
- data/lib/brotli/reader.rb +167 -0
- data/lib/brotli/version.rb +1 -1
- data/lib/brotli/writer.rb +81 -0
- data/lib/brotli.rb +2 -0
- data/vendor/brotli/c/common/constants.c +7 -7
- data/vendor/brotli/c/common/constants.h +2 -5
- data/vendor/brotli/c/common/context.c +2 -2
- data/vendor/brotli/c/common/context.h +1 -2
- data/vendor/brotli/c/common/dictionary.c +4 -5856
- data/vendor/brotli/c/common/dictionary.h +1 -2
- data/vendor/brotli/c/common/dictionary_inc.h +5847 -0
- data/vendor/brotli/c/common/platform.c +0 -4
- data/vendor/brotli/c/common/platform.h +182 -43
- data/vendor/brotli/c/common/shared_dictionary.c +3 -7
- data/vendor/brotli/c/common/shared_dictionary_internal.h +1 -1
- data/vendor/brotli/c/common/static_init.h +56 -0
- data/vendor/brotli/c/common/transform.c +6 -4
- data/vendor/brotli/c/common/transform.h +1 -2
- data/vendor/brotli/c/common/version.h +3 -3
- data/vendor/brotli/c/dec/bit_reader.c +2 -3
- data/vendor/brotli/c/dec/bit_reader.h +0 -4
- data/vendor/brotli/c/dec/decode.c +128 -39
- data/vendor/brotli/c/dec/huffman.c +2 -5
- data/vendor/brotli/c/dec/huffman.h +0 -2
- data/vendor/brotli/c/dec/prefix.c +67 -0
- data/vendor/brotli/c/dec/prefix.h +18 -708
- data/vendor/brotli/c/dec/prefix_inc.h +707 -0
- data/vendor/brotli/c/dec/state.c +18 -15
- data/vendor/brotli/c/dec/state.h +2 -6
- data/vendor/brotli/c/dec/static_init.c +53 -0
- data/vendor/brotli/c/dec/static_init.h +30 -0
- data/vendor/brotli/c/enc/backward_references.c +32 -8
- data/vendor/brotli/c/enc/backward_references.h +1 -5
- data/vendor/brotli/c/enc/backward_references_hq.c +15 -15
- data/vendor/brotli/c/enc/backward_references_hq.h +1 -5
- data/vendor/brotli/c/enc/bit_cost.c +28 -4
- data/vendor/brotli/c/enc/bit_cost.h +8 -40
- data/vendor/brotli/c/enc/bit_cost_inc.h +1 -1
- data/vendor/brotli/c/enc/block_splitter.c +9 -12
- data/vendor/brotli/c/enc/block_splitter.h +0 -3
- data/vendor/brotli/c/enc/block_splitter_inc.h +14 -8
- data/vendor/brotli/c/enc/brotli_bit_stream.c +10 -9
- data/vendor/brotli/c/enc/brotli_bit_stream.h +0 -6
- data/vendor/brotli/c/enc/cluster.c +0 -2
- data/vendor/brotli/c/enc/cluster.h +0 -2
- data/vendor/brotli/c/enc/command.c +1 -1
- data/vendor/brotli/c/enc/command.h +8 -10
- data/vendor/brotli/c/enc/compound_dictionary.c +3 -5
- data/vendor/brotli/c/enc/compound_dictionary.h +1 -4
- data/vendor/brotli/c/enc/compress_fragment.c +3 -13
- data/vendor/brotli/c/enc/compress_fragment.h +0 -2
- data/vendor/brotli/c/enc/compress_fragment_two_pass.c +5 -15
- data/vendor/brotli/c/enc/compress_fragment_two_pass.h +0 -2
- data/vendor/brotli/c/enc/dictionary_hash.c +127 -1830
- data/vendor/brotli/c/enc/dictionary_hash.h +23 -3
- data/vendor/brotli/c/enc/dictionary_hash_inc.h +1829 -0
- data/vendor/brotli/c/enc/encode.c +77 -52
- data/vendor/brotli/c/enc/encoder_dict.c +9 -7
- data/vendor/brotli/c/enc/encoder_dict.h +2 -4
- data/vendor/brotli/c/enc/entropy_encode.c +3 -6
- data/vendor/brotli/c/enc/entropy_encode.h +2 -4
- data/vendor/brotli/c/enc/entropy_encode_static.h +18 -12
- data/vendor/brotli/c/enc/fast_log.c +1 -1
- data/vendor/brotli/c/enc/fast_log.h +2 -3
- data/vendor/brotli/c/enc/find_match_length.h +0 -2
- data/vendor/brotli/c/enc/hash.h +38 -31
- data/vendor/brotli/c/enc/hash_base.h +38 -0
- data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +11 -1
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +24 -7
- data/vendor/brotli/c/enc/hash_longest_match64_simd_inc.h +304 -0
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +30 -11
- data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -0
- data/vendor/brotli/c/enc/hash_longest_match_simd_inc.h +278 -0
- data/vendor/brotli/c/enc/histogram.c +1 -0
- data/vendor/brotli/c/enc/histogram.h +0 -4
- data/vendor/brotli/c/enc/literal_cost.c +4 -6
- data/vendor/brotli/c/enc/literal_cost.h +0 -2
- data/vendor/brotli/c/enc/matching_tag_mask.h +69 -0
- data/vendor/brotli/c/enc/memory.c +0 -5
- data/vendor/brotli/c/enc/memory.h +0 -4
- data/vendor/brotli/c/enc/metablock.c +7 -9
- data/vendor/brotli/c/enc/metablock.h +3 -3
- data/vendor/brotli/c/enc/metablock_inc.h +4 -4
- data/vendor/brotli/c/enc/params.h +0 -1
- data/vendor/brotli/c/enc/prefix.h +0 -2
- data/vendor/brotli/c/enc/quality.h +17 -10
- data/vendor/brotli/c/enc/ringbuffer.h +1 -4
- data/vendor/brotli/c/enc/state.h +2 -2
- data/vendor/brotli/c/enc/static_dict.c +5 -11
- data/vendor/brotli/c/enc/static_dict.h +1 -3
- data/vendor/brotli/c/enc/static_dict_lut.c +224 -0
- data/vendor/brotli/c/enc/static_dict_lut.h +20 -5837
- data/vendor/brotli/c/enc/static_dict_lut_inc.h +5830 -0
- data/vendor/brotli/c/enc/static_init.c +59 -0
- data/vendor/brotli/c/enc/static_init.h +30 -0
- data/vendor/brotli/c/enc/static_init_lazy.cc +26 -0
- data/vendor/brotli/c/enc/utf8_util.c +1 -1
- data/vendor/brotli/c/enc/utf8_util.h +0 -2
- data/vendor/brotli/c/enc/write_bits.h +0 -2
- data/vendor/brotli/c/include/brotli/decode.h +1 -1
- data/vendor/brotli/c/include/brotli/encode.h +5 -1
- data/vendor/brotli/c/include/brotli/port.h +4 -7
- data/vendor/brotli/c/include/brotli/types.h +2 -2
- metadata +22 -10
- data/test/brotli_test.rb +0 -183
- data/test/brotli_writer_test.rb +0 -93
- data/test/test_helper.rb +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 439249d900d92fdfbdba0c607d03b1cc52be123ed909bf7971d6c8b89c8134de
|
|
4
|
+
data.tar.gz: 3ae1816fee964948daedfa0835f2098efd4526def10f855f6a3fcc415ad56ce1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 330cc7d4176f2ede18d615c7c51862131182c5e3826d164b3cced606a490924d44ef349ab746677e8f62f547a87601ddc65c5f95197a7cc43f53e87f1a7f448d
|
|
7
|
+
data.tar.gz: 711194c375cd78bba734cb5ae4b89270ddcbaa8a457e3e45b055a6334a0a684d1f7351780c868a965c804cab306796949f5e915a60bbeb95f332b6900fea68a6
|
data/README.md
CHANGED
|
@@ -80,13 +80,125 @@ File.open('output.br', 'wb') do |file|
|
|
|
80
80
|
end
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
+
### Streaming Decompression with Reader
|
|
84
|
+
|
|
85
|
+
```ruby
|
|
86
|
+
# Basic usage
|
|
87
|
+
File.open('output.br', 'rb') do |file|
|
|
88
|
+
reader = Brotli::Reader.new(file)
|
|
89
|
+
data = reader.read
|
|
90
|
+
reader.close
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# With dictionary
|
|
94
|
+
File.open('output.br', 'rb') do |file|
|
|
95
|
+
reader = Brotli::Reader.new(file, dictionary: dictionary)
|
|
96
|
+
data = reader.read
|
|
97
|
+
reader.close
|
|
98
|
+
end
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`Brotli::Reader` is the preferred API when you already have an IO-like input.
|
|
102
|
+
It handles incremental decompression for you, including small `read` and
|
|
103
|
+
`readpartial` calls.
|
|
104
|
+
|
|
105
|
+
### Low-level Streaming with Compressor and Decompressor
|
|
106
|
+
|
|
107
|
+
`Brotli::Writer` and `Brotli::Reader` are the preferred high-level streaming
|
|
108
|
+
interfaces. `Brotli::Compressor` and `Brotli::Decompressor` are lower-level
|
|
109
|
+
primitives intended for integrations which already manage their own buffering
|
|
110
|
+
and chunk boundaries.
|
|
111
|
+
|
|
112
|
+
Use `Brotli::Writer` and `Brotli::Reader` when you have an IO-like stream and
|
|
113
|
+
want Brotli to handle the streaming lifecycle for you.
|
|
114
|
+
|
|
115
|
+
Use `Brotli::Compressor` and `Brotli::Decompressor` when your application
|
|
116
|
+
already owns the buffering model, for example when working with framed
|
|
117
|
+
protocols, event loops, chunked transports, or custom body transcoders.
|
|
118
|
+
|
|
119
|
+
This is a typical chunk-by-chunk compression pattern:
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
compressor = Brotli::Compressor.new
|
|
123
|
+
|
|
124
|
+
compressed_chunk = compressor.process(input_chunk)
|
|
125
|
+
compressed_chunk << compressor.flush
|
|
126
|
+
|
|
127
|
+
# when the input stream is finished
|
|
128
|
+
compressed_tail = compressor.finish
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
And this is the corresponding incremental decompression pattern:
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
decompressor = Brotli::Decompressor.new
|
|
135
|
+
output = +""
|
|
136
|
+
|
|
137
|
+
compressed_chunks.each do |input_chunk|
|
|
138
|
+
output << decompressor.process(input_chunk)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
unless decompressor.finished?
|
|
142
|
+
raise Brotli::Error, "Unexpected end of compressed stream"
|
|
143
|
+
end
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
For fully chunked or frame-based transports, call `#process` once per received
|
|
147
|
+
compressed chunk and append the returned output. `#finished?` tells you whether
|
|
148
|
+
the full Brotli stream has been decoded, and `#can_accept_more_data` indicates
|
|
149
|
+
whether the decompressor is ready for more input or still has buffered output to
|
|
150
|
+
drain first.
|
|
151
|
+
|
|
152
|
+
These low-level classes are useful when you need to plug Brotli into an
|
|
153
|
+
existing incremental pipeline without wrapping the stream in an IO-like object.
|
|
154
|
+
|
|
155
|
+
### `output_buffer_limit`
|
|
156
|
+
|
|
157
|
+
`Brotli::Decompressor#process` also accepts `output_buffer_limit:`:
|
|
158
|
+
|
|
159
|
+
```ruby
|
|
160
|
+
decompressor = Brotli::Decompressor.new
|
|
161
|
+
output = +""
|
|
162
|
+
|
|
163
|
+
compressed_chunks.each do |chunk|
|
|
164
|
+
output << decompressor.process(chunk, output_buffer_limit: 16 * 1024)
|
|
165
|
+
|
|
166
|
+
until decompressor.can_accept_more_data || decompressor.finished?
|
|
167
|
+
output << decompressor.process("", output_buffer_limit: 16 * 1024)
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
unless decompressor.finished?
|
|
172
|
+
raise Brotli::Error, "Unexpected end of compressed stream"
|
|
173
|
+
end
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
`output_buffer_limit:` caps how many decompressed bytes are returned from a
|
|
177
|
+
single `#process` call. When the limit is reached, the decompressor may still
|
|
178
|
+
have buffered state to drain. In that case `#can_accept_more_data` returns
|
|
179
|
+
`false`, and you should keep calling `#process("")` until it becomes `true`
|
|
180
|
+
again or the stream is finished.
|
|
181
|
+
|
|
182
|
+
Use `output_buffer_limit:` when:
|
|
183
|
+
|
|
184
|
+
- you want to bound memory usage or work per iteration
|
|
185
|
+
- you are feeding decompressed bytes into a downstream consumer with backpressure
|
|
186
|
+
- you are integrating Brotli into an event loop, framed protocol, or chunked transport
|
|
187
|
+
- you are reading small slices from a large compressed payload and do not want a single call to return a very large output buffer
|
|
188
|
+
|
|
189
|
+
You usually do not need `output_buffer_limit:` when:
|
|
190
|
+
|
|
191
|
+
- you are using `Brotli.inflate` for one-shot decompression
|
|
192
|
+
- you are using `Brotli::Reader`, which already handles incremental buffering for IO-style reads
|
|
193
|
+
- you are happy for each `#process` call to return all currently available output
|
|
194
|
+
|
|
83
195
|
See test/brotli_test.rb for more examples.
|
|
84
196
|
|
|
85
197
|
## Development
|
|
86
198
|
|
|
87
199
|
After checking out the repo, run `bin/setup` to install bundle and Brotli C library dependencies.
|
|
88
200
|
|
|
89
|
-
Run `rake build` to build
|
|
201
|
+
Run `rake build` to build the Brotli extension for Ruby. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
90
202
|
|
|
91
203
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
92
204
|
|
data/Rakefile
CHANGED
|
@@ -20,9 +20,9 @@ Rake::ExtensionTask.new("brotli") do |ext|
|
|
|
20
20
|
ext.lib_dir = "lib/brotli"
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
task :
|
|
24
|
-
task :
|
|
25
|
-
task :
|
|
23
|
+
task build: :compile
|
|
24
|
+
task test: :compile
|
|
25
|
+
task default: :test
|
|
26
26
|
|
|
27
27
|
task :docker do
|
|
28
28
|
gcc_versions = ["14", "15"]
|
data/brotli.gemspec
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
-
require "brotli/version"
|
|
1
|
+
require_relative "lib/brotli/version"
|
|
5
2
|
|
|
6
3
|
Gem::Specification.new do |spec|
|
|
7
4
|
spec.name = "brotli"
|
|
@@ -14,14 +11,17 @@ Gem::Specification.new do |spec|
|
|
|
14
11
|
spec.homepage = "https://github.com/miyucy/brotli"
|
|
15
12
|
spec.license = "MIT"
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
spec.files
|
|
23
|
-
|
|
24
|
-
|
|
14
|
+
tracked_files = Dir.chdir(__dir__) { `git ls-files -z`.split("\x0") }
|
|
15
|
+
vendored_brotli_files = Dir.chdir(__dir__) do
|
|
16
|
+
Dir["vendor/brotli/c/{common,enc,dec,include}/**/*"].select { |path| File.file?(path) }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
spec.files = tracked_files
|
|
20
|
+
.reject { |path| path == "vendor/brotli" || path.start_with?("test/") }
|
|
21
|
+
.concat(vendored_brotli_files)
|
|
22
|
+
.append("vendor/brotli/LICENSE")
|
|
23
|
+
.sort
|
|
24
|
+
.uniq
|
|
25
25
|
spec.require_paths = ["lib"]
|
|
26
26
|
spec.extensions = ["ext/brotli/extconf.rb"]
|
|
27
27
|
end
|