Class: MultiCompress::Dictionary

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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Object



3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
# File 'ext/multi_compress/multi_compress.c', line 3167

static VALUE dict_initialize(int argc, VALUE *argv, VALUE self) {
    VALUE raw, opts;
    scan_one_required_keywords(argc, argv, &raw, &opts);
    StringValue(raw);

    mc_opts_t parsed_opts;
    mc_parse_opts(opts, &parsed_opts);
    reject_algorithm_keyword(&parsed_opts);

    dictionary_t *d;
    TypedData_Get_Struct(self, dictionary_t, &dictionary_type, d);

    VALUE algo_sym = parsed_opts.algo;
    d->algo = NIL_P(algo_sym) ? ALGO_ZSTD : sym_to_algo(algo_sym);

    if (d->algo == ALGO_LZ4)
        rb_raise(eUnsupportedError, "LZ4 does not support dictionaries");

    d->size = RSTRING_LEN(raw);
    d->data = ALLOC_N(uint8_t, d->size);
    memcpy(d->data, RSTRING_PTR(raw), d->size);

    return self;
}

Class Method Details

.load(*args) ⇒ Object



3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
# File 'ext/multi_compress/multi_compress.c', line 3281

static VALUE dict_load(int argc, VALUE *argv, VALUE self) {
    VALUE path, opts;
    scan_one_required_keywords(argc, argv, &path, &opts);
    StringValue(path);
    raise_if_path_has_null_byte(path);

    mc_opts_t parsed_opts;
    mc_parse_opts(opts, &parsed_opts);
    reject_algorithm_keyword(&parsed_opts);

    VALUE algo_sym = parsed_opts.algo;
    compress_algo_t algo = NIL_P(algo_sym) ? ALGO_ZSTD : sym_to_algo(algo_sym);

    if (algo == ALGO_LZ4)
        rb_raise(eUnsupportedError, "LZ4 does not support dictionaries");

    const char *cpath = RSTRING_PTR(path);
    FILE *f = fopen(cpath, "rb");
    if (!f)
        rb_sys_fail(cpath);

    fseek(f, 0, SEEK_END);
    long file_size = ftell(f);
    fseek(f, 0, SEEK_SET);

    if (file_size <= 0) {
        fclose(f);
        rb_raise(eDataError, "dictionary file is empty: %s", cpath);
    }
    if ((unsigned long long)file_size > DICT_FILE_MAX_SIZE) {
        fclose(f);
        rb_raise(eDataError, "dictionary file too large (%ld bytes, max=%d)", file_size,
                 (int)DICT_FILE_MAX_SIZE);
    }

    uint8_t *buf = ALLOC_N(uint8_t, file_size);
    size_t read_bytes = fread(buf, 1, file_size, f);
    fclose(f);

    if ((long)read_bytes != file_size) {
        xfree(buf);
        rb_raise(eDataError, "failed to read dictionary: %s", cpath);
    }

    VALUE dict_obj = dict_alloc(cDictionary);
    dictionary_t *d;
    TypedData_Get_Struct(dict_obj, dictionary_t, &dictionary_type, d);
    d->algo = algo;
    d->data = buf;
    d->size = (size_t)file_size;
    return dict_obj;
}

Instance Method Details

#algoObject



3351
3352
3353
3354
3355
# File 'ext/multi_compress/multi_compress.c', line 3351

static VALUE dict_algo(VALUE self) {
    dictionary_t *d;
    TypedData_Get_Struct(self, dictionary_t, &dictionary_type, d);
    return algo_to_sym(d->algo);
}

#save(path) ⇒ Object



3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
# File 'ext/multi_compress/multi_compress.c', line 3334

static VALUE dict_save(VALUE self, VALUE path) {
    dictionary_t *d;
    TypedData_Get_Struct(self, dictionary_t, &dictionary_type, d);

    const char *cpath = StringValueCStr(path);
    FILE *f = fopen(cpath, "wb");
    if (!f)
        rb_sys_fail(cpath);

    size_t written = fwrite(d->data, 1, d->size, f);
    fclose(f);

    if (written != d->size)
        rb_raise(eError, "failed to write dictionary to %s", cpath);
    return path;
}

#sizeObject



3357
3358
3359
3360
3361
# File 'ext/multi_compress/multi_compress.c', line 3357

static VALUE dict_size(VALUE self) {
    dictionary_t *d;
    TypedData_Get_Struct(self, dictionary_t, &dictionary_type, d);
    return SIZET2NUM(d->size);
}