2022-06-18 19:17:31 +02:00
|
|
|
#include "source.h"
|
|
|
|
#include <stdlib.h>
|
2022-06-19 23:50:08 +02:00
|
|
|
#include <string.h>
|
|
|
|
#include <gint/defs/util.h>
|
2022-06-18 19:17:31 +02:00
|
|
|
|
2022-06-19 23:50:08 +02:00
|
|
|
source_t *source_open(source_intf_t *intf, void *cookie, char const *origin)
|
2022-06-18 19:17:31 +02:00
|
|
|
{
|
2022-06-19 23:50:08 +02:00
|
|
|
source_t *s = calloc(1, sizeof *s);
|
|
|
|
if(!s) goto fail;
|
|
|
|
|
|
|
|
s->origin = strdup(origin);
|
|
|
|
if(!s->origin) goto fail;
|
|
|
|
|
|
|
|
s->buf = buffer_create(0, 1024);
|
|
|
|
if(!s->buf) goto fail;
|
|
|
|
|
|
|
|
s->intf = intf;
|
|
|
|
s->cookie = cookie;
|
|
|
|
return s;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
source_free(s);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t source_size(source_t *s)
|
|
|
|
{
|
|
|
|
return s && s->intf && s->intf->size ? s->intf->size(s->cookie) : 0;
|
2022-06-18 19:17:31 +02:00
|
|
|
}
|
|
|
|
|
2022-06-19 23:50:08 +02:00
|
|
|
ssize_t source_load(source_t *s, off_t offset, size_t segment_size)
|
2022-06-18 19:17:31 +02:00
|
|
|
{
|
2022-06-21 22:24:27 +02:00
|
|
|
if(!s || !buffer_resize(s->buf, segment_size))
|
|
|
|
return -1;
|
2022-06-18 19:17:31 +02:00
|
|
|
|
|
|
|
s->buf_offset = offset;
|
2022-06-19 23:50:08 +02:00
|
|
|
ssize_t rc = s->intf->read(s->cookie, s->buf->mem, offset, segment_size);
|
|
|
|
|
|
|
|
if(rc < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
s->buf->data_size = rc;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool source_ensure_loaded(source_t *s, off_t offset, int n)
|
|
|
|
{
|
|
|
|
if(!s)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if(offset >= s->buf_offset &&
|
|
|
|
offset + n <= (int)(s->buf_offset + s->buf->data_size))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int s_size = source_size(s);
|
|
|
|
int max_offset = max(s_size - n, 0);
|
|
|
|
|
|
|
|
/* Load 1 block before the current position, 1 after */
|
|
|
|
off_t new_s_offset = offset - s->buf->block_size;
|
|
|
|
new_s_offset = max(0, min(new_s_offset, max_offset));
|
|
|
|
|
|
|
|
/* Use 2 blocks of buffer by default */
|
|
|
|
source_load(s, new_s_offset, 2 * s->buf->block_size);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void source_free(source_t *s)
|
|
|
|
{
|
|
|
|
if(!s)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(s->intf && s->cookie)
|
|
|
|
s->intf->close(s->cookie);
|
|
|
|
|
|
|
|
free(s->origin);
|
|
|
|
free(s);
|
2022-06-18 19:17:31 +02:00
|
|
|
}
|