brotli 0.8.0 → 0.9.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/ext/brotli/brotli.c +104 -85
- data/ext/brotli/brotli.h +0 -5
- data/ext/brotli/extconf.rb +113 -42
- data/lib/brotli/version.rb +1 -1
- metadata +5 -21
- data/.github/workflows/main.yml +0 -37
- data/.github/workflows/publish.yml +0 -24
- data/.gitignore +0 -18
- data/.gitmodules +0 -3
- data/.rspec +0 -2
- data/Dockerfile +0 -38
- data/Gemfile +0 -10
- data/Rakefile +0 -42
- data/bin/before_install.sh +0 -9
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/brotli.gemspec +0 -27
- data/smoke.sh +0 -8
- data/vendor/brotli/c/common/dictionary.bin +0 -432
- data/vendor/brotli/c/common/dictionary.bin.br +0 -0
- data/vendor/brotli/c/enc/static_init_lazy.cc +0 -26
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6e39135e3c6e289c1b4f233d8e0bec31f1cfb6be48f63280b5a7609965b88459
|
|
4
|
+
data.tar.gz: 5f0bae9eb2e35baf822e7eff9e8432e24043893afe29c70506050d41c073bbaa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 46ae27522c3cb015279531a8d6b91af3afcd40a0b61c552db76e7caa9562a547f8f4e2f09873f5e113314cbc0ffe811fcfdc9a0c02b84aa2df4ade1d005857e9
|
|
7
|
+
data.tar.gz: cc393196d928f8d761b83bf7f04415c7f1ddd1b2f113008063e9b99615004adf00af95171932d009efeeb0e6ad2f5edb3c26196610475b08a4e5db0d56e5e201
|
data/ext/brotli/brotli.c
CHANGED
|
@@ -101,13 +101,11 @@ brotli_inflate_no_gvl(void *arg)
|
|
|
101
101
|
buffer_t* buffer = args->buffer;
|
|
102
102
|
BrotliDecoderState* s = args->s;
|
|
103
103
|
|
|
104
|
-
#ifdef HAVE_BROTLIDECODERATTACHDICTIONARY
|
|
105
104
|
/* Attach dictionary if provided */
|
|
106
105
|
if (args->dict && args->dict_len > 0) {
|
|
107
106
|
BrotliDecoderAttachDictionary(s, BROTLI_SHARED_DICTIONARY_RAW,
|
|
108
107
|
args->dict_len, args->dict);
|
|
109
108
|
}
|
|
110
|
-
#endif
|
|
111
109
|
|
|
112
110
|
for (;;) {
|
|
113
111
|
r = BrotliDecoderDecompressStream(s,
|
|
@@ -133,6 +131,13 @@ brotli_inflate_no_gvl(void *arg)
|
|
|
133
131
|
return arg;
|
|
134
132
|
}
|
|
135
133
|
|
|
134
|
+
static VALUE
|
|
135
|
+
brotli_inflate_take_result(VALUE arg)
|
|
136
|
+
{
|
|
137
|
+
brotli_inflate_args_t *args = (brotli_inflate_args_t *)arg;
|
|
138
|
+
return rb_str_new(args->buffer->ptr, args->buffer->used);
|
|
139
|
+
}
|
|
140
|
+
|
|
136
141
|
static VALUE
|
|
137
142
|
brotli_inflate(int argc, VALUE *argv, VALUE self)
|
|
138
143
|
{
|
|
@@ -141,7 +146,7 @@ brotli_inflate(int argc, VALUE *argv, VALUE self)
|
|
|
141
146
|
VALUE value = Qnil;
|
|
142
147
|
VALUE dict = Qnil;
|
|
143
148
|
const char *error = NULL;
|
|
144
|
-
brotli_inflate_args_t args;
|
|
149
|
+
brotli_inflate_args_t args = {0};
|
|
145
150
|
|
|
146
151
|
(void)self;
|
|
147
152
|
|
|
@@ -153,6 +158,9 @@ brotli_inflate(int argc, VALUE *argv, VALUE self)
|
|
|
153
158
|
|
|
154
159
|
StringValue(str);
|
|
155
160
|
dict = brotli_hash_lookup(opts, id_dictionary);
|
|
161
|
+
if (!NIL_P(dict)) {
|
|
162
|
+
StringValue(dict);
|
|
163
|
+
}
|
|
156
164
|
|
|
157
165
|
args.str = (uint8_t*)RSTRING_PTR(str);
|
|
158
166
|
args.len = (size_t)RSTRING_LEN(str);
|
|
@@ -161,28 +169,24 @@ brotli_inflate(int argc, VALUE *argv, VALUE self)
|
|
|
161
169
|
args.r = BROTLI_DECODER_RESULT_ERROR;
|
|
162
170
|
|
|
163
171
|
if (!NIL_P(dict)) {
|
|
164
|
-
#ifdef HAVE_BROTLIDECODERATTACHDICTIONARY
|
|
165
|
-
StringValue(dict);
|
|
166
172
|
args.dict = (uint8_t*)RSTRING_PTR(dict);
|
|
167
173
|
args.dict_len = (size_t)RSTRING_LEN(dict);
|
|
168
|
-
#else
|
|
169
|
-
rb_raise(rb_eBrotli, "Dictionary support not available in this build");
|
|
170
|
-
#endif
|
|
171
174
|
} else {
|
|
172
175
|
args.dict = NULL;
|
|
173
176
|
args.dict_len = 0;
|
|
174
177
|
}
|
|
175
178
|
|
|
176
|
-
#ifdef HAVE_RUBY_THREAD_H
|
|
177
179
|
rb_thread_call_without_gvl(brotli_inflate_no_gvl, &args, NULL, NULL);
|
|
178
|
-
#else
|
|
179
|
-
brotli_inflate_no_gvl(&args);
|
|
180
|
-
#endif
|
|
181
180
|
RB_GC_GUARD(str);
|
|
182
181
|
RB_GC_GUARD(dict);
|
|
183
182
|
|
|
184
183
|
if (args.r == BROTLI_DECODER_RESULT_SUCCESS) {
|
|
185
|
-
|
|
184
|
+
int state = 0;
|
|
185
|
+
value = rb_protect(brotli_inflate_take_result, (VALUE)&args, &state);
|
|
186
|
+
if (state) {
|
|
187
|
+
brotli_inflate_cleanup(&args);
|
|
188
|
+
rb_jump_tag(state);
|
|
189
|
+
}
|
|
186
190
|
} else if (args.r == BROTLI_DECODER_RESULT_ERROR) {
|
|
187
191
|
error = BrotliDecoderErrorString(BrotliDecoderGetErrorCode(args.s));
|
|
188
192
|
} else if (args.r == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) {
|
|
@@ -204,11 +208,11 @@ brotli_inflate(int argc, VALUE *argv, VALUE self)
|
|
|
204
208
|
* deflate
|
|
205
209
|
******************************************************************************/
|
|
206
210
|
|
|
207
|
-
static
|
|
211
|
+
static const char *
|
|
208
212
|
brotli_deflate_set_mode(BrotliEncoderState* s, VALUE value)
|
|
209
213
|
{
|
|
210
214
|
if (NIL_P(value)) {
|
|
211
|
-
return;
|
|
215
|
+
return NULL;
|
|
212
216
|
}
|
|
213
217
|
|
|
214
218
|
if (value == ID2SYM(id_generic)) {
|
|
@@ -218,68 +222,99 @@ brotli_deflate_set_mode(BrotliEncoderState* s, VALUE value)
|
|
|
218
222
|
} else if (value == ID2SYM(id_font)) {
|
|
219
223
|
BrotliEncoderSetParameter(s, BROTLI_PARAM_MODE, BROTLI_MODE_FONT);
|
|
220
224
|
} else {
|
|
221
|
-
|
|
225
|
+
return "invalid mode";
|
|
222
226
|
}
|
|
227
|
+
|
|
228
|
+
return NULL;
|
|
223
229
|
}
|
|
224
230
|
|
|
225
|
-
static
|
|
231
|
+
static const char *
|
|
226
232
|
brotli_deflate_set_quality(BrotliEncoderState* s, VALUE value)
|
|
227
233
|
{
|
|
228
|
-
|
|
234
|
+
long param;
|
|
229
235
|
|
|
230
236
|
if (NIL_P(value)) {
|
|
231
|
-
return;
|
|
237
|
+
return NULL;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (!FIXNUM_P(value)) {
|
|
241
|
+
return "invalid quality value. Should be 0 to 11.";
|
|
232
242
|
}
|
|
233
243
|
|
|
234
|
-
param =
|
|
244
|
+
param = FIX2LONG(value);
|
|
235
245
|
if (0 <= param && param <= 11) {
|
|
236
|
-
BrotliEncoderSetParameter(s, BROTLI_PARAM_QUALITY, param);
|
|
246
|
+
BrotliEncoderSetParameter(s, BROTLI_PARAM_QUALITY, (uint32_t)param);
|
|
237
247
|
} else {
|
|
238
|
-
|
|
248
|
+
return "invalid quality value. Should be 0 to 11.";
|
|
239
249
|
}
|
|
250
|
+
|
|
251
|
+
return NULL;
|
|
240
252
|
}
|
|
241
253
|
|
|
242
|
-
static
|
|
254
|
+
static const char *
|
|
243
255
|
brotli_deflate_set_lgwin(BrotliEncoderState* s, VALUE value)
|
|
244
256
|
{
|
|
245
|
-
|
|
257
|
+
long param;
|
|
246
258
|
|
|
247
259
|
if (NIL_P(value)) {
|
|
248
|
-
return;
|
|
260
|
+
return NULL;
|
|
249
261
|
}
|
|
250
262
|
|
|
251
|
-
|
|
263
|
+
if (!FIXNUM_P(value)) {
|
|
264
|
+
return "invalid lgwin value. Should be 10 to 24.";
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
param = FIX2LONG(value);
|
|
252
268
|
if (10 <= param && param <= 24) {
|
|
253
|
-
BrotliEncoderSetParameter(s, BROTLI_PARAM_LGWIN, param);
|
|
269
|
+
BrotliEncoderSetParameter(s, BROTLI_PARAM_LGWIN, (uint32_t)param);
|
|
254
270
|
} else {
|
|
255
|
-
|
|
271
|
+
return "invalid lgwin value. Should be 10 to 24.";
|
|
256
272
|
}
|
|
273
|
+
|
|
274
|
+
return NULL;
|
|
257
275
|
}
|
|
258
276
|
|
|
259
|
-
static
|
|
277
|
+
static const char *
|
|
260
278
|
brotli_deflate_set_lgblock(BrotliEncoderState* s, VALUE value)
|
|
261
279
|
{
|
|
262
|
-
|
|
280
|
+
long param;
|
|
263
281
|
|
|
264
282
|
if (NIL_P(value)) {
|
|
265
|
-
return;
|
|
283
|
+
return NULL;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (!FIXNUM_P(value)) {
|
|
287
|
+
return "invalid lgblock value. Should be 0 or 16 to 24.";
|
|
266
288
|
}
|
|
267
289
|
|
|
268
|
-
param =
|
|
290
|
+
param = FIX2LONG(value);
|
|
269
291
|
if (param == 0 || (16 <= param && param <= 24)) {
|
|
270
|
-
BrotliEncoderSetParameter(s, BROTLI_PARAM_LGBLOCK, param);
|
|
292
|
+
BrotliEncoderSetParameter(s, BROTLI_PARAM_LGBLOCK, (uint32_t)param);
|
|
271
293
|
} else {
|
|
272
|
-
|
|
294
|
+
return "invalid lgblock value. Should be 0 or 16 to 24.";
|
|
273
295
|
}
|
|
296
|
+
|
|
297
|
+
return NULL;
|
|
274
298
|
}
|
|
275
299
|
|
|
276
|
-
static
|
|
300
|
+
static const char *
|
|
277
301
|
brotli_deflate_parse_options(BrotliEncoderState* s, VALUE opts)
|
|
278
302
|
{
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
303
|
+
const char *err;
|
|
304
|
+
|
|
305
|
+
err = brotli_deflate_set_mode(s, brotli_hash_lookup(opts, id_mode));
|
|
306
|
+
if (err) {
|
|
307
|
+
return err;
|
|
308
|
+
}
|
|
309
|
+
err = brotli_deflate_set_quality(s, brotli_hash_lookup(opts, id_quality));
|
|
310
|
+
if (err) {
|
|
311
|
+
return err;
|
|
312
|
+
}
|
|
313
|
+
err = brotli_deflate_set_lgwin(s, brotli_hash_lookup(opts, id_lgwin));
|
|
314
|
+
if (err) {
|
|
315
|
+
return err;
|
|
316
|
+
}
|
|
317
|
+
return brotli_deflate_set_lgblock(s, brotli_hash_lookup(opts, id_lgblock));
|
|
283
318
|
}
|
|
284
319
|
|
|
285
320
|
typedef struct {
|
|
@@ -288,9 +323,7 @@ typedef struct {
|
|
|
288
323
|
BrotliEncoderState* s;
|
|
289
324
|
buffer_t* buffer;
|
|
290
325
|
BROTLI_BOOL finished;
|
|
291
|
-
#if defined(HAVE_BROTLIENCODERPREPAREDICTIONARY) && defined(HAVE_BROTLIENCODERATTACHPREPAREDDICTIONARY)
|
|
292
326
|
BrotliEncoderPreparedDictionary* prepared_dict;
|
|
293
|
-
#endif
|
|
294
327
|
} brotli_deflate_args_t;
|
|
295
328
|
|
|
296
329
|
static void
|
|
@@ -302,12 +335,10 @@ brotli_deflate_cleanup(brotli_deflate_args_t* args)
|
|
|
302
335
|
BrotliEncoderDestroyInstance(args->s);
|
|
303
336
|
args->s = NULL;
|
|
304
337
|
}
|
|
305
|
-
#if defined(HAVE_BROTLIENCODERPREPAREDICTIONARY) && defined(HAVE_BROTLIENCODERATTACHPREPAREDDICTIONARY)
|
|
306
338
|
if (args->prepared_dict) {
|
|
307
339
|
BrotliEncoderDestroyPreparedDictionary(args->prepared_dict);
|
|
308
340
|
args->prepared_dict = NULL;
|
|
309
341
|
}
|
|
310
|
-
#endif
|
|
311
342
|
}
|
|
312
343
|
|
|
313
344
|
static void*
|
|
@@ -347,6 +378,13 @@ brotli_deflate_no_gvl(void *arg)
|
|
|
347
378
|
return arg;
|
|
348
379
|
}
|
|
349
380
|
|
|
381
|
+
static VALUE
|
|
382
|
+
brotli_deflate_take_result(VALUE arg)
|
|
383
|
+
{
|
|
384
|
+
brotli_deflate_args_t *args = (brotli_deflate_args_t *)arg;
|
|
385
|
+
return rb_str_new(args->buffer->ptr, args->buffer->used);
|
|
386
|
+
}
|
|
387
|
+
|
|
350
388
|
static VALUE
|
|
351
389
|
brotli_deflate(int argc, VALUE *argv, VALUE self)
|
|
352
390
|
{
|
|
@@ -354,8 +392,9 @@ brotli_deflate(int argc, VALUE *argv, VALUE self)
|
|
|
354
392
|
VALUE opts = Qnil;
|
|
355
393
|
VALUE value = Qnil;
|
|
356
394
|
VALUE dict = Qnil;
|
|
357
|
-
brotli_deflate_args_t args;
|
|
395
|
+
brotli_deflate_args_t args = {0};
|
|
358
396
|
size_t max_compressed_size;
|
|
397
|
+
const char *err;
|
|
359
398
|
|
|
360
399
|
(void)self;
|
|
361
400
|
|
|
@@ -365,21 +404,24 @@ brotli_deflate(int argc, VALUE *argv, VALUE self)
|
|
|
365
404
|
}
|
|
366
405
|
StringValue(str);
|
|
367
406
|
dict = brotli_hash_lookup(opts, id_dictionary);
|
|
407
|
+
if (!NIL_P(dict)) {
|
|
408
|
+
StringValue(dict);
|
|
409
|
+
}
|
|
368
410
|
|
|
369
411
|
args.str = (uint8_t*)RSTRING_PTR(str);
|
|
370
412
|
args.len = (size_t)RSTRING_LEN(str);
|
|
371
413
|
args.s = brotli_encoder_state_create();
|
|
372
|
-
brotli_deflate_parse_options(args.s, opts);
|
|
414
|
+
err = brotli_deflate_parse_options(args.s, opts);
|
|
415
|
+
if (err) {
|
|
416
|
+
brotli_deflate_cleanup(&args);
|
|
417
|
+
rb_raise(rb_eArgError, "%s", err);
|
|
418
|
+
}
|
|
373
419
|
max_compressed_size = BrotliEncoderMaxCompressedSize(args.len);
|
|
374
420
|
args.buffer = create_buffer(max_compressed_size);
|
|
375
421
|
args.finished = BROTLI_FALSE;
|
|
376
422
|
|
|
377
|
-
#if defined(HAVE_BROTLIENCODERPREPAREDICTIONARY) && defined(HAVE_BROTLIENCODERATTACHPREPAREDDICTIONARY)
|
|
378
423
|
args.prepared_dict = NULL;
|
|
379
|
-
#endif
|
|
380
424
|
if (!NIL_P(dict)) {
|
|
381
|
-
#if defined(HAVE_BROTLIENCODERPREPAREDICTIONARY) && defined(HAVE_BROTLIENCODERATTACHPREPAREDDICTIONARY)
|
|
382
|
-
StringValue(dict);
|
|
383
425
|
args.prepared_dict = BrotliEncoderPrepareDictionary(
|
|
384
426
|
BROTLI_SHARED_DICTIONARY_RAW,
|
|
385
427
|
(size_t)RSTRING_LEN(dict),
|
|
@@ -396,21 +438,18 @@ brotli_deflate(int argc, VALUE *argv, VALUE self)
|
|
|
396
438
|
brotli_deflate_cleanup(&args);
|
|
397
439
|
rb_raise(rb_eBrotli, "Failed to attach dictionary for compression");
|
|
398
440
|
}
|
|
399
|
-
#else
|
|
400
|
-
brotli_deflate_cleanup(&args);
|
|
401
|
-
rb_raise(rb_eBrotli, "Dictionary support not available in this build");
|
|
402
|
-
#endif
|
|
403
441
|
}
|
|
404
442
|
|
|
405
|
-
#ifdef HAVE_RUBY_THREAD_H
|
|
406
443
|
rb_thread_call_without_gvl(brotli_deflate_no_gvl, &args, NULL, NULL);
|
|
407
|
-
#else
|
|
408
|
-
brotli_deflate_no_gvl(&args);
|
|
409
|
-
#endif
|
|
410
444
|
RB_GC_GUARD(str);
|
|
411
445
|
RB_GC_GUARD(dict);
|
|
412
446
|
if (args.finished == BROTLI_TRUE) {
|
|
413
|
-
|
|
447
|
+
int state = 0;
|
|
448
|
+
value = rb_protect(brotli_deflate_take_result, (VALUE)&args, &state);
|
|
449
|
+
if (state) {
|
|
450
|
+
brotli_deflate_cleanup(&args);
|
|
451
|
+
rb_jump_tag(state);
|
|
452
|
+
}
|
|
414
453
|
}
|
|
415
454
|
|
|
416
455
|
brotli_deflate_cleanup(&args);
|
|
@@ -432,7 +471,7 @@ static VALUE brotli_version(VALUE klass) {
|
|
|
432
471
|
|
|
433
472
|
(void)klass;
|
|
434
473
|
snprintf(version, sizeof(version), "%u.%u.%u", ver >> 24, (ver >> 12) & 0xFFF, ver & 0xFFF);
|
|
435
|
-
return
|
|
474
|
+
return rb_str_new_cstr(version);
|
|
436
475
|
}
|
|
437
476
|
|
|
438
477
|
/*******************************************************************************
|
|
@@ -462,9 +501,7 @@ brotli_copy_string_data(VALUE string, size_t* len)
|
|
|
462
501
|
|
|
463
502
|
typedef struct {
|
|
464
503
|
BrotliEncoderState* state;
|
|
465
|
-
#if defined(HAVE_BROTLIENCODERPREPAREDICTIONARY) && defined(HAVE_BROTLIENCODERATTACHPREPAREDDICTIONARY)
|
|
466
504
|
BrotliEncoderPreparedDictionary* prepared_dict;
|
|
467
|
-
#endif
|
|
468
505
|
uint8_t* dict_data;
|
|
469
506
|
size_t dict_len;
|
|
470
507
|
BROTLI_BOOL finished;
|
|
@@ -523,21 +560,13 @@ static void* decompress_no_gvl(void *ptr) {
|
|
|
523
560
|
static void
|
|
524
561
|
brotli_encoder_step(brotli_encoder_args_t *args)
|
|
525
562
|
{
|
|
526
|
-
#ifdef HAVE_RUBY_THREAD_H
|
|
527
563
|
rb_thread_call_without_gvl(compress_no_gvl, (void*)args, NULL, NULL);
|
|
528
|
-
#else
|
|
529
|
-
compress_no_gvl((void*)args);
|
|
530
|
-
#endif
|
|
531
564
|
}
|
|
532
565
|
|
|
533
566
|
static void
|
|
534
567
|
brotli_decompressor_step(brotli_decoder_args_t *args)
|
|
535
568
|
{
|
|
536
|
-
#ifdef HAVE_RUBY_THREAD_H
|
|
537
569
|
rb_thread_call_without_gvl(decompress_no_gvl, (void*)args, NULL, NULL);
|
|
538
|
-
#else
|
|
539
|
-
decompress_no_gvl((void*)args);
|
|
540
|
-
#endif
|
|
541
570
|
}
|
|
542
571
|
|
|
543
572
|
static void
|
|
@@ -547,12 +576,10 @@ brotli_encoder_destroy(brotli_encoder_t* encoder)
|
|
|
547
576
|
BrotliEncoderDestroyInstance(encoder->state);
|
|
548
577
|
encoder->state = NULL;
|
|
549
578
|
}
|
|
550
|
-
#if defined(HAVE_BROTLIENCODERPREPAREDICTIONARY) && defined(HAVE_BROTLIENCODERATTACHPREPAREDDICTIONARY)
|
|
551
579
|
if (encoder->prepared_dict) {
|
|
552
580
|
BrotliEncoderDestroyPreparedDictionary(encoder->prepared_dict);
|
|
553
581
|
encoder->prepared_dict = NULL;
|
|
554
582
|
}
|
|
555
|
-
#endif
|
|
556
583
|
brotli_free(NULL, encoder->dict_data);
|
|
557
584
|
encoder->dict_data = NULL;
|
|
558
585
|
encoder->dict_len = 0;
|
|
@@ -587,7 +614,6 @@ brotli_encoder_attach_dictionary(brotli_encoder_t* encoder, VALUE opts)
|
|
|
587
614
|
return;
|
|
588
615
|
}
|
|
589
616
|
|
|
590
|
-
#if defined(HAVE_BROTLIENCODERPREPAREDICTIONARY) && defined(HAVE_BROTLIENCODERATTACHPREPAREDDICTIONARY)
|
|
591
617
|
encoder->dict_data = brotli_copy_string_data(dict, &encoder->dict_len);
|
|
592
618
|
encoder->prepared_dict = BrotliEncoderPrepareDictionary(
|
|
593
619
|
BROTLI_SHARED_DICTIONARY_RAW,
|
|
@@ -613,9 +639,6 @@ brotli_encoder_attach_dictionary(brotli_encoder_t* encoder, VALUE opts)
|
|
|
613
639
|
encoder->dict_len = 0;
|
|
614
640
|
rb_raise(rb_eBrotli, "Failed to attach dictionary for compression");
|
|
615
641
|
}
|
|
616
|
-
#else
|
|
617
|
-
rb_raise(rb_eBrotli, "Dictionary support not available in this build");
|
|
618
|
-
#endif
|
|
619
642
|
}
|
|
620
643
|
|
|
621
644
|
static VALUE
|
|
@@ -684,7 +707,7 @@ brotli_compressor_memsize(const void *p)
|
|
|
684
707
|
static const rb_data_type_t brotli_compressor_data_type = {
|
|
685
708
|
"brotli_compressor",
|
|
686
709
|
{ 0, brotli_compressor_free, brotli_compressor_memsize },
|
|
687
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
|
710
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
|
688
711
|
};
|
|
689
712
|
|
|
690
713
|
static VALUE
|
|
@@ -693,9 +716,7 @@ rb_compressor_alloc(VALUE klass)
|
|
|
693
716
|
brotli_compressor_t *br;
|
|
694
717
|
VALUE obj = TypedData_Make_Struct(klass, brotli_compressor_t, &brotli_compressor_data_type, br);
|
|
695
718
|
br->encoder.state = NULL;
|
|
696
|
-
#if defined(HAVE_BROTLIENCODERPREPAREDICTIONARY) && defined(HAVE_BROTLIENCODERATTACHPREPAREDDICTIONARY)
|
|
697
719
|
br->encoder.prepared_dict = NULL;
|
|
698
|
-
#endif
|
|
699
720
|
br->encoder.dict_data = NULL;
|
|
700
721
|
br->encoder.dict_len = 0;
|
|
701
722
|
br->encoder.finished = BROTLI_FALSE;
|
|
@@ -715,12 +736,16 @@ rb_compressor_initialize(int argc, VALUE* argv, VALUE self)
|
|
|
715
736
|
{
|
|
716
737
|
VALUE opts = Qnil;
|
|
717
738
|
brotli_compressor_t *br;
|
|
739
|
+
const char *err;
|
|
718
740
|
|
|
719
741
|
rb_scan_args(argc, argv, "01", &opts);
|
|
720
742
|
|
|
721
743
|
TypedData_Get_Struct(self, brotli_compressor_t, &brotli_compressor_data_type, br);
|
|
722
744
|
brotli_encoder_reset(&br->encoder);
|
|
723
|
-
brotli_deflate_parse_options(br->encoder.state, opts);
|
|
745
|
+
err = brotli_deflate_parse_options(br->encoder.state, opts);
|
|
746
|
+
if (err) {
|
|
747
|
+
rb_raise(rb_eArgError, "%s", err);
|
|
748
|
+
}
|
|
724
749
|
brotli_encoder_attach_dictionary(&br->encoder, opts);
|
|
725
750
|
|
|
726
751
|
return self;
|
|
@@ -896,7 +921,6 @@ brotli_decompressor_attach_dictionary(brotli_decompressor_t* br, VALUE opts)
|
|
|
896
921
|
return;
|
|
897
922
|
}
|
|
898
923
|
|
|
899
|
-
#ifdef HAVE_BROTLIDECODERATTACHDICTIONARY
|
|
900
924
|
br->dict_data = brotli_copy_string_data(dict, &br->dict_len);
|
|
901
925
|
if (!BrotliDecoderAttachDictionary(br->state,
|
|
902
926
|
BROTLI_SHARED_DICTIONARY_RAW,
|
|
@@ -907,9 +931,6 @@ brotli_decompressor_attach_dictionary(brotli_decompressor_t* br, VALUE opts)
|
|
|
907
931
|
br->dict_len = 0;
|
|
908
932
|
rb_raise(rb_eBrotli, "Failed to attach dictionary for decompression");
|
|
909
933
|
}
|
|
910
|
-
#else
|
|
911
|
-
rb_raise(rb_eBrotli, "Dictionary support not available in this build");
|
|
912
|
-
#endif
|
|
913
934
|
}
|
|
914
935
|
|
|
915
936
|
static VALUE
|
|
@@ -1156,9 +1177,7 @@ rb_decompressor_unused_data(VALUE self)
|
|
|
1156
1177
|
void
|
|
1157
1178
|
Init_brotli(void)
|
|
1158
1179
|
{
|
|
1159
|
-
#if HAVE_RB_EXT_RACTOR_SAFE
|
|
1160
1180
|
rb_ext_ractor_safe(true);
|
|
1161
|
-
#endif
|
|
1162
1181
|
|
|
1163
1182
|
VALUE rb_mBrotli;
|
|
1164
1183
|
rb_mBrotli = rb_define_module("Brotli");
|
data/ext/brotli/brotli.h
CHANGED
|
@@ -3,16 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
#include "ruby.h"
|
|
5
5
|
|
|
6
|
-
// ruby/thread.h is ruby 2.x
|
|
7
|
-
#ifdef HAVE_RUBY_THREAD_H
|
|
8
6
|
#include "ruby/thread.h"
|
|
9
|
-
#endif
|
|
10
7
|
|
|
11
8
|
#include "brotli/encode.h"
|
|
12
9
|
#include "brotli/decode.h"
|
|
13
|
-
#ifdef HAVE_BROTLI_SHARED_DICTIONARY_H
|
|
14
10
|
#include "brotli/shared_dictionary.h"
|
|
15
|
-
#endif
|
|
16
11
|
#include "buffer.h"
|
|
17
12
|
|
|
18
13
|
#endif /* BROTLI_H */
|
data/ext/brotli/extconf.rb
CHANGED
|
@@ -1,60 +1,131 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "mkmf"
|
|
2
4
|
require "fileutils"
|
|
3
5
|
require "rbconfig"
|
|
6
|
+
require "rubygems/version"
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
VENDORED_DIRS = %w[common dec enc include].freeze
|
|
9
|
+
MINIMUM_BROTLI_VERSION = Gem::Version.new("1.2.0")
|
|
10
|
+
BUILD_DIR = Dir.pwd
|
|
11
|
+
VENDORED_SOURCE_DIR = File.expand_path("../../vendor/brotli/c", __dir__)
|
|
7
12
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
have_header("brotli/decode.h"),
|
|
11
|
-
have_header("brotli/encode.h"),
|
|
12
|
-
pkg_config("libbrotlicommon"),
|
|
13
|
-
pkg_config("libbrotlidec"),
|
|
14
|
-
pkg_config("libbrotlienc")
|
|
15
|
-
].all? { |e| e }
|
|
16
|
-
|
|
17
|
-
have_header("brotli/shared_dictionary.h")
|
|
18
|
-
have_func("BrotliEncoderPrepareDictionary", "brotli/encode.h")
|
|
19
|
-
have_func("BrotliEncoderAttachPreparedDictionary", "brotli/encode.h")
|
|
20
|
-
have_func("BrotliDecoderAttachDictionary", "brotli/decode.h")
|
|
21
|
-
|
|
22
|
-
if enable_config("vendor")
|
|
23
|
-
have_dev_pkg = false
|
|
24
|
-
Logging::message "Use vendor brotli\n"
|
|
25
|
-
$defs << "-DHAVE_BROTLI_SHARED_DICTIONARY_H"
|
|
26
|
-
$defs << "-DHAVE_BROTLIENCODERPREPAREDICTIONARY"
|
|
27
|
-
$defs << "-DHAVE_BROTLIENCODERATTACHPREPAREDDICTIONARY"
|
|
28
|
-
$defs << "-DHAVE_BROTLIDECODERATTACHDICTIONARY"
|
|
13
|
+
def generated_vendored_dirs
|
|
14
|
+
VENDORED_DIRS.map { |dirname| File.join(BUILD_DIR, dirname) }
|
|
29
15
|
end
|
|
30
16
|
|
|
31
|
-
|
|
32
|
-
|
|
17
|
+
def remove_generated_vendored_dirs
|
|
18
|
+
generated_vendored_dirs.each { |path| FileUtils.rm_rf(path) }
|
|
19
|
+
end
|
|
33
20
|
|
|
34
|
-
|
|
21
|
+
def copy_vendored_sources
|
|
22
|
+
sources = Dir[File.join(VENDORED_SOURCE_DIR, "{common,dec,enc,include}", "**", "*.{c,h}")].sort
|
|
35
23
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
24
|
+
if sources.empty?
|
|
25
|
+
abort "ERROR: Vendored Brotli sources not found at #{VENDORED_SOURCE_DIR}.\n" \
|
|
26
|
+
"Install system libbrotli-dev >= #{MINIMUM_BROTLI_VERSION} or ensure vendor sources are present."
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
sources.each do |source|
|
|
30
|
+
relative_path = source.delete_prefix("#{VENDORED_SOURCE_DIR}/")
|
|
31
|
+
destination = File.join(BUILD_DIR, relative_path)
|
|
40
32
|
|
|
41
|
-
|
|
42
|
-
FileUtils.
|
|
43
|
-
FileUtils.mkdir_p dirname
|
|
44
|
-
FileUtils.cp_r(File.join(vendor_dir, dirname), ext_dir)
|
|
33
|
+
FileUtils.mkdir_p(File.dirname(destination))
|
|
34
|
+
FileUtils.cp(source, destination)
|
|
45
35
|
end
|
|
36
|
+
end
|
|
46
37
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
file["#{ext_dir}#{File::SEPARATOR}"] = ""
|
|
51
|
-
srcs << file
|
|
52
|
-
objs << file.sub(/\.c\z/, ".#{objext}")
|
|
38
|
+
def vendored_source_files
|
|
39
|
+
Dir[File.join(BUILD_DIR, "{common,dec,enc,include}", "**", "*.c")].sort.map do |path|
|
|
40
|
+
path.delete_prefix("#{BUILD_DIR}/")
|
|
53
41
|
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def add_vendored_sources_to_makefile
|
|
45
|
+
objext = RbConfig::CONFIG["OBJEXT"]
|
|
46
|
+
source_files = vendored_source_files
|
|
47
|
+
object_files = source_files.map { |path| path.sub(/\.c\z/, ".#{objext}") }
|
|
54
48
|
|
|
55
49
|
makefile = File.read("Makefile")
|
|
56
50
|
makefile = makefile
|
|
57
|
-
.sub(/^ORIG_SRCS = .*$/, "ORIG_SRCS = brotli.c buffer.c #{
|
|
58
|
-
.sub(/^OBJS = .*$/, "OBJS = brotli.#{objext} buffer.#{objext} #{
|
|
51
|
+
.sub(/^ORIG_SRCS = .*$/, "ORIG_SRCS = brotli.c buffer.c #{source_files.join(" ")}")
|
|
52
|
+
.sub(/^OBJS = .*$/, "OBJS = brotli.#{objext} buffer.#{objext} #{object_files.join(" ")}")
|
|
59
53
|
File.write("Makefile", makefile)
|
|
60
54
|
end
|
|
55
|
+
|
|
56
|
+
def mkmf_flags
|
|
57
|
+
{
|
|
58
|
+
cflags: $CFLAGS.dup,
|
|
59
|
+
cxxflags: $CXXFLAGS.dup,
|
|
60
|
+
cppflags: $CPPFLAGS.dup,
|
|
61
|
+
defs: $defs.dup,
|
|
62
|
+
incflags: $INCFLAGS.dup,
|
|
63
|
+
ldflags: $LDFLAGS.dup,
|
|
64
|
+
libs: $libs.dup,
|
|
65
|
+
local_libs: $LOCAL_LIBS.dup
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def restore_mkmf_flags(flags)
|
|
70
|
+
$CFLAGS = flags[:cflags]
|
|
71
|
+
$CXXFLAGS = flags[:cxxflags]
|
|
72
|
+
$CPPFLAGS = flags[:cppflags]
|
|
73
|
+
$defs = flags[:defs]
|
|
74
|
+
$INCFLAGS = flags[:incflags]
|
|
75
|
+
$LDFLAGS = flags[:ldflags]
|
|
76
|
+
$libs = flags[:libs]
|
|
77
|
+
$LOCAL_LIBS = flags[:local_libs]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def system_brotli_version
|
|
81
|
+
version = pkg_config("libbrotlicommon", "modversion")
|
|
82
|
+
Gem::Version.new(version) if version
|
|
83
|
+
rescue ArgumentError
|
|
84
|
+
nil
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def system_brotli_available?
|
|
88
|
+
flags = mkmf_flags
|
|
89
|
+
version = system_brotli_version
|
|
90
|
+
|
|
91
|
+
unless version && version >= MINIMUM_BROTLI_VERSION
|
|
92
|
+
Logging.message(
|
|
93
|
+
"System Brotli version %s is too old; need >= %s\n",
|
|
94
|
+
version || "unknown",
|
|
95
|
+
MINIMUM_BROTLI_VERSION
|
|
96
|
+
)
|
|
97
|
+
restore_mkmf_flags(flags)
|
|
98
|
+
return false
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
available = pkg_config("libbrotlicommon") &&
|
|
102
|
+
pkg_config("libbrotlidec") &&
|
|
103
|
+
pkg_config("libbrotlienc") &&
|
|
104
|
+
have_header("brotli/decode.h") &&
|
|
105
|
+
have_header("brotli/encode.h") &&
|
|
106
|
+
have_header("brotli/shared_dictionary.h") &&
|
|
107
|
+
have_func("BrotliEncoderPrepareDictionary", "brotli/encode.h") &&
|
|
108
|
+
have_func("BrotliEncoderAttachPreparedDictionary", "brotli/encode.h") &&
|
|
109
|
+
have_func("BrotliDecoderAttachDictionary", "brotli/decode.h")
|
|
110
|
+
|
|
111
|
+
restore_mkmf_flags(flags) unless available
|
|
112
|
+
available
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
dir_config("brotli")
|
|
116
|
+
have_func("rb_gc_mark_movable")
|
|
117
|
+
|
|
118
|
+
$CPPFLAGS << " -DOS_MACOSX" if RbConfig::CONFIG["host_os"] =~ /darwin|mac os/
|
|
119
|
+
|
|
120
|
+
remove_generated_vendored_dirs
|
|
121
|
+
|
|
122
|
+
use_vendored_brotli = enable_config("vendor", false) || !system_brotli_available?
|
|
123
|
+
|
|
124
|
+
if use_vendored_brotli
|
|
125
|
+
Logging.message "Using vendored Brotli sources\n"
|
|
126
|
+
copy_vendored_sources
|
|
127
|
+
$INCFLAGS << " -Ienc -Idec -Icommon -Iinclude"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
create_makefile("brotli/brotli")
|
|
131
|
+
add_vendored_sources_to_makefile if use_vendored_brotli
|
data/lib/brotli/version.rb
CHANGED