Improve/add streamfile custom IO (subfiles, decryption, etc)

Adds some special streamfiles that do custom IO, meant to be chained
together.
This commit is contained in:
bnnm 2018-01-20 00:54:08 +01:00
parent 23998b0b97
commit dfbeee2cf3

View File

@ -247,6 +247,192 @@ STREAMFILE * open_stdio_streamfile_by_file(FILE * file, const char * filename) {
return open_stdio_streamfile_buffer_by_file(file,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
}
/* **************************************************** */
//todo stream_index: copy? pass? funtion? external?
typedef struct {
STREAMFILE sf;
STREAMFILE *inner_sf;
} WRAP_STREAMFILE;
static size_t wrap_read(WRAP_STREAMFILE *streamfile, uint8_t * dest, off_t offset, size_t length) {
return streamfile->inner_sf->read(streamfile->inner_sf, dest, offset, length); /* default */
}
static size_t wrap_get_size(WRAP_STREAMFILE * streamfile) {
return streamfile->inner_sf->get_size(streamfile->inner_sf); /* default */
}
static size_t wrap_get_offset(WRAP_STREAMFILE * streamfile) {
return streamfile->inner_sf->get_offset(streamfile->inner_sf); /* default */
}
static void wrap_get_name(WRAP_STREAMFILE *streamfile, char *buffer, size_t length) {
streamfile->inner_sf->get_name(streamfile->inner_sf, buffer, length); /* default */
}
static void wrap_get_realname(WRAP_STREAMFILE *streamfile, char *buffer, size_t length) {
streamfile->inner_sf->get_realname(streamfile->inner_sf, buffer, length); /* default */
}
static void wrap_open(WRAP_STREAMFILE *streamfile, const char * const filename, size_t buffersize) {
streamfile->inner_sf->open(streamfile->inner_sf, filename, buffersize); /* default (don't wrap) */
}
static void wrap_close(WRAP_STREAMFILE *streamfile) {
//streamfile->inner_sf->close(streamfile->inner_sf); /* don't close */
free(streamfile);
}
STREAMFILE *open_wrap_streamfile(STREAMFILE *streamfile) {
WRAP_STREAMFILE *this_sf;
if (!streamfile) return NULL;
this_sf = calloc(1,sizeof(WRAP_STREAMFILE));
if (!this_sf) return NULL;
/* set callbacks and internals */
this_sf->sf.read = (void*)wrap_read;
this_sf->sf.get_size = (void*)wrap_get_size;
this_sf->sf.get_offset = (void*)wrap_get_offset;
this_sf->sf.get_name = (void*)wrap_get_name;
this_sf->sf.get_realname = (void*)wrap_get_realname;
this_sf->sf.open = (void*)wrap_open;
this_sf->sf.close = (void*)wrap_close;
this_sf->sf.stream_index = streamfile->stream_index;
this_sf->inner_sf = streamfile;
return &this_sf->sf;
}
/* **************************************************** */
typedef struct {
STREAMFILE sf;
STREAMFILE *inner_sf;
off_t start;
size_t size;
} CLAMP_STREAMFILE;
static size_t clamp_read(CLAMP_STREAMFILE *streamfile, uint8_t *dest, off_t offset, size_t length) {
off_t inner_offset = streamfile->start + offset;
size_t clamp_length = length > (streamfile->size - offset) ? (streamfile->size - offset) : length;
return streamfile->inner_sf->read(streamfile->inner_sf, dest, inner_offset, clamp_length);
}
static size_t clamp_get_size(CLAMP_STREAMFILE *streamfile) {
return streamfile->size;
}
static off_t clamp_get_offset(CLAMP_STREAMFILE *streamfile) {
return streamfile->inner_sf->get_offset(streamfile->inner_sf) - streamfile->start;
}
static void clamp_get_name(CLAMP_STREAMFILE *streamfile, char *buffer, size_t length) {
streamfile->inner_sf->get_name(streamfile->inner_sf, buffer, length); /* default */
}
static void clamp_get_realname(CLAMP_STREAMFILE *streamfile, char *buffer, size_t length) {
streamfile->inner_sf->get_realname(streamfile->inner_sf, buffer, length); /* default */
}
static STREAMFILE *clamp_open(CLAMP_STREAMFILE *streamfile, const char * const filename, size_t buffersize) {
STREAMFILE *new_inner_sf = streamfile->inner_sf->open(streamfile->inner_sf,filename,buffersize);
return open_clamp_streamfile(new_inner_sf, streamfile->start, streamfile->size);
}
static void clamp_close(CLAMP_STREAMFILE *streamfile) {
streamfile->inner_sf->close(streamfile->inner_sf);
free(streamfile);
}
STREAMFILE *open_clamp_streamfile(STREAMFILE *streamfile, off_t start, size_t size) {
CLAMP_STREAMFILE *this_sf;
if (!streamfile || !size || start > size) return NULL;
this_sf = calloc(1,sizeof(CLAMP_STREAMFILE));
if (!this_sf) return NULL;
/* set callbacks and internals */
this_sf->sf.read = (void*)clamp_read;
this_sf->sf.get_size = (void*)clamp_get_size;
this_sf->sf.get_offset = (void*)clamp_get_offset;
this_sf->sf.get_name = (void*)clamp_get_name;
this_sf->sf.get_realname = (void*)clamp_get_realname;
this_sf->sf.open = (void*)clamp_open;
this_sf->sf.close = (void*)clamp_close;
this_sf->sf.stream_index = streamfile->stream_index;
this_sf->inner_sf = streamfile;
this_sf->start = start;
this_sf->size = size;
return &this_sf->sf;
}
/* **************************************************** */
typedef struct {
STREAMFILE sf;
STREAMFILE *inner_sf;
void* data;
size_t data_size;
size_t (*read_callback)(STREAMFILE *, uint8_t *, off_t, size_t, void*);
} IO_STREAMFILE;
static size_t io_read(IO_STREAMFILE *streamfile, uint8_t *dest, off_t offset, size_t length) {
return streamfile->read_callback(streamfile->inner_sf, dest, offset, length, streamfile->data);
}
static size_t io_get_size(IO_STREAMFILE *streamfile) {
return streamfile->inner_sf->get_size(streamfile->inner_sf); /* default */
}
static off_t io_get_offset(IO_STREAMFILE *streamfile) {
return streamfile->inner_sf->get_offset(streamfile->inner_sf); /* default */
}
static void io_get_name(IO_STREAMFILE *streamfile, char *buffer, size_t length) {
streamfile->inner_sf->get_name(streamfile->inner_sf, buffer, length); /* default */
}
static void io_get_realname(IO_STREAMFILE *streamfile, char *buffer, size_t length) {
streamfile->inner_sf->get_realname(streamfile->inner_sf, buffer, length); /* default */
}
static STREAMFILE *io_open(IO_STREAMFILE *streamfile, const char * const filename, size_t buffersize) {
STREAMFILE *new_inner_sf = streamfile->inner_sf->open(streamfile->inner_sf,filename,buffersize);
return open_io_streamfile(new_inner_sf, streamfile->data, streamfile->data_size, streamfile->read_callback);
}
static void io_close(IO_STREAMFILE *streamfile) {
streamfile->inner_sf->close(streamfile->inner_sf);
free(streamfile->data);
free(streamfile);
}
STREAMFILE *open_io_streamfile(STREAMFILE *streamfile, void* data, size_t data_size, void* read_callback) {
IO_STREAMFILE *this_sf;
if (!streamfile) return NULL;
if ((data && !data_size) || (!data && data_size)) return NULL;
this_sf = calloc(1,sizeof(IO_STREAMFILE));
if (!this_sf) return NULL;
/* set callbacks and internals */
this_sf->sf.read = (void*)io_read;
this_sf->sf.get_size = (void*)io_get_size;
this_sf->sf.get_offset = (void*)io_get_offset;
this_sf->sf.get_name = (void*)io_get_name;
this_sf->sf.get_realname = (void*)io_get_realname;
this_sf->sf.open = (void*)io_open;
this_sf->sf.close = (void*)io_close;
this_sf->sf.stream_index = streamfile->stream_index;
this_sf->inner_sf = streamfile;
if (data) {
this_sf->data = malloc(data_size);
if (!this_sf->data) {
free(this_sf);
return NULL;
}
memcpy(this_sf->data, data, data_size);
}
this_sf->data_size = data_size;
this_sf->read_callback = read_callback;
return &this_sf->sf;
}
/* **************************************************** */