Pull to refresh

libral – слой абстракции доступа к библиотекам сжатия

Reading time 2 min
Views 1.3K
Привет Хабр! Хочу представить свою С/С++ библиотеку libral, которая с недавних пор стала open source под лицензией GPL3. Возможно кому-то она будет полезна. Библиотека предоставляет единый интерфейс к различным алгоритмам сжатия данных без потерь.
На данный момент поддерживаются библиотеки:


Данная библиотека позволяет легко переключаться между различными алгоритмами сжатия, что поможет выбрать оптимальный для задачи с минимальными изменениями кода. С ее помощью очень легко писать бенчмарки, код ниже.
Библиотека находится в стадии разработки, поэтому на стабильность рассчитывать пока не стоит.
API достаточно простой. Каждая библиотека сжатия описывается своим драйвером, имеющих единый интерфейс. На данный момент (v0.1) доступ через функции файлового ввода/вывода реализованы не для всех драйверов, пока можно уверенно пользоваться compress() / uncompress().

struct file_driver_t{ 
    fd_t *(* open)(const char *fname, int mode, void *params); 
    int (* close)(fd_t *fd); 
    off_t (* seek)(fd_t *fd, size_t offset, int whence); 
    off_t (* tell)(fd_t *fd); 
    size_t(* read)(fd_t *fd, char *buf, size_t size); 
    size_t(* write)(fd_t *fd, char *buf, size_t size); 
    int (* feof)(fd_t *fd);
    int (* ferror)(fd_t *fd);
    enum ral_status (* compress)(char *dest, size_t *destLen, const char *source, size_t sourceLen, void *param); 
    enum ral_status (* uncompress)(char *dest, size_t *destLen, const char *source, size_t sourceLen, void *param); 
};

Для выбора конкретного драйвера служит функция get_driver:
enum drivers_t {RAL_STDC, RAL_GZ, RAL_LZO, RAL_SNAPPY, RAL_BZIP, RAL_END};
struct file_driver_t *get_driver(enum drivers_t d);

Пример использования:
#include <ral.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

void fill_rand(char *buf, size_t size){ 
    // we want to fill half, to show compression 
    for(size_t i = 0; i < size / 2; i++){ 
        buf[i] = (char)rand(); 
    } 
} 

int main(){ 
    static const size_t size_small = 1000000; 
    // some drivers need more space to outbufer while compressing 
    static const size_t size_big = 2*size_small; 
    static char in[size_small]; 
    static char tmp[size_big]; 
    static char out[size_big]; 

    // you can simply change drivers here
    struct file_driver_t *dr = get_driver(RAL_BZIP); 
    if( dr == NULL || dr->compress == NULL || dr->uncompress == NULL ){ 
        fprintf(stderr, "cant get driver\n"); 
        return -1; 
    } 
    fill_rand(in, size_small); 

    size_t tmp_len = size_big; 
    if( dr->compress(tmp, &tmp_len, in, size_small, NULL) != RAL_OK ){ 
        fprintf(stderr, "compress failed\n"); 
        return -1; 
    } 
    printf("Compressed: in size: %ld out size: %ld\n", size_small, tmp_len); 

    size_t out_len = size_big; 
    if( dr->uncompress(out, &out_len, tmp, tmp_len, NULL) != RAL_OK ){ 
        fprintf(stderr, "uncompress failed\n"); 
        return -1; 
    } 
    if( out_len != size_small || 
        memcmp(in, out, size_small) != 0 ) 
    { 
        fprintf(stderr, "Input and output differs\n"); 
        return -1; 
    } else { 
        printf("Decompression ok\n"); 
    } 

    return 0; 
}

Выслушаю и приму к сведению любой трол любые замечания и предложения, особенно интересуют мнения насчет file IO API.
Страница: github.com/artemg/ral
GIt: git://github.com/artemg/ral.git
targz: github.com/downloads/artemg/ral/libral-0.1.tar.gz
Tags:
Hubs:
+31
Comments 34
Comments Comments 34

Articles