Add size_callback to open_io_streamfile for more complex stuff

This commit is contained in:
bnnm 2018-03-30 18:10:23 +02:00
parent 99888d6517
commit e4c819af2e
8 changed files with 21 additions and 13 deletions

View File

@ -244,7 +244,7 @@ static STREAMFILE* setup_bgw_atrac3_streamfile(STREAMFILE *streamFile, off_t sub
if (!new_streamFile) goto fail;
temp_streamFile = new_streamFile;
new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, bgw_decryption_read);
new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, bgw_decryption_read,NULL);
if (!new_streamFile) goto fail;
temp_streamFile = new_streamFile;

View File

@ -146,7 +146,7 @@ static STREAMFILE* setup_fsb_streamfile(STREAMFILE *streamFile, const uint8_t *
if (!new_streamFile) goto fail;
temp_streamFile = new_streamFile;
new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, fsb_decryption_read);
new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, fsb_decryption_read,NULL);
if (!new_streamFile) goto fail;
temp_streamFile = new_streamFile;

View File

@ -104,7 +104,7 @@ static STREAMFILE* setup_bmdx_streamfile(STREAMFILE *streamFile, off_t start_off
if (!new_streamFile) goto fail;
temp_streamFile = new_streamFile;
new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, bmdx_decryption_read);
new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, bmdx_decryption_read,NULL);
if (!new_streamFile) goto fail;
temp_streamFile = new_streamFile;

View File

@ -92,7 +92,7 @@ static STREAMFILE* setup_jstm_streamfile(STREAMFILE *streamFile, off_t start_off
if (!new_streamFile) goto fail;
temp_streamFile = new_streamFile;
new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, jstm_decryption_read);
new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, jstm_decryption_read,NULL);
if (!new_streamFile) goto fail;
temp_streamFile = new_streamFile;

View File

@ -876,7 +876,7 @@ static VGMSTREAM *parse_riff_ogg(STREAMFILE * streamFile, off_t start_offset, si
io_data.patch_offset = patch_offset;
custom_streamFile = open_io_streamfile(open_wrap_streamfile(streamFile), &io_data,io_data_size, riff_ogg_io_read);
custom_streamFile = open_io_streamfile(open_wrap_streamfile(streamFile), &io_data,io_data_size, riff_ogg_io_read,NULL);
if (!custom_streamFile) return NULL;
vgmstream = init_vgmstream_ogg_vorbis_callbacks(custom_streamFile, NULL, start_offset, &ovmi);

View File

@ -365,7 +365,7 @@ static STREAMFILE* setup_sead_hca_streamfile(STREAMFILE *streamFile, off_t subfi
io_data.header_size = header_size;
io_data.key_start = key_start;
new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, sead_decryption_read);
new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, sead_decryption_read,NULL);
if (!new_streamFile) goto fail;
temp_streamFile = new_streamFile;
}

View File

@ -383,16 +383,22 @@ typedef struct {
STREAMFILE sf;
STREAMFILE *inner_sf;
void* data;
void* data; /* state for custom reads, malloc'ed + copied on open (to re-open streamfiles cleanly) */
size_t data_size;
size_t (*read_callback)(STREAMFILE *, uint8_t *, off_t, size_t, void*);
size_t (*read_callback)(STREAMFILE *, uint8_t *, off_t, size_t, void*); /* custom read to modify data before copying into buffer */
size_t (*size_callback)(STREAMFILE *, void*); /* size when custom reads make data smaller/bigger than underlying streamfile */
//todo would need to make sure re-opened streamfiles work with this, maybe should use init_data_callback per call
//size_t (*close_data_callback)(STREAMFILE *, void*); /* called during close, allows to free stuff in data */
} 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 */
if (streamfile->size_callback)
return streamfile->size_callback(streamfile->inner_sf, streamfile->data);
else
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 */
@ -406,7 +412,7 @@ static void io_get_realname(IO_STREAMFILE *streamfile, char *buffer, size_t leng
static STREAMFILE *io_open(IO_STREAMFILE *streamfile, const char * const filename, size_t buffersize) {
//todo should have some flag to decide if opening other files with IO
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);
return open_io_streamfile(new_inner_sf, streamfile->data, streamfile->data_size, streamfile->read_callback, streamfile->size_callback);
}
static void io_close(IO_STREAMFILE *streamfile) {
streamfile->inner_sf->close(streamfile->inner_sf);
@ -414,7 +420,7 @@ static void io_close(IO_STREAMFILE *streamfile) {
free(streamfile);
}
STREAMFILE *open_io_streamfile(STREAMFILE *streamfile, void* data, size_t data_size, void* read_callback) {
STREAMFILE *open_io_streamfile(STREAMFILE *streamfile, void* data, size_t data_size, void* read_callback, void* size_callback) {
IO_STREAMFILE *this_sf;
if (!streamfile) return NULL;
@ -444,6 +450,7 @@ STREAMFILE *open_io_streamfile(STREAMFILE *streamfile, void* data, size_t data_s
}
this_sf->data_size = data_size;
this_sf->read_callback = read_callback;
this_sf->size_callback = size_callback;
return &this_sf->sf;
}

View File

@ -46,7 +46,8 @@
#endif
/* struct representing a file with callbacks. Code should use STREAMFILEs and not std C functions
* to do file operations, as plugins may need to provide their own callbacks. */
* to do file operations, as plugins may need to provide their own callbacks.
* Reads from arbitrary offsets, meaning internally may need fseek equivalents during reads. */
typedef struct _STREAMFILE {
size_t (*read)(struct _STREAMFILE *,uint8_t * dest, off_t offset, size_t length);
size_t (*get_size)(struct _STREAMFILE *);
@ -83,7 +84,7 @@ STREAMFILE *open_clamp_streamfile(STREAMFILE *streamfile, off_t start, size_t si
/* Opens a STREAMFILE that uses custom IO for streamfile reads.
* Can be used to modify data on the fly (ex. decryption), or even transform it from a format to another. */
STREAMFILE *open_io_streamfile(STREAMFILE *streamfile, void* data, size_t data_size, void* read_callback);//void* size_callback, void* seek_callback);
STREAMFILE *open_io_streamfile(STREAMFILE *streamfile, void* data, size_t data_size, void* read_callback, void* size_callback);
/* Opens a STREAMFILE that reports a fake name, but still re-opens itself properly.
* Can be used to trick a meta's extension check (to call from another, with a modified SF).