Class: Libdeflate::Decompressor

Inherits:
Object
  • Object
show all
Defined in:
ext/libdeflate/libdeflate_ext.c

Instance Method Summary collapse

Constructor Details

#initializeObject

Returns a new Libdeflate::Decompressor object.

Libdeflate::Decompressor.new #=> #<Libdeflate::Decompressor:0x007fde591a6500>


254
255
256
257
258
259
260
261
262
263
264
265
# File 'ext/libdeflate/libdeflate_ext.c', line 254

static VALUE
rb_decompressor_initialize(VALUE self)
{
    struct libdeflate_decompressor *d = libdeflate_alloc_decompressor();
    if (d == NULL) {
        rb_raise(rb_eLibdefalteError, "libdeflate_alloc_decompressor");
    }

    DATA_PTR(self) = d;

    return self;
}

Instance Method Details

#decompress(str, format = nil, outbuf = nil) ⇒ String

Decompresses the given string compressed in format. Valid values of format are DEFLATE (default), ZLIB and GZIP. If outbuf is given, the resulting uncompressed data will be written to it.

decompressor.decompress("\x01\x03\x00\xFC\xFFfoo")                                     #=> "foo"
decompressor.decompress("x\x9C\x01\x03\x00\xFC\xFFfoo\x02\x82\x01E", Libdeflate::ZLIB) #=> "foo"

outbuf = 'bar'
decompressor.decompress("\x01\x03\x00\xFC\xFFfoo", nil, outbuf) #=> "foo"
outbuf                                                          #=> "foo"

Returns:

  • (String)


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
350
351
352
353
354
355
356
357
358
359
360
361
362
# File 'ext/libdeflate/libdeflate_ext.c', line 303

static VALUE
rb_compressor_decompress(int argc, VALUE *argv, VALUE self)
{
    struct libdeflate_decompressor *d = check_decompressor(self);
    VALUE str, format, outbuf;
    enum libdeflate_result (*decompress_func)(struct libdeflate_decompressor *, const void *, size_t, void *, size_t, size_t *);
    size_t actual_out_nbytes_ret;
    enum libdeflate_result decompress_result;

    rb_scan_args(argc, argv, "12", &str, &format, &outbuf);

    StringValue(str);

    switch (NIL_P(format) ? FORMAT_DEFLATE : FIX2INT(format)) {
        case FORMAT_DEFLATE:
            decompress_func = &libdeflate_deflate_decompress;
            break;
        case FORMAT_ZLIB:
            decompress_func = &libdeflate_zlib_decompress;
            break;
        case FORMAT_GZIP:
            decompress_func = &libdeflate_gzip_decompress;
            break;
        default:
            rb_raise(rb_eLibdefalteError, "unknown compressed data format: %d", FIX2INT(format));
    }

    if (NIL_P(outbuf)) {
        outbuf = rb_str_buf_new(next_power_of_two(RSTRING_LEN(str)) << 4);
    } else {
        StringValue(outbuf);
        rb_str_modify(outbuf);
    }

    for (;;) {
        decompress_result = decompress_func(d,
                                            RSTRING_PTR(str),
                                            RSTRING_LEN(str),
                                            RSTRING_PTR(outbuf),
                                            rb_str_capacity(outbuf),
                                            &actual_out_nbytes_ret);

        if (decompress_result != LIBDEFLATE_INSUFFICIENT_SPACE) {
            break;
        }

        rb_str_modify_expand(outbuf, (rb_str_capacity(outbuf) << 1) - RSTRING_LEN(outbuf));
    }

    if (decompress_result == LIBDEFLATE_BAD_DATA) {
        rb_raise(rb_eBadDataError, "failed to decompress data");
    } else if (decompress_result != LIBDEFLATE_SUCCESS) {
        rb_raise(rb_eLibdefalteError, "failed to decompress data");
    }

    rb_str_set_len(outbuf, actual_out_nbytes_ret);
    OBJ_INFECT(outbuf, str);

    return outbuf;
}