Fix issues when getting extension affecting .mpf + cleanup

This commit is contained in:
bnnm 2021-01-03 16:07:17 +01:00
parent a2716b8e7d
commit 7a047c967a

View File

@ -861,15 +861,15 @@ STREAMFILE* open_multifile_streamfile_f(STREAMFILE **streamfiles, size_t streamf
/* **************************************************** */
STREAMFILE* open_streamfile(STREAMFILE *streamfile, const char *pathname) {
return streamfile->open(streamfile, pathname, STREAMFILE_DEFAULT_BUFFER_SIZE);
STREAMFILE* open_streamfile(STREAMFILE* sf, const char* pathname) {
return sf->open(sf, pathname, STREAMFILE_DEFAULT_BUFFER_SIZE);
}
STREAMFILE* open_streamfile_by_ext(STREAMFILE *streamfile, const char *ext) {
STREAMFILE* open_streamfile_by_ext(STREAMFILE* sf, const char* ext) {
char filename[PATH_LIMIT];
int filename_len, fileext_len;
streamfile->get_name(streamfile, filename, sizeof(filename));
sf->get_name(sf, filename, sizeof(filename));
filename_len = strlen(filename);
fileext_len = strlen(filename_extension(filename));
@ -882,17 +882,17 @@ STREAMFILE* open_streamfile_by_ext(STREAMFILE *streamfile, const char *ext) {
strcpy(filename + filename_len - fileext_len, ext);
}
return streamfile->open(streamfile, filename, STREAMFILE_DEFAULT_BUFFER_SIZE);
return sf->open(sf, filename, STREAMFILE_DEFAULT_BUFFER_SIZE);
}
STREAMFILE* open_streamfile_by_filename(STREAMFILE *streamfile, const char * filename) {
STREAMFILE* open_streamfile_by_filename(STREAMFILE* sf, const char* filename) {
char fullname[PATH_LIMIT];
char partname[PATH_LIMIT];
char *path, *name;
if (!streamfile || !filename || !filename[0]) return NULL;
if (!sf || !filename || !filename[0]) return NULL;
streamfile->get_name(streamfile, fullname, sizeof(fullname));
sf->get_name(sf, fullname, sizeof(fullname));
//todo normalize separators in a better way, safeops, improve copying
path = strrchr(fullname,DIR_SEPARATOR);
@ -903,10 +903,10 @@ STREAMFILE* open_streamfile_by_filename(STREAMFILE *streamfile, const char * fil
fix_dir_separators(partname);
/* normalize relative paths as don't work ok in some plugins */
if (partname[0]=='.' && partname[1] == DIR_SEPARATOR) { /* './name' */
if (partname[0] == '.' && partname[1] == DIR_SEPARATOR) { /* './name' */
name = partname + 2; /* ignore './' */
}
else if (partname[0]=='.' && partname[1]=='.' && partname[2] == DIR_SEPARATOR) { /* '../name' */
else if (partname[0] == '.' && partname[1] == '.' && partname[2] == DIR_SEPARATOR) { /* '../name' */
char *pathprev;
path[0] = '\0'; /* remove last separator so next call works */
@ -931,23 +931,23 @@ STREAMFILE* open_streamfile_by_filename(STREAMFILE *streamfile, const char * fil
strcpy(fullname, filename);
}
return streamfile->open(streamfile, fullname, STREAMFILE_DEFAULT_BUFFER_SIZE);
return sf->open(sf, fullname, STREAMFILE_DEFAULT_BUFFER_SIZE);
}
STREAMFILE* reopen_streamfile(STREAMFILE *streamfile, size_t buffer_size) {
STREAMFILE* reopen_streamfile(STREAMFILE* sf, size_t buffer_size) {
char pathname[PATH_LIMIT];
if (!streamfile) return NULL;
if (!sf) return NULL;
if (buffer_size == 0)
buffer_size = STREAMFILE_DEFAULT_BUFFER_SIZE;
streamfile->get_name(streamfile,pathname,sizeof(pathname));
return streamfile->open(streamfile,pathname,buffer_size);
sf->get_name(sf, pathname,sizeof(pathname));
return sf->open(sf, pathname, buffer_size);
}
/* **************************************************** */
size_t read_line(char *buf, int buf_size, off_t offset, STREAMFILE *sf, int *p_line_ok) {
size_t read_line(char* buf, int buf_size, off_t offset, STREAMFILE* sf, int* p_line_ok) {
int i;
off_t file_size = get_streamfile_size(sf);
int extra_bytes = 0; /* how many bytes over those put in the buffer were read */
@ -996,7 +996,7 @@ size_t read_line(char *buf, int buf_size, off_t offset, STREAMFILE *sf, int *p_l
return i + extra_bytes;
}
size_t read_string(char *buf, size_t buf_size, off_t offset, STREAMFILE *sf) {
size_t read_string(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf) {
size_t pos;
for (pos = 0; pos < buf_size; pos++) {
@ -1019,7 +1019,7 @@ fail:
return 0;
}
size_t read_string_utf16(char *buf, size_t buf_size, off_t offset, STREAMFILE *sf, int big_endian) {
size_t read_string_utf16(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf, int big_endian) {
size_t pos, offpos;
uint16_t (*read_u16)(off_t,STREAMFILE*) = big_endian ? read_u16be : read_u16le;
@ -1049,16 +1049,16 @@ size_t read_string_utf16be(char* buf, size_t buf_size, off_t offset, STREAMFILE*
return read_string_utf16(buf, buf_size, offset, sf, 1);
}
/* ************************************************************************* */
size_t read_key_file(uint8_t *buf, size_t buf_size, STREAMFILE *sf) {
size_t read_key_file(uint8_t* buf, size_t buf_size, STREAMFILE* sf) {
char keyname[PATH_LIMIT];
char filename[PATH_LIMIT];
const char *path, *ext;
STREAMFILE * streamFileKey = NULL;
STREAMFILE* sf_key = NULL;
size_t keysize;
sf->get_name(sf,filename,sizeof(filename));
get_streamfile_name(sf, filename, sizeof(filename));
if (strlen(filename)+4 > sizeof(keyname)) goto fail;
@ -1067,20 +1067,20 @@ size_t read_key_file(uint8_t *buf, size_t buf_size, STREAMFILE *sf) {
ext = strrchr(filename,'.');
if (ext!=NULL) ext = ext+1;
path = strrchr(filename,DIR_SEPARATOR);
path = strrchr(filename, DIR_SEPARATOR);
if (path!=NULL) path = path+1;
/* "(name.ext)key" */
strcpy(keyname, filename);
strcat(keyname, "key");
streamFileKey = sf->open(sf,keyname,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (streamFileKey) goto found;
sf_key = sf->open(sf, keyname, STREAMFILE_DEFAULT_BUFFER_SIZE);
if (sf_key) goto found;
/* "(name.ext)KEY" */
/*
strcpy(keyname+strlen(keyname)-3,"KEY");
streamFileKey = streamFile->open(streamFile,keyname,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (streamFileKey) goto found;
sf_key = sf->open(sf, keyname, STREAMFILE_DEFAULT_BUFFER_SIZE);
if (sf_key) goto found;
*/
@ -1094,38 +1094,38 @@ size_t read_key_file(uint8_t *buf, size_t buf_size, STREAMFILE *sf) {
}
if (ext) strcat(keyname, ext);
strcat(keyname, "key");
streamFileKey = sf->open(sf,keyname,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (streamFileKey) goto found;
sf_key = sf->open(sf, keyname, STREAMFILE_DEFAULT_BUFFER_SIZE);
if (sf_key) goto found;
/* "(.ext)KEY" */
/*
strcpy(keyname+strlen(keyname)-3,"KEY");
streamFileKey = streamFile->open(streamFile,keyname,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (streamFileKey) goto found;
sf_key = sf->open(sf, keyname, STREAMFILE_DEFAULT_BUFFER_SIZE);
if (sf_key) goto found;
*/
goto fail;
}
found:
keysize = get_streamfile_size(streamFileKey);
keysize = get_streamfile_size(sf_key);
if (keysize > buf_size) goto fail;
if (read_streamfile(buf, 0, keysize, streamFileKey) != keysize)
if (read_streamfile(buf, 0, keysize, sf_key) != keysize)
goto fail;
close_streamfile(streamFileKey);
close_streamfile(sf_key);
return keysize;
fail:
close_streamfile(streamFileKey);
close_streamfile(sf_key);
return 0;
}
STREAMFILE *read_filemap_file(STREAMFILE *sf, int file_num) {
STREAMFILE* read_filemap_file(STREAMFILE* sf, int file_num) {
char filename[PATH_LIMIT];
off_t txt_offset, file_size;
STREAMFILE *sf_map = NULL;
STREAMFILE* sf_map = NULL;
sf_map = open_streamfile_by_filename(sf, ".txtm");
if (!sf_map) goto fail;
@ -1163,7 +1163,7 @@ STREAMFILE *read_filemap_file(STREAMFILE *sf, int file_num) {
if (strcmp(key, filename) == 0) {
int n;
char subval[PATH_LIMIT];
const char *current = val;
const char* current = val;
int i;
for (i = 0; i <= file_num; i++) {
@ -1192,7 +1192,7 @@ fail:
return NULL;
}
void fix_dir_separators(char * filename) {
void fix_dir_separators(char* filename) {
char c;
int i = 0;
while ((c = filename[i]) != '\0') {
@ -1202,11 +1202,13 @@ void fix_dir_separators(char * filename) {
}
}
int check_extensions(STREAMFILE *sf, const char * cmp_exts) {
/* ************************************************************************* */
int check_extensions(STREAMFILE* sf, const char* cmp_exts) {
char filename[PATH_LIMIT];
const char * ext = NULL;
const char * cmp_ext = NULL;
const char * ststr_res = NULL;
const char* ext = NULL;
const char* cmp_ext = NULL;
const char* ststr_res = NULL;
size_t ext_len, cmp_len;
sf->get_name(sf,filename,sizeof(filename));
@ -1232,6 +1234,7 @@ int check_extensions(STREAMFILE *sf, const char * cmp_exts) {
return 0;
}
/* ************************************************************************* */
/**
* Find a chunk starting from an offset, and save its offset/size (if not NULL), with offset after id/size.
@ -1241,11 +1244,11 @@ int check_extensions(STREAMFILE *sf, const char * cmp_exts) {
*
* returns 0 on failure
*/
static int find_chunk_internal(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, size_t max_size, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size, int big_endian_type, int big_endian_size, int zero_size_end) {
static int find_chunk_internal(STREAMFILE* sf, uint32_t chunk_id, off_t start_offset, size_t max_size, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size, int big_endian_type, int big_endian_size, int zero_size_end) {
int32_t (*read_32bit_type)(off_t,STREAMFILE*) = big_endian_type ? read_32bitBE : read_32bitLE;
int32_t (*read_32bit_size)(off_t,STREAMFILE*) = big_endian_size ? read_32bitBE : read_32bitLE;
off_t offset, max_offset;
size_t file_size = get_streamfile_size(streamFile);
size_t file_size = get_streamfile_size(sf);
if (max_size == 0)
max_size = file_size;
@ -1258,8 +1261,8 @@ static int find_chunk_internal(STREAMFILE *streamFile, uint32_t chunk_id, off_t
/* read chunks */
while (offset < max_offset) {
uint32_t chunk_type = read_32bit_type(offset + 0x00,streamFile);
uint32_t chunk_size = read_32bit_size(offset + 0x04,streamFile);
uint32_t chunk_type = read_32bit_type(offset + 0x00,sf);
uint32_t chunk_size = read_32bit_size(offset + 0x04,sf);
//;VGM_LOG("CHUNK: type=%x, size=%x at %lx\n", chunk_type, chunk_size, offset);
if (chunk_type == 0xFFFFFFFF || chunk_size == 0xFFFFFFFF)
@ -1280,36 +1283,39 @@ static int find_chunk_internal(STREAMFILE *streamFile, uint32_t chunk_id, off_t
return 0;
}
int find_chunk_be(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size) {
return find_chunk(streamFile, chunk_id, start_offset, full_chunk_size, out_chunk_offset, out_chunk_size, 1, 0);
int find_chunk_be(STREAMFILE* sf, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size) {
return find_chunk(sf, chunk_id, start_offset, full_chunk_size, out_chunk_offset, out_chunk_size, 1, 0);
}
int find_chunk_le(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size) {
return find_chunk(streamFile, chunk_id, start_offset, full_chunk_size, out_chunk_offset, out_chunk_size, 0, 0);
int find_chunk_le(STREAMFILE* sf, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size) {
return find_chunk(sf, chunk_id, start_offset, full_chunk_size, out_chunk_offset, out_chunk_size, 0, 0);
}
int find_chunk(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size, int big_endian_size, int zero_size_end) {
return find_chunk_internal(streamFile, chunk_id, start_offset, 0, full_chunk_size, out_chunk_offset, out_chunk_size, 1, big_endian_size, zero_size_end);
int find_chunk(STREAMFILE* sf, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size, int big_endian_size, int zero_size_end) {
return find_chunk_internal(sf, chunk_id, start_offset, 0, full_chunk_size, out_chunk_offset, out_chunk_size, 1, big_endian_size, zero_size_end);
}
int find_chunk_riff_le(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, size_t max_size, off_t *out_chunk_offset, size_t *out_chunk_size) {
return find_chunk_internal(streamFile, chunk_id, start_offset, max_size, 0, out_chunk_offset, out_chunk_size, 1, 0, 0);
int find_chunk_riff_le(STREAMFILE* sf, uint32_t chunk_id, off_t start_offset, size_t max_size, off_t *out_chunk_offset, size_t *out_chunk_size) {
return find_chunk_internal(sf, chunk_id, start_offset, max_size, 0, out_chunk_offset, out_chunk_size, 1, 0, 0);
}
int find_chunk_riff_be(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, size_t max_size, off_t *out_chunk_offset, size_t *out_chunk_size) {
return find_chunk_internal(streamFile, chunk_id, start_offset, max_size, 0, out_chunk_offset, out_chunk_size, 1, 1, 0);
int find_chunk_riff_be(STREAMFILE* sf, uint32_t chunk_id, off_t start_offset, size_t max_size, off_t *out_chunk_offset, size_t *out_chunk_size) {
return find_chunk_internal(sf, chunk_id, start_offset, max_size, 0, out_chunk_offset, out_chunk_size, 1, 1, 0);
}
int find_chunk_riff_ve(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, size_t max_size, off_t *out_chunk_offset, size_t *out_chunk_size, int big_endian) {
return find_chunk_internal(streamFile, chunk_id, start_offset, max_size, 0, out_chunk_offset, out_chunk_size, big_endian, big_endian, 0);
int find_chunk_riff_ve(STREAMFILE* sf, uint32_t chunk_id, off_t start_offset, size_t max_size, off_t *out_chunk_offset, size_t *out_chunk_size, int big_endian) {
return find_chunk_internal(sf, chunk_id, start_offset, max_size, 0, out_chunk_offset, out_chunk_size, big_endian, big_endian, 0);
}
/* ************************************************************************* */
/* copies name as-is (may include full path included) */
void get_streamfile_name(STREAMFILE *streamFile, char * buffer, size_t size) {
streamFile->get_name(streamFile,buffer,size);
void get_streamfile_name(STREAMFILE* sf, char* buffer, size_t size) {
sf->get_name(sf, buffer, size);
}
/* copies the filename without path */
void get_streamfile_filename(STREAMFILE *streamFile, char * buffer, size_t size) {
void get_streamfile_filename(STREAMFILE* sf, char* buffer, size_t size) {
char foldername[PATH_LIMIT];
const char *path;
const char* path;
streamFile->get_name(streamFile,foldername,sizeof(foldername));
get_streamfile_name(sf, foldername, sizeof(foldername));
//todo Windows CMD accepts both \\ and /, better way to handle this?
path = strrchr(foldername,'\\');
@ -1325,22 +1331,24 @@ void get_streamfile_filename(STREAMFILE *streamFile, char * buffer, size_t size)
strcpy(buffer, foldername);
}
}
/* copies the filename without path or extension */
void get_streamfile_basename(STREAMFILE *streamFile, char * buffer, size_t size) {
char *ext;
get_streamfile_filename(streamFile,buffer,size);
/* copies the filename without path or extension */
void get_streamfile_basename(STREAMFILE* sf, char* buffer, size_t size) {
char* ext;
get_streamfile_filename(sf, buffer, size);
ext = strrchr(buffer,'.');
if (ext) {
ext[0] = '\0'; /* remove .ext from buffer */
}
}
/* copies path removing name (NULL when if filename has no path) */
void get_streamfile_path(STREAMFILE *streamFile, char * buffer, size_t size) {
const char *path;
streamFile->get_name(streamFile,buffer,size);
/* copies path removing name (NULL when if filename has no path) */
void get_streamfile_path(STREAMFILE* sf, char* buffer, size_t size) {
const char* path;
get_streamfile_name(sf, buffer, size);
path = strrchr(buffer,DIR_SEPARATOR);
if (path!=NULL) path = path+1; /* includes "/" */
@ -1351,34 +1359,47 @@ void get_streamfile_path(STREAMFILE *streamFile, char * buffer, size_t size) {
buffer[0] = '\0';
}
}
void get_streamfile_ext(STREAMFILE *streamFile, char * filename, size_t size) {
streamFile->get_name(streamFile,filename,size);
strcpy(filename, filename_extension(filename));
/* copies extension only */
void get_streamfile_ext(STREAMFILE* sf, char* buffer, size_t size) {
char filename[PATH_LIMIT];
const char* extension = NULL;
get_streamfile_name(sf, filename, sizeof(filename));
extension = filename_extension(filename);
if (!extension) {
buffer[0] = '\n';
}
else {
strncpy(buffer, extension, size); //todo use something better
}
}
/* ************************************************************************* */
/* debug util, mainly for custom IO testing */
void dump_streamfile(STREAMFILE *streamFile, int num) {
void dump_streamfile(STREAMFILE* sf, int num) {
#ifdef VGM_DEBUG_OUTPUT
off_t offset = 0;
FILE *f = NULL;
FILE* f = NULL;
if (num >= 0) {
char filename[PATH_LIMIT];
char dumpname[PATH_LIMIT];
get_streamfile_filename(streamFile, filename, PATH_LIMIT);
get_streamfile_filename(sf, filename, PATH_LIMIT);
snprintf(dumpname,PATH_LIMIT, "%s_%02i.dump", filename, num);
f = fopen(dumpname,"wb");
if (!f) return;
}
VGM_LOG("dump streamfile: size %x\n", get_streamfile_size(streamFile));
while (offset < get_streamfile_size(streamFile)) {
VGM_LOG("dump streamfile: size %x\n", get_streamfile_size(sf));
while (offset < get_streamfile_size(sf)) {
uint8_t buffer[0x8000];
size_t read;
read = read_streamfile(buffer,offset,0x8000,streamFile);
read = read_streamfile(buffer,offset,0x8000,sf);
if(!read) {
VGM_LOG("dump streamfile: can't read at %lx\n", offset);
break;