Module: Brotli

Defined in:
lib/brotli/version.rb,
ext/brotli/brotli.c

Defined Under Namespace

Classes: Error, Writer

Constant Summary collapse

VERSION =
'0.7.0'

Class Method Summary collapse

Class Method Details

.deflate(*args) ⇒ Object



294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
# File 'ext/brotli/brotli.c', line 294

static VALUE
brotli_deflate(int argc, VALUE *argv, VALUE self)
{
    VALUE str = Qnil, opts = Qnil, value = Qnil, dict = Qnil;
    brotli_deflate_args_t args;

    rb_scan_args(argc, argv, "11", &str, &opts);
    if (NIL_P(str)) {
        rb_raise(rb_eArgError, "input should not be nil");
        return Qnil;
    }
    StringValue(str);

    /* Extract dictionary from options if provided */
    if (!NIL_P(opts)) {
        Check_Type(opts, T_HASH);
        dict = rb_hash_aref(opts, CSTR2SYM("dictionary"));
    }

    args.str = (uint8_t*)RSTRING_PTR(str);
    args.len = (size_t)RSTRING_LEN(str);
    args.s = brotli_deflate_parse_options(
        BrotliEncoderCreateInstance(brotli_alloc, brotli_free, NULL),
        opts);
    size_t max_compressed_size = BrotliEncoderMaxCompressedSize(args.len);
    args.buffer = create_buffer(max_compressed_size);
    args.finished = BROTLI_FALSE;

    /* Set dictionary parameters */
    if (!NIL_P(dict)) {
#if defined(HAVE_BROTLIENCODERPREPAREDICTIONARY) && defined(HAVE_BROTLIENCODERATTACHPREPAREDDICTIONARY)
        StringValue(dict);
        args.dict = (uint8_t*)RSTRING_PTR(dict);
        args.dict_len = (size_t)RSTRING_LEN(dict);
#else
        rb_raise(rb_eBrotli, "Dictionary support not available in this build");
#endif
    } else {
        args.dict = NULL;
        args.dict_len = 0;
    }

#ifdef HAVE_RUBY_THREAD_H
    rb_thread_call_without_gvl(brotli_deflate_no_gvl, (void *)&args, NULL, NULL);
#else
    brotli_deflate_no_gvl((void *)&args);
#endif
    if (args.finished == BROTLI_TRUE) {
        value = rb_str_new(args.buffer->ptr, args.buffer->used);
    }

    delete_buffer(args.buffer);
    BrotliEncoderDestroyInstance(args.s);

    return value;
}

.inflate(*args) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'ext/brotli/brotli.c', line 83

static VALUE
brotli_inflate(int argc, VALUE *argv, VALUE self)
{
    VALUE str = Qnil, opts = Qnil, value = Qnil, dict = Qnil;
    brotli_inflate_args_t args;

    rb_scan_args(argc, argv, "11", &str, &opts);

    if (rb_respond_to(str, id_read)) {
      str = rb_funcall(str, id_read, 0, 0);
    }

    StringValue(str);

    /* Extract dictionary from options if provided */
    if (!NIL_P(opts)) {
        Check_Type(opts, T_HASH);
        dict = rb_hash_aref(opts, CSTR2SYM("dictionary"));
    }

    args.str = (uint8_t*)RSTRING_PTR(str);
    args.len = (size_t)RSTRING_LEN(str);
    args.buffer = create_buffer(BUFSIZ);
    args.s = BrotliDecoderCreateInstance(brotli_alloc,
                                         brotli_free,
                                         NULL);
    args.r = BROTLI_DECODER_RESULT_ERROR;

    /* Set dictionary parameters */
    if (!NIL_P(dict)) {
#ifdef HAVE_BROTLIDECODERATTACHDICTIONARY
        StringValue(dict);
        args.dict = (uint8_t*)RSTRING_PTR(dict);
        args.dict_len = (size_t)RSTRING_LEN(dict);
#else
        rb_raise(rb_eBrotli, "Dictionary support not available in this build");
#endif
    } else {
        args.dict = NULL;
        args.dict_len = 0;
    }

#ifdef HAVE_RUBY_THREAD_H
    rb_thread_call_without_gvl(brotli_inflate_no_gvl, (void *)&args, NULL, NULL);
#else
    brotli_inflate_no_gvl((void *)&args);
#endif
    if (args.r == BROTLI_DECODER_RESULT_SUCCESS) {
        value = rb_str_new(args.buffer->ptr, args.buffer->used);
        delete_buffer(args.buffer);
        BrotliDecoderDestroyInstance(args.s);
    } else if (args.r == BROTLI_DECODER_RESULT_ERROR) {
        const char * error = BrotliDecoderErrorString(BrotliDecoderGetErrorCode(args.s));
        delete_buffer(args.buffer);
        BrotliDecoderDestroyInstance(args.s);
        rb_raise(rb_eBrotli, "%s", error);
    } else if (args.r == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) {
        delete_buffer(args.buffer);
        BrotliDecoderDestroyInstance(args.s);
        rb_raise(rb_eBrotli, "Needs more input");
    } else if (args.r == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
        /* never reach to this block */
        delete_buffer(args.buffer);
        BrotliDecoderDestroyInstance(args.s);
        rb_raise(rb_eBrotli, "Needs more output");
    }

    return value;
}

.versionObject

*****************************************************************************

version

****************************************************************************



355
356
357
358
359
360
# File 'ext/brotli/brotli.c', line 355

static VALUE brotli_version(VALUE klass) {
    uint32_t ver = BrotliEncoderVersion();
    char version[255];
    snprintf(version, sizeof(version), "%u.%u.%u", ver >> 24, (ver >> 12) & 0xFFF, ver & 0xFFF);
    return rb_str_new2(version);
}