brotli 0.2.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|