brotli 0.2.3 → 0.4.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/.github/workflows/main.yml +34 -0
- data/.github/workflows/publish.yml +34 -0
- data/Gemfile +6 -3
- data/Rakefile +16 -9
- data/brotli.gemspec +7 -13
- data/ext/brotli/brotli.c +209 -31
- data/ext/brotli/buffer.c +1 -7
- data/ext/brotli/buffer.h +1 -1
- data/ext/brotli/extconf.rb +20 -18
- data/lib/brotli/version.rb +1 -1
- data/test/brotli_test.rb +104 -0
- data/test/brotli_writer_test.rb +36 -0
- data/test/test_helper.rb +8 -0
- data/vendor/brotli/c/common/constants.c +15 -0
- data/vendor/brotli/c/common/constants.h +136 -0
- data/vendor/brotli/c/common/context.c +156 -0
- data/vendor/brotli/c/common/context.h +4 -152
- data/vendor/brotli/c/common/dictionary.bin.br +0 -0
- data/vendor/brotli/c/common/dictionary.c +10 -1
- data/vendor/brotli/c/common/platform.c +22 -0
- data/vendor/brotli/c/common/platform.h +43 -17
- data/vendor/brotli/c/common/transform.c +59 -3
- data/vendor/brotli/c/common/transform.h +5 -0
- data/vendor/brotli/c/common/version.h +2 -2
- data/vendor/brotli/c/dec/bit_reader.c +28 -0
- data/vendor/brotli/c/dec/bit_reader.h +58 -16
- data/vendor/brotli/c/dec/decode.c +353 -251
- data/vendor/brotli/c/dec/huffman.h +6 -12
- data/vendor/brotli/c/dec/prefix.h +0 -18
- data/vendor/brotli/c/dec/state.c +9 -14
- data/vendor/brotli/c/dec/state.h +144 -37
- data/vendor/brotli/c/enc/backward_references.c +8 -7
- data/vendor/brotli/c/enc/backward_references.h +5 -4
- data/vendor/brotli/c/enc/backward_references_hq.c +51 -33
- data/vendor/brotli/c/enc/backward_references_hq.h +11 -8
- data/vendor/brotli/c/enc/backward_references_inc.h +24 -14
- data/vendor/brotli/c/enc/block_splitter.c +3 -3
- data/vendor/brotli/c/enc/block_splitter_inc.h +15 -6
- data/vendor/brotli/c/enc/brotli_bit_stream.c +13 -30
- data/vendor/brotli/c/enc/cluster_inc.h +6 -3
- data/vendor/brotli/c/enc/command.c +28 -0
- data/vendor/brotli/c/enc/command.h +12 -12
- data/vendor/brotli/c/enc/compress_fragment_two_pass.c +1 -1
- data/vendor/brotli/c/enc/dictionary_hash.c +1826 -1100
- data/vendor/brotli/c/enc/dictionary_hash.h +2 -1
- data/vendor/brotli/c/enc/encode.c +104 -39
- data/vendor/brotli/c/enc/encoder_dict.c +3 -2
- data/vendor/brotli/c/enc/encoder_dict.h +3 -1
- data/vendor/brotli/c/enc/entropy_encode.c +2 -0
- data/vendor/brotli/c/enc/entropy_encode.h +2 -2
- data/vendor/brotli/c/enc/fast_log.c +105 -0
- data/vendor/brotli/c/enc/fast_log.h +19 -100
- data/vendor/brotli/c/enc/find_match_length.h +2 -3
- data/vendor/brotli/c/enc/hash.h +80 -90
- data/vendor/brotli/c/enc/hash_composite_inc.h +52 -63
- data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +88 -49
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +50 -50
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +53 -50
- data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +91 -60
- data/vendor/brotli/c/enc/hash_rolling_inc.h +23 -27
- data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +39 -38
- data/vendor/brotli/c/enc/memory.h +24 -12
- data/vendor/brotli/c/enc/metablock.c +23 -27
- data/vendor/brotli/c/enc/metablock_inc.h +1 -1
- data/vendor/brotli/c/enc/params.h +3 -1
- data/vendor/brotli/c/enc/ringbuffer.h +4 -1
- data/vendor/brotli/c/enc/utf8_util.c +1 -1
- data/vendor/brotli/c/enc/write_bits.h +27 -25
- data/vendor/brotli/c/include/brotli/encode.h +22 -1
- data/vendor/brotli/c/include/brotli/port.h +14 -0
- metadata +17 -97
- data/.travis.yml +0 -31
- data/docs/Brotli.html +0 -485
- data/docs/Brotli/Error.html +0 -124
- data/docs/_index.html +0 -122
- data/docs/class_list.html +0 -51
- data/docs/css/common.css +0 -1
- data/docs/css/full_list.css +0 -58
- data/docs/css/style.css +0 -496
- data/docs/file.README.html +0 -127
- data/docs/file_list.html +0 -56
- data/docs/frames.html +0 -17
- data/docs/index.html +0 -127
- data/docs/js/app.js +0 -292
- data/docs/js/full_list.js +0 -216
- data/docs/js/jquery.js +0 -4
- data/docs/method_list.html +0 -67
- data/docs/top-level-namespace.html +0 -110
- data/spec/brotli_spec.rb +0 -88
- data/spec/inflate_spec.rb +0 -75
- data/spec/spec_helper.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 410f0b599c6bf42f90cb7fa83c6710304ad0fb018b1f4b5560bfadadaef165d9
|
4
|
+
data.tar.gz: 03fbcca525c9705b99935ab2ea4db0bb80e4c6a960d3010450a173c5b305eb43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe26f6b7a9a2f3a0bf0ab5d1e79ff89ff8dc2a763e3b8beb073feb365f6ae222dcf277672bbbe2ac7aeaa71f2b024edd6ce49a6a7254452897fdbfef61f422a5
|
7
|
+
data.tar.gz: c1952c3b820fa2ec0b5a1e1567acfe831fcc1a6131f07e12acf3b26595c3bda90c89182abfcc57730febe5311906632ea8c19a21e16e866a5e620a8b85cfa2d4
|
@@ -0,0 +1,34 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on: [pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
strategy:
|
8
|
+
fail-fast: false
|
9
|
+
matrix:
|
10
|
+
ruby: [2.5, 2.6, 2.7, 3.0]
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
steps:
|
13
|
+
- uses: actions/checkout@v2
|
14
|
+
with:
|
15
|
+
submodules: true
|
16
|
+
- name: Set up Ruby
|
17
|
+
uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: ${{ matrix.ruby }}
|
20
|
+
bundler-cache: true
|
21
|
+
- name: Run the default task
|
22
|
+
run: |
|
23
|
+
bundle exec rake clobber test build
|
24
|
+
gem install --no-document "$(ls pkg/brotli-*.gem)"
|
25
|
+
cat <<EOF | ruby
|
26
|
+
require "brotli"
|
27
|
+
if Brotli.inflate(Brotli.deflate(File.read("README.md"))) == File.read("README.md")
|
28
|
+
puts "OK"
|
29
|
+
exit 0
|
30
|
+
else
|
31
|
+
puts "NG"
|
32
|
+
exit 0
|
33
|
+
end
|
34
|
+
EOF
|
@@ -0,0 +1,34 @@
|
|
1
|
+
name: Publish Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
tags:
|
6
|
+
- 'v*'
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
build:
|
10
|
+
strategy:
|
11
|
+
fail-fast: false
|
12
|
+
matrix:
|
13
|
+
ruby: [2.7]
|
14
|
+
runs-on: ubuntu-latest
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
with:
|
18
|
+
submodules: true
|
19
|
+
- name: Set up Ruby
|
20
|
+
uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby }}
|
23
|
+
bundler-cache: true
|
24
|
+
- name: Run release task
|
25
|
+
run: |
|
26
|
+
mkdir -p ~/.gem
|
27
|
+
cat << EOF > ~/.gem/credentials
|
28
|
+
---
|
29
|
+
:github: Bearer ${{secrets.GITHUB_TOKEN}}
|
30
|
+
:rubygems_api_key: ${{secrets.RUBYGEMS_API_KEY}}
|
31
|
+
EOF
|
32
|
+
chmod 600 ~/.gem/credentials
|
33
|
+
bundle exec rake release[remote]
|
34
|
+
rm -f ~/.gem/credentials
|
data/Gemfile
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in brotli.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
gem
|
7
|
-
gem
|
6
|
+
gem "rake", "~> 13.0"
|
7
|
+
gem "rake-compiler"
|
8
|
+
gem "test-unit", "~> 3.0"
|
9
|
+
gem "test-unit-rr"
|
10
|
+
gem "rantly"
|
data/Rakefile
CHANGED
@@ -1,18 +1,25 @@
|
|
1
|
+
require "bundler/setup"
|
1
2
|
require "bundler/gem_tasks"
|
2
|
-
require "
|
3
|
+
require "rake/clean"
|
4
|
+
require "rake/testtask"
|
3
5
|
require "rake/extensiontask"
|
4
|
-
require "yard"
|
5
6
|
|
6
|
-
|
7
|
+
CLEAN.include("ext/brotli/common")
|
8
|
+
CLEAN.include("ext/brotli/dec")
|
9
|
+
CLEAN.include("ext/brotli/enc")
|
10
|
+
CLEAN.include("ext/brotli/include")
|
7
11
|
|
8
|
-
|
9
|
-
|
10
|
-
|
12
|
+
Rake::TestTask.new(:test) do |t|
|
13
|
+
t.libs << "test"
|
14
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
15
|
+
t.warning = true
|
16
|
+
t.verbose = true
|
17
|
+
end
|
11
18
|
|
12
19
|
Rake::ExtensionTask.new("brotli") do |ext|
|
13
20
|
ext.lib_dir = "lib/brotli"
|
14
21
|
end
|
15
22
|
|
16
|
-
|
17
|
-
|
18
|
-
|
23
|
+
task :build => :compile
|
24
|
+
task :test => :compile
|
25
|
+
task :default => :test
|
data/brotli.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require "brotli/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "brotli"
|
@@ -9,25 +9,19 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["miyucy"]
|
10
10
|
spec.email = ["fistfvck@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
12
|
+
spec.summary = "Brotli compressor/decompressor"
|
13
|
+
spec.description = "Brotli compressor/decompressor"
|
14
14
|
spec.homepage = "https://github.com/miyucy/brotli"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
17
|
-
spec.test_files = `git ls-files -z --
|
17
|
+
spec.test_files = `git ls-files -z -- test`.split("\x0")
|
18
18
|
spec.files = `git ls-files -z`.split("\x0")
|
19
19
|
spec.files -= spec.test_files
|
20
|
-
spec.files -= [
|
21
|
-
spec.files += Dir[
|
22
|
-
spec.files += [
|
20
|
+
spec.files -= ["vendor/brotli"]
|
21
|
+
spec.files += Dir["vendor/brotli/c/{common,enc,dec,include}/**/*"]
|
22
|
+
spec.files += ["vendor/brotli/LICENSE"]
|
23
23
|
spec.bindir = "exe"
|
24
24
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
25
25
|
spec.require_paths = ["lib"]
|
26
26
|
spec.extensions = ["ext/brotli/extconf.rb"]
|
27
|
-
|
28
|
-
spec.add_development_dependency "bundler"
|
29
|
-
spec.add_development_dependency "rake"
|
30
|
-
spec.add_development_dependency "rake-compiler"
|
31
|
-
spec.add_development_dependency "rspec"
|
32
|
-
spec.add_development_dependency "rantly"
|
33
27
|
end
|
data/ext/brotli/brotli.c
CHANGED
@@ -2,20 +2,19 @@
|
|
2
2
|
|
3
3
|
#define CSTR2SYM(x) ID2SYM(rb_intern(x))
|
4
4
|
|
5
|
-
static VALUE rb_mBrotli;
|
6
5
|
static VALUE rb_eBrotli;
|
7
6
|
|
8
|
-
static void*
|
7
|
+
static inline void*
|
9
8
|
brotli_alloc(void* opaque, size_t size)
|
10
9
|
{
|
11
|
-
return
|
10
|
+
return ruby_xmalloc(size);
|
12
11
|
}
|
13
12
|
|
14
|
-
static void
|
13
|
+
static inline void
|
15
14
|
brotli_free(void* opaque, void* address)
|
16
15
|
{
|
17
16
|
if (address) {
|
18
|
-
|
17
|
+
ruby_xfree(address);
|
19
18
|
}
|
20
19
|
}
|
21
20
|
|
@@ -138,11 +137,10 @@ brotli_deflate_set_mode(BrotliEncoderState* s, VALUE value)
|
|
138
137
|
static void
|
139
138
|
brotli_deflate_set_quality(BrotliEncoderState* s, VALUE value)
|
140
139
|
{
|
141
|
-
uint32_t param;
|
142
140
|
if (NIL_P(value)) {
|
143
141
|
return;
|
144
142
|
} else {
|
145
|
-
param = NUM2INT(value);
|
143
|
+
int32_t param = NUM2INT(value);
|
146
144
|
if (0 <= param && param <= 11) {
|
147
145
|
BrotliEncoderSetParameter(s, BROTLI_PARAM_QUALITY, param);
|
148
146
|
} else {
|
@@ -154,11 +152,10 @@ brotli_deflate_set_quality(BrotliEncoderState* s, VALUE value)
|
|
154
152
|
static void
|
155
153
|
brotli_deflate_set_lgwin(BrotliEncoderState* s, VALUE value)
|
156
154
|
{
|
157
|
-
uint32_t param;
|
158
155
|
if (NIL_P(value)) {
|
159
156
|
return;
|
160
157
|
} else {
|
161
|
-
param = NUM2INT(value);
|
158
|
+
int32_t param = NUM2INT(value);
|
162
159
|
if (10 <= param && param <= 24) {
|
163
160
|
BrotliEncoderSetParameter(s, BROTLI_PARAM_LGWIN, param);
|
164
161
|
} else {
|
@@ -170,11 +167,10 @@ brotli_deflate_set_lgwin(BrotliEncoderState* s, VALUE value)
|
|
170
167
|
static void
|
171
168
|
brotli_deflate_set_lgblock(BrotliEncoderState* s, VALUE value)
|
172
169
|
{
|
173
|
-
uint32_t param;
|
174
170
|
if (NIL_P(value)) {
|
175
171
|
return;
|
176
172
|
} else {
|
177
|
-
param = NUM2INT(value);
|
173
|
+
int32_t param = NUM2INT(value);
|
178
174
|
if ((param == 0) || (16 <= param && param <= 24)) {
|
179
175
|
BrotliEncoderSetParameter(s, BROTLI_PARAM_LGBLOCK, param);
|
180
176
|
} else {
|
@@ -241,26 +237,6 @@ brotli_deflate_no_gvl(void *arg)
|
|
241
237
|
return arg;
|
242
238
|
}
|
243
239
|
|
244
|
-
/*
|
245
|
-
* call-seq:
|
246
|
-
* Brotli.deflate(str, opts=nil) -> String
|
247
|
-
* @param [String] str
|
248
|
-
* string
|
249
|
-
* @param [Hash] opts
|
250
|
-
* options
|
251
|
-
* @option opts [Symbol] :mode
|
252
|
-
* Deflate mode
|
253
|
-
* * :generic
|
254
|
-
* * :text
|
255
|
-
* * :font
|
256
|
-
* @option opts [Integer] :quality
|
257
|
-
* quality 0-11
|
258
|
-
* @option opts [Integer] :lgwin
|
259
|
-
* lgwin 10-24
|
260
|
-
* @option opts [Integer] :lgblock
|
261
|
-
* lgblock 16-24 or 0
|
262
|
-
* @return [String] Deflated string
|
263
|
-
*/
|
264
240
|
static VALUE
|
265
241
|
brotli_deflate(int argc, VALUE *argv, VALUE self)
|
266
242
|
{
|
@@ -268,6 +244,10 @@ brotli_deflate(int argc, VALUE *argv, VALUE self)
|
|
268
244
|
brotli_deflate_args_t args;
|
269
245
|
|
270
246
|
rb_scan_args(argc, argv, "11", &str, &opts);
|
247
|
+
if (NIL_P(str)) {
|
248
|
+
rb_raise(rb_eArgError, "input should not be nil");
|
249
|
+
return Qnil;
|
250
|
+
}
|
271
251
|
StringValue(str);
|
272
252
|
|
273
253
|
args.str = (uint8_t*)RSTRING_PTR(str);
|
@@ -293,6 +273,185 @@ brotli_deflate(int argc, VALUE *argv, VALUE self)
|
|
293
273
|
return value;
|
294
274
|
}
|
295
275
|
|
276
|
+
/*******************************************************************************
|
277
|
+
* version
|
278
|
+
******************************************************************************/
|
279
|
+
|
280
|
+
static VALUE brotli_version(VALUE klass) {
|
281
|
+
uint32_t ver = BrotliEncoderVersion();
|
282
|
+
char version[255];
|
283
|
+
snprintf(version, sizeof(version), "%u.%u.%u", ver >> 24, (ver >> 12) & 0xFFF, ver & 0xFFF);
|
284
|
+
return rb_str_new2(version);
|
285
|
+
}
|
286
|
+
|
287
|
+
/*******************************************************************************
|
288
|
+
* Writer
|
289
|
+
******************************************************************************/
|
290
|
+
|
291
|
+
static ID id_write, id_flush, id_close;
|
292
|
+
|
293
|
+
struct brotli {
|
294
|
+
VALUE io;
|
295
|
+
BrotliEncoderState* state;
|
296
|
+
};
|
297
|
+
|
298
|
+
static void br_mark(void *p)
|
299
|
+
{
|
300
|
+
struct brotli *br = p;
|
301
|
+
rb_gc_mark(br->io);
|
302
|
+
}
|
303
|
+
|
304
|
+
static void br_free(void *p)
|
305
|
+
{
|
306
|
+
struct brotli* br = p;
|
307
|
+
BrotliEncoderDestroyInstance(br->state);
|
308
|
+
br->state = NULL;
|
309
|
+
br->io = Qnil;
|
310
|
+
ruby_xfree(br);
|
311
|
+
}
|
312
|
+
|
313
|
+
static size_t br_memsize(const void *p)
|
314
|
+
{
|
315
|
+
return sizeof(struct brotli);
|
316
|
+
}
|
317
|
+
|
318
|
+
static const rb_data_type_t brotli_data_type = {
|
319
|
+
"brotli",
|
320
|
+
{ br_mark, br_free, br_memsize },
|
321
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
322
|
+
};
|
323
|
+
|
324
|
+
typedef struct {
|
325
|
+
BrotliEncoderState* state;
|
326
|
+
BrotliEncoderOperation op;
|
327
|
+
size_t available_in;
|
328
|
+
const uint8_t* next_in;
|
329
|
+
} brotli_encoder_args_t;
|
330
|
+
|
331
|
+
static void* compress_no_gvl(void *ptr) {
|
332
|
+
brotli_encoder_args_t *args = ptr;
|
333
|
+
size_t zero = 0;
|
334
|
+
if (!BrotliEncoderCompressStream(args->state, args->op,
|
335
|
+
&args->available_in, &args->next_in,
|
336
|
+
&zero, NULL, NULL)) {
|
337
|
+
rb_raise(rb_eBrotli, "BrotliEncoderCompressStream failed");
|
338
|
+
}
|
339
|
+
return NULL;
|
340
|
+
}
|
341
|
+
|
342
|
+
static size_t push_output(struct brotli *br) {
|
343
|
+
size_t len = 0;
|
344
|
+
if (BrotliEncoderHasMoreOutput(br->state)) {
|
345
|
+
const uint8_t* out = BrotliEncoderTakeOutput(br->state, &len);
|
346
|
+
if (len > 0) {
|
347
|
+
rb_funcall(br->io, id_write, 1, rb_str_new((const char*)out, len));
|
348
|
+
}
|
349
|
+
}
|
350
|
+
return len;
|
351
|
+
}
|
352
|
+
|
353
|
+
static VALUE rb_writer_alloc(VALUE klass) {
|
354
|
+
struct brotli *br;
|
355
|
+
VALUE obj = TypedData_Make_Struct(klass, struct brotli, &brotli_data_type, br);
|
356
|
+
br->io = Qnil;
|
357
|
+
br->state = BrotliEncoderCreateInstance(brotli_alloc, brotli_free, NULL);
|
358
|
+
if (!br->state) {
|
359
|
+
rb_raise(rb_eNoMemError, "BrotliEncoderCreateInstance failed");
|
360
|
+
return Qnil;
|
361
|
+
}
|
362
|
+
return obj;
|
363
|
+
}
|
364
|
+
|
365
|
+
static VALUE rb_writer_initialize(int argc, VALUE* argv, VALUE self) {
|
366
|
+
VALUE io = Qnil;
|
367
|
+
VALUE opts = Qnil;
|
368
|
+
rb_scan_args(argc, argv, "11", &io, &opts);
|
369
|
+
if (NIL_P(io)) {
|
370
|
+
rb_raise(rb_eArgError, "io should not be nil");
|
371
|
+
return Qnil;
|
372
|
+
}
|
373
|
+
|
374
|
+
struct brotli *br;
|
375
|
+
TypedData_Get_Struct(self, struct brotli, &brotli_data_type, br);
|
376
|
+
brotli_deflate_parse_options(br->state, opts);
|
377
|
+
br->io = io;
|
378
|
+
return self;
|
379
|
+
}
|
380
|
+
|
381
|
+
static VALUE rb_writer_write(VALUE self, VALUE buf) {
|
382
|
+
struct brotli* br;
|
383
|
+
TypedData_Get_Struct(self, struct brotli, &brotli_data_type, br);
|
384
|
+
StringValue(buf);
|
385
|
+
|
386
|
+
const size_t total = (size_t)RSTRING_LEN(buf);
|
387
|
+
|
388
|
+
brotli_encoder_args_t args = {
|
389
|
+
.state = br->state,
|
390
|
+
.op = BROTLI_OPERATION_PROCESS,
|
391
|
+
.available_in = total,
|
392
|
+
.next_in = (uint8_t*)RSTRING_PTR(buf)
|
393
|
+
};
|
394
|
+
|
395
|
+
while (args.available_in > 0) {
|
396
|
+
rb_thread_call_without_gvl(compress_no_gvl, (void*)&args, NULL, NULL);
|
397
|
+
push_output(br);
|
398
|
+
}
|
399
|
+
|
400
|
+
return SIZET2NUM(total);
|
401
|
+
}
|
402
|
+
|
403
|
+
static VALUE rb_writer_finish(VALUE self) {
|
404
|
+
struct brotli* br;
|
405
|
+
TypedData_Get_Struct(self, struct brotli, &brotli_data_type, br);
|
406
|
+
|
407
|
+
brotli_encoder_args_t args = {
|
408
|
+
.state = br->state,
|
409
|
+
.op = BROTLI_OPERATION_FINISH,
|
410
|
+
.available_in = 0,
|
411
|
+
.next_in = NULL
|
412
|
+
};
|
413
|
+
|
414
|
+
while (!BrotliEncoderIsFinished(br->state)) {
|
415
|
+
rb_thread_call_without_gvl(compress_no_gvl, (void*)&args, NULL, NULL);
|
416
|
+
push_output(br);
|
417
|
+
}
|
418
|
+
return br->io;
|
419
|
+
}
|
420
|
+
|
421
|
+
static VALUE rb_writer_flush(VALUE self) {
|
422
|
+
struct brotli *br;
|
423
|
+
TypedData_Get_Struct(self, struct brotli, &brotli_data_type, br);
|
424
|
+
|
425
|
+
brotli_encoder_args_t args = {
|
426
|
+
.state = br->state,
|
427
|
+
.op = BROTLI_OPERATION_FLUSH,
|
428
|
+
.available_in = 0,
|
429
|
+
.next_in = NULL
|
430
|
+
};
|
431
|
+
|
432
|
+
do {
|
433
|
+
rb_thread_call_without_gvl(compress_no_gvl, (void*)&args, NULL, NULL);
|
434
|
+
push_output(br);
|
435
|
+
} while (BrotliEncoderHasMoreOutput(br->state));
|
436
|
+
|
437
|
+
if (rb_respond_to(br->io, id_flush)) {
|
438
|
+
rb_funcall(br->io, id_flush, 0);
|
439
|
+
}
|
440
|
+
return self;
|
441
|
+
}
|
442
|
+
|
443
|
+
static VALUE rb_writer_close(VALUE self) {
|
444
|
+
struct brotli* br;
|
445
|
+
TypedData_Get_Struct(self, struct brotli, &brotli_data_type, br);
|
446
|
+
|
447
|
+
rb_writer_finish(self);
|
448
|
+
|
449
|
+
if (rb_respond_to(br->io, id_close)) {
|
450
|
+
rb_funcall(br->io, id_close, 0);
|
451
|
+
}
|
452
|
+
return br->io;
|
453
|
+
}
|
454
|
+
|
296
455
|
/*******************************************************************************
|
297
456
|
* entry
|
298
457
|
******************************************************************************/
|
@@ -300,8 +459,27 @@ brotli_deflate(int argc, VALUE *argv, VALUE self)
|
|
300
459
|
void
|
301
460
|
Init_brotli(void)
|
302
461
|
{
|
462
|
+
#if HAVE_RB_EXT_RACTOR_SAFE
|
463
|
+
rb_ext_ractor_safe(true);
|
464
|
+
#endif
|
465
|
+
|
466
|
+
VALUE rb_mBrotli;
|
467
|
+
VALUE rb_Writer;
|
303
468
|
rb_mBrotli = rb_define_module("Brotli");
|
304
469
|
rb_eBrotli = rb_define_class_under(rb_mBrotli, "Error", rb_eStandardError);
|
470
|
+
rb_global_variable(&rb_eBrotli);
|
305
471
|
rb_define_singleton_method(rb_mBrotli, "deflate", RUBY_METHOD_FUNC(brotli_deflate), -1);
|
306
472
|
rb_define_singleton_method(rb_mBrotli, "inflate", RUBY_METHOD_FUNC(brotli_inflate), 1);
|
473
|
+
rb_define_singleton_method(rb_mBrotli, "version", RUBY_METHOD_FUNC(brotli_version), 0);
|
474
|
+
// Brotli::Writer
|
475
|
+
id_write = rb_intern("write");
|
476
|
+
id_flush = rb_intern("flush");
|
477
|
+
id_close = rb_intern("close");
|
478
|
+
rb_Writer = rb_define_class_under(rb_mBrotli, "Writer", rb_cObject);
|
479
|
+
rb_define_alloc_func(rb_Writer, rb_writer_alloc);
|
480
|
+
rb_define_method(rb_Writer, "initialize", RUBY_METHOD_FUNC(rb_writer_initialize), -1);
|
481
|
+
rb_define_method(rb_Writer, "write", RUBY_METHOD_FUNC(rb_writer_write), 1);
|
482
|
+
rb_define_method(rb_Writer, "finish", RUBY_METHOD_FUNC(rb_writer_finish), 0);
|
483
|
+
rb_define_method(rb_Writer, "flush", RUBY_METHOD_FUNC(rb_writer_flush), 0);
|
484
|
+
rb_define_method(rb_Writer, "close", RUBY_METHOD_FUNC(rb_writer_close), 0);
|
307
485
|
}
|