mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-18 15:54:05 +01:00
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:
parent
23998b0b97
commit
dfbeee2cf3
186
src/streamfile.c
186
src/streamfile.c
@ -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;
|
||||
}
|
||||
|
||||
/* **************************************************** */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user