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



2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
# File 'ext/multi_compress/multi_compress.c', line 2645

static VALUE dict_initialize(int argc, VALUE *argv, VALUE self) {
    VALUE raw, opts;
    rb_scan_args(argc, argv, "1:", &raw, &opts);
    StringValue(raw);
    reject_algorithm_keyword(opts);

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

    VALUE algo_sym = Qnil;
    if (!NIL_P(opts)) {
        algo_sym = opt_get(opts, sym_cache.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



2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
# File 'ext/multi_compress/multi_compress.c', line 2763

static VALUE dict_load(int argc, VALUE *argv, VALUE self) {
    VALUE path, opts;
    rb_scan_args(argc, argv, "1:", &path, &opts);
    StringValue(path);
    reject_algorithm_keyword(opts);
    raise_if_path_has_null_byte(path);

    VALUE algo_sym = Qnil;
    if (!NIL_P(opts)) {
        algo_sym = opt_get(opts, sym_cache.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



2833
2834
2835
2836
2837
# File 'ext/multi_compress/multi_compress.c', line 2833

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



2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
# File 'ext/multi_compress/multi_compress.c', line 2816

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



2839
2840
2841
2842
2843
# File 'ext/multi_compress/multi_compress.c', line 2839

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