Skip to content

Commit

Permalink
Merge branch 'in-mem-io' into ref
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasHickman committed Sep 25, 2017
1 parent 2528d03 commit 1e4c980
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 56 deletions.
116 changes: 60 additions & 56 deletions hfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,12 @@ hFILE *hfile_init_wrapper(size_t struct_size, hFILE* wrapper)

return &fp->base;
}
static const struct hFILE_backend mem_backend;

void hfile_destroy(hFILE *fp)
{
int save = errno;
if (fp) free(fp->buffer);
if (fp && fp->backend != &mem_backend) free(fp->buffer);
free(fp);
errno = save;
}
Expand Down Expand Up @@ -663,7 +664,7 @@ static hFILE *hopen_fd(const char *filename, const char *mode)

static hFILE *hpreload_fd(const char *filename, const char *mode)
{
if(!strchr(mode, 'r'))
if(mode == NULL || !strchr(mode, 'r'))
{
return NULL;
}
Expand All @@ -672,21 +673,13 @@ static hFILE *hpreload_fd(const char *filename, const char *mode)
FILE *file = fopen(filename, mode);
if (!file) goto error;

fseek(file, 0, SEEK_END);
if(fseek(file, 0, SEEK_END) != 0) goto error;
int len = ftell(file);
fseek(file, 0, SEEK_SET);

char* buffer = malloc(len);
if(buffer == NULL)
{
errno = ENOMEM;
goto error;
}
if(fread(buffer, 1, len, file) != len)
{
errno = EIO;
goto error;
}
if(buffer == NULL) goto error;
if(fread(buffer, 1, len, file) != len) goto error;

fp = (hFILE_fd *) hfile_init_fixed(sizeof (hFILE_fd), mode, buffer, len, len);
if (fp == NULL) goto error;
Expand Down Expand Up @@ -798,6 +791,16 @@ static int cmp_prefix(const char *key, const char *s)
return 0;
}

static hFILE *create_hfile_mem(char* buffer, const char* mode, size_t buf_filled, size_t buf_size)
{
hFILE_mem *fp = (hFILE_mem *) hfile_init_fixed(sizeof(hFILE_mem), mode, buffer, buf_filled, buf_size);
if (fp == NULL)
return NULL;

fp->base.backend = &mem_backend;
return &fp->base;
}

static hFILE *hopen_mem(const char *url, const char *mode)
{
size_t length, size;
Expand All @@ -821,13 +824,52 @@ static hFILE *hopen_mem(const char *url, const char *mode)
if (buffer == NULL) return NULL;
hts_decode_percent(buffer, &length, data);
}
hFILE* hf;

hFILE_mem *fp = (hFILE_mem *)
hfile_init_fixed(sizeof (hFILE_mem), mode, buffer, length, size);
if (fp == NULL) { free(buffer); return NULL; }
if(!(hf = create_hfile_mem(buffer, mode, length, size))){
free(buffer);
return NULL;
}

fp->base.backend = &mem_backend;
return &fp->base;
return hf;
}

hFILE *hopenv_mem(const char *filename, const char *mode, va_list args)
{
char* buffer = va_arg(args, char*);
size_t sz = va_arg(args, size_t);
va_end(args);

hFILE* hf;

if(!(hf = create_hfile_mem(buffer, mode, sz, sz))){
free(buffer);
return NULL;
}

return hf;
}

int hfile_mem_get_buffer(hFILE *file, char **buffer, size_t *length){
if(file->backend != &mem_backend) {
errno = EINVAL;
return -1;
}

*buffer = file->buffer;
*length = file->buffer - file->limit;

return 0;
}

int hfile_plugin_init_mem(struct hFILE_plugin *self)
{
// mem files are declared remote so they work with a tabix index
static const struct hFILE_scheme_handler handler =
{NULL, hfile_always_remote, "mem", 2000 + 50, hopenv_mem};
self->name = "mem";
hfile_add_scheme_handler("mem", &handler);
return 0;
}


Expand Down Expand Up @@ -908,44 +950,6 @@ static int init_add_plugin(void *obj, int (*init)(struct hFILE_plugin *),
return 0;
}

hFILE *hopenv_mem(const char *filename, const char *mode, va_list args)
{
char* buffer = va_arg(args, char*);
size_t sz = va_arg(args, size_t);
va_end(args);

hFILE_mem *fp = (hFILE_mem *) hfile_init_fixed(sizeof(hFILE_mem), mode, buffer, sz, sz);

fp->base.backend = &mem_backend;

return &fp->base;
}

int hfile_mem_get_buffer(hFILE *file, char **buffer, size_t *length){
if(file->is_hFILE_wrapper)
file = ((hFILE_wrapper*)file)->wrapper;

if(file->backend != &mem_backend) {
errno = EINVAL;
return -1;
}

*buffer = file->buffer;
*length = file->buffer - file->limit;

return 0;
}

int hfile_plugin_init_mem(struct hFILE_plugin *self)
{
// mem files are declared remote so they work with a tabix index
static const struct hFILE_scheme_handler handler =
{NULL, hfile_always_remote, "mem", 2000 + 50, hopenv_mem};
self->name = "mem";
hfile_add_scheme_handler("mem", &handler);
return 0;
}

static void load_hfile_plugins()
{
static const struct hFILE_scheme_handler
Expand Down
10 changes: 10 additions & 0 deletions test/hfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,13 @@ int main(void)
fail("hopen('mem:', 'r') failed read");
if(strcmp(buffer, test_string) != 0)
fail("hopen('mem:', 'r') missread '%s' != '%s'", buffer, test_string);
char* internal_buf;
size_t interval_buf_len;
if(hfile_mem_get_buffer(fin, &internal_buf, &interval_buf_len) != 0){
fail("hopen('mem:', 'r') failed to get internal buffer");
}
if (hclose(fin) != 0) fail("hclose mem for reading");
free(internal_buf);

test_string = strdup("Test string");
fin = hopen("mem:", "wr:", test_string, 12);
Expand All @@ -232,7 +238,11 @@ int main(void)
fail("hopen('mem:', 'wr') failed read");
if (strcmp(buffer, "Test string extra") != 0)
fail("hopen('mem:', 'wr') misswrote '%s' != '%s'", buffer, "Test string extra");
if(hfile_mem_get_buffer(fin, &internal_buf, &interval_buf_len) != 0){
fail("hopen('mem:', 'wr') failed to get internal buffer");
}
if (hclose(fin) != 0) fail("hclose mem for writing");
free(internal_buf);

fin = hopen("data:,hello, world!%0A", "r");
if (fin == NULL) fail("hopen(\"data:...\")");
Expand Down

0 comments on commit 1e4c980

Please sign in to comment.