New API call burn_offst_source_new()

This commit is contained in:
2010-09-22 17:51:26 +00:00
parent f2436351ef
commit c49995b11a
8 changed files with 234 additions and 5 deletions

View File

@@ -481,10 +481,11 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
int burn_fifo_cancel(struct burn_source *source)
{
int ret;
struct burn_source_fifo *fs = source->data;
burn_source_cancel(fs->inp);
return(1);
ret = burn_source_cancel(fs->inp);
return ret;
}
/*
@@ -747,3 +748,162 @@ int burn_fifo_fill(struct burn_source *source, int bufsize, int flag)
1 | ((flag & 1) << 1));
}
/* ----------------------------- Offset source ----------------------------- */
/* ts B00922 */
static void offst_free(struct burn_source *source);
static struct burn_source_offst *offst_auth(struct burn_source *source)
{
if (source->free_data != offst_free) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002017a,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Expected offset source object as parameter",
0, 0);
return NULL;
}
return (struct burn_source_offst *) source->data;
}
static off_t offst_get_size(struct burn_source *source)
{
struct burn_source_offst *fs;
if ((fs = offst_auth(source)) == NULL)
return (off_t) 0;
return fs->size;
}
static int offst_set_size(struct burn_source *source, off_t size)
{
struct burn_source_offst *fs;
if ((fs = offst_auth(source)) == NULL)
return 0;
fs->size = size;
return 1;
}
static void offst_free(struct burn_source *source)
{
struct burn_source_offst *fs;
if ((fs = offst_auth(source)) == NULL)
return;
if (fs->prev != NULL)
offst_auth(fs->prev)->next = fs->next;
if (fs->next != NULL)
offst_auth(fs->next)->prev = fs->prev;
if (fs->inp != NULL)
burn_source_free(fs->inp); /* i.e. decrement refcount */
free(source->data);
}
static int offst_read(struct burn_source *source, unsigned char *buffer,
int size)
{
int ret, to_read, todo;
struct burn_source_offst *fs;
if ((fs = offst_auth(source)) == NULL)
return -1;
/* Eventually skip bytes up to start position */;
if (!fs->running) {
if (fs->prev != NULL)
fs->pos = offst_auth(fs->prev)->pos;
fs->running= 1;
}
if(fs->pos < fs->start) {
todo = fs->start - fs->pos;
while (todo > 0) {
to_read = todo;
if (to_read > size)
to_read = size;
ret = burn_source_read(fs->inp, buffer, to_read);
if (ret <= 0)
return ret;
todo -= ret;
fs->pos += ret;
}
}
/* Produce EOF if source size is exhausted.
burn_source delivers no incomplete sector buffers.
*/
if (fs->pos + size > fs->start + fs->size)
return 0;
/* Read payload */
ret = burn_source_read(fs->inp, buffer, size);
if (ret > 0)
fs->pos += ret;
return ret;
}
static int offst_cancel(struct burn_source *source)
{
int ret;
struct burn_source_offst *fs;
if ((fs = offst_auth(source)) == NULL)
return -1;
ret = burn_source_cancel(fs->inp);
return ret;
}
struct burn_source *burn_offst_source_new(
struct burn_source *inp, struct burn_source *prev,
off_t start, off_t size, int flag)
{
struct burn_source *src;
struct burn_source_offst *fs, *prev_fs = NULL;
if (prev != NULL)
if ((prev_fs = offst_auth(prev)) == NULL)
return NULL; /* Not type burn_source_offst */
fs = calloc(1, sizeof(struct burn_source_offst));
if (fs == NULL)
return NULL;
src = burn_source_new();
if (src == NULL) {
free((char *) fs);
return NULL;
}
src->read = NULL;
src->read_sub = NULL;
src->get_size = offst_get_size;
src->set_size = offst_set_size;
src->free_data = offst_free;
src->data = fs;
src->version= 1;
src->read_xt = offst_read;
src->cancel= offst_cancel;
fs->inp = inp;
fs->prev = prev;
fs->next = NULL;
if (prev != NULL) {
if (prev_fs->next != NULL) {
offst_auth(prev_fs->next)->prev = src;
fs->next = prev_fs->next;
}
prev_fs->next = src;
if (prev_fs->start + prev_fs->size > start) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020179,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Offset source start address is before end of previous source",
0, 0);
return NULL;
}
}
fs->start = start;
fs->size = size;
fs->running = 0;
fs->pos = 0;
inp->refcount++; /* make sure inp lives longer than src */
return src;
}