cleanup: separte sf code

This commit is contained in:
bnnm 2023-06-25 22:02:34 +02:00
parent 442084cc85
commit 5d9b4ed827
11 changed files with 236 additions and 213 deletions

View File

@ -3,7 +3,7 @@
#include "../coding/coding.h"
#include "mixing.h"
#include "../util/channel_mappings.h"
#include "../util/sf_utils.h"
/*******************************************************************************/
/* TEXT */

View File

@ -285,7 +285,6 @@ int render_layout(sample_t* buf, int32_t sample_count, VGMSTREAM* vgmstream) {
case layout_blocked_ivaud:
case layout_blocked_ea_swvr:
case layout_blocked_adm:
case layout_blocked_bdsp:
case layout_blocked_ps2_iab:
case layout_blocked_vs_str:
case layout_blocked_rws:

View File

@ -185,6 +185,7 @@
<ClInclude Include="util\reader_sf.h" />
<ClInclude Include="util\reader_text.h" />
<ClInclude Include="util\samples_ops.h" />
<ClInclude Include="util\sf_utils.h" />
<ClInclude Include="util\text_reader.h" />
</ItemGroup>
<ItemGroup>
@ -745,6 +746,7 @@
<ClCompile Include="util\paths.c" />
<ClCompile Include="util\reader.c" />
<ClCompile Include="util\samples_ops.c" />
<ClCompile Include="util\sf_utils.c" />
<ClCompile Include="util\text_reader.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -380,6 +380,9 @@
<ClInclude Include="util\samples_ops.h">
<Filter>util\Header Files</Filter>
</ClInclude>
<ClInclude Include="util\sf_utils.h">
<Filter>util\Header Files</Filter>
</ClInclude>
<ClInclude Include="util\text_reader.h">
<Filter>util\Header Files</Filter>
</ClInclude>
@ -2056,6 +2059,9 @@
<ClCompile Include="util\samples_ops.c">
<Filter>util\Source Files</Filter>
</ClCompile>
<ClCompile Include="util\sf_utils.c">
<Filter>util\Source Files</Filter>
</ClCompile>
<ClCompile Include="util\text_reader.c">
<Filter>util\Source Files</Filter>
</ClCompile>

View File

@ -4,6 +4,7 @@
#include "../vgmstream.h"
#include "../util/reader_sf.h"
#include "../util/reader_text.h"
#include "../util/sf_utils.h"
typedef VGMSTREAM* (*init_vgmstream_t)(STREAMFILE* sf);

View File

@ -1,8 +1,8 @@
#include "streamfile.h"
#include "util.h"
#include "vgmstream.h"
#include "util/reader_sf.h"
#include "util/paths.h"
#include "util/sf_utils.h"
#include <string.h>
/* for dup/fdopen in some systems */
@ -985,92 +985,10 @@ STREAMFILE* open_multifile_streamfile_f(STREAMFILE** sfs, size_t sfs_size) {
/* **************************************************** */
/* change pathname's extension to another (or add it if extensionless) */
static void swap_extension(char* pathname, /*size_t*/ int pathname_len, const char* swap) {
char* extension = (char*)filename_extension(pathname);
//todo safeops
if (extension[0] == '\0') {
strcat(pathname, ".");
strcat(pathname, swap);
}
else {
strcpy(extension, swap);
}
}
STREAMFILE* open_streamfile(STREAMFILE* sf, const char* pathname) {
return sf->open(sf, pathname, STREAMFILE_DEFAULT_BUFFER_SIZE);
}
STREAMFILE* open_streamfile_by_ext(STREAMFILE* sf, const char* ext) {
char filename[PATH_LIMIT];
get_streamfile_name(sf, filename, sizeof(filename));
swap_extension(filename, sizeof(filename), ext);
return open_streamfile(sf, filename);
}
STREAMFILE* open_streamfile_by_filename(STREAMFILE* sf, const char* filename) {
char fullname[PATH_LIMIT];
char partname[PATH_LIMIT];
char *path, *name, *otherpath;
if (!sf || !filename || !filename[0]) return NULL;
get_streamfile_name(sf, fullname, sizeof(fullname));
//todo normalize separators in a better way, safeops, improve copying
/* check for non-normalized paths first (ex. txth) */
path = strrchr(fullname, '/');
otherpath = strrchr(fullname, '\\');
if (otherpath > path) { //todo cast to ptr?
/* foobar makes paths like "(fake protocol)://(windows path with \)".
* Hack to work around both separators, though probably foo_streamfile
* should just return and handle normalized paths without protocol. */
path = otherpath;
}
if (path) {
path[1] = '\0'; /* remove name after separator */
strcpy(partname, filename);
fix_dir_separators(partname); /* normalize to DIR_SEPARATOR */
/* normalize relative paths as don't work ok in some plugins */
if (partname[0] == '.' && partname[1] == DIR_SEPARATOR) { /* './name' */
name = partname + 2; /* ignore './' */
}
else if (partname[0] == '.' && partname[1] == '.' && partname[2] == DIR_SEPARATOR) { /* '../name' */
char* pathprev;
path[0] = '\0'; /* remove last separator so next call works */
pathprev = strrchr(fullname,DIR_SEPARATOR);
if (pathprev) {
pathprev[1] = '\0'; /* remove prev dir after separator */
name = partname + 3; /* ignore '../' */
}
else { /* let plugin handle? */
path[0] = DIR_SEPARATOR;
name = partname;
}
/* could work with more relative paths but whatevs */
}
else {
name = partname;
}
strcat(fullname, name);
}
else {
strcpy(fullname, filename);
}
return open_streamfile(sf, fullname);
}
STREAMFILE* reopen_streamfile(STREAMFILE* sf, size_t buffer_size) {
char pathname[PATH_LIMIT];
@ -1084,111 +1002,6 @@ STREAMFILE* reopen_streamfile(STREAMFILE* sf, size_t buffer_size) {
/* ************************************************************************* */
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;
size_t ext_len, cmp_len;
sf->get_name(sf, filename, sizeof(filename));
ext = filename_extension(filename);
ext_len = strlen(ext);
cmp_ext = cmp_exts;
do {
ststr_res = strstr(cmp_ext, ",");
cmp_len = ststr_res == NULL
? strlen(cmp_ext) /* total length if more not found */
: (intptr_t)ststr_res - (intptr_t)cmp_ext; /* find next ext; ststr_res should always be greater than cmp_ext, resulting in a positive cmp_len */
if (ext_len == cmp_len && strncasecmp(ext,cmp_ext, ext_len) == 0)
return 1;
cmp_ext = ststr_res;
if (cmp_ext != NULL)
cmp_ext = cmp_ext + 1; /* skip comma */
} while (cmp_ext != NULL);
return 0;
}
/* ************************************************************************* */
/* copies name as-is (may include full path included) */
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* sf, char* buffer, size_t size) {
char foldername[PATH_LIMIT];
const char* path;
get_streamfile_name(sf, foldername, sizeof(foldername));
//todo Windows CMD accepts both \\ and /, better way to handle this?
path = strrchr(foldername,'\\');
if (!path)
path = strrchr(foldername,'/');
if (path != NULL)
path = path+1;
//todo validate sizes and copy sensible max
if (path) {
strcpy(buffer, path);
} else {
strcpy(buffer, foldername);
}
}
/* 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* 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 "/" */
if (path) {
buffer[path - buffer] = '\0';
} else {
buffer[0] = '\0';
}
}
/* 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* sf, int num) {
#ifdef VGM_DEBUG_OUTPUT

View File

@ -130,15 +130,6 @@ STREAMFILE* open_multifile_streamfile_f(STREAMFILE** sfs, size_t sfs_size);
* Just a wrapper, to avoid having to access the STREAMFILE's callbacks directly. */
STREAMFILE* open_streamfile(STREAMFILE* sf, const char* pathname);
/* Opens a STREAMFILE from a base pathname + new extension
* Can be used to get companion headers. */
STREAMFILE* open_streamfile_by_ext(STREAMFILE* sf, const char* ext);
/* Opens a STREAMFILE from a base path + new filename.
* Can be used to get companion files. Relative paths like
* './filename', '../filename', 'dir/filename' also work. */
STREAMFILE* open_streamfile_by_filename(STREAMFILE* sf, const char* filename);
/* Reopen a STREAMFILE with a different buffer size, for fine-tuned bigfile parsing.
* Uses default buffer size when buffer_size is 0 */
STREAMFILE* reopen_streamfile(STREAMFILE* sf, size_t buffer_size);
@ -161,18 +152,6 @@ static inline size_t get_streamfile_size(STREAMFILE* sf) {
}
/* various STREAMFILE helpers functions */
/* Checks if the stream filename is one of the extensions (comma-separated, ex. "adx" or "adx,aix").
* Empty is ok to accept files without extension ("", "adx,,aix"). Returns 0 on failure */
int check_extensions(STREAMFILE* sf, const char* cmp_exts);
/* filename helpers */
void get_streamfile_name(STREAMFILE* sf, char* buf, size_t size);
void get_streamfile_filename(STREAMFILE* sf, char* buf, size_t size);
void get_streamfile_basename(STREAMFILE* sf, char* buf, size_t size);
void get_streamfile_path(STREAMFILE* sf, char* buf, size_t size);
void get_streamfile_ext(STREAMFILE* sf, char* buf, size_t size);
void dump_streamfile(STREAMFILE* sf, int num);
#endif

View File

@ -1,7 +1,8 @@
#include "companion_files.h"
#include "paths.h"
#include "../vgmstream.h"
#include "../util/reader_text.h"
#include "reader_text.h"
#include "sf_utils.h"
size_t read_key_file(uint8_t* buf, size_t buf_size, STREAMFILE* sf) {

192
src/util/sf_utils.c Normal file
View File

@ -0,0 +1,192 @@
#include "sf_utils.h"
#include "../vgmstream.h"
#include "reader_sf.h"
#include "paths.h"
/* change pathname's extension to another (or add it if extensionless) */
static void swap_extension(char* pathname, /*size_t*/ int pathname_len, const char* swap) {
char* extension = (char*)filename_extension(pathname);
//todo safeops
if (extension[0] == '\0') {
strcat(pathname, ".");
strcat(pathname, swap);
}
else {
strcpy(extension, swap);
}
}
STREAMFILE* open_streamfile_by_ext(STREAMFILE* sf, const char* ext) {
char filename[PATH_LIMIT];
get_streamfile_name(sf, filename, sizeof(filename));
swap_extension(filename, sizeof(filename), ext);
return open_streamfile(sf, filename);
}
STREAMFILE* open_streamfile_by_filename(STREAMFILE* sf, const char* filename) {
char fullname[PATH_LIMIT];
char partname[PATH_LIMIT];
char *path, *name, *otherpath;
if (!sf || !filename || !filename[0]) return NULL;
get_streamfile_name(sf, fullname, sizeof(fullname));
//todo normalize separators in a better way, safeops, improve copying
/* check for non-normalized paths first (ex. txth) */
path = strrchr(fullname, '/');
otherpath = strrchr(fullname, '\\');
if (otherpath > path) { //todo cast to ptr?
/* foobar makes paths like "(fake protocol)://(windows path with \)".
* Hack to work around both separators, though probably foo_streamfile
* should just return and handle normalized paths without protocol. */
path = otherpath;
}
if (path) {
path[1] = '\0'; /* remove name after separator */
strcpy(partname, filename);
fix_dir_separators(partname); /* normalize to DIR_SEPARATOR */
/* normalize relative paths as don't work ok in some plugins */
if (partname[0] == '.' && partname[1] == DIR_SEPARATOR) { /* './name' */
name = partname + 2; /* ignore './' */
}
else if (partname[0] == '.' && partname[1] == '.' && partname[2] == DIR_SEPARATOR) { /* '../name' */
char* pathprev;
path[0] = '\0'; /* remove last separator so next call works */
pathprev = strrchr(fullname,DIR_SEPARATOR);
if (pathprev) {
pathprev[1] = '\0'; /* remove prev dir after separator */
name = partname + 3; /* ignore '../' */
}
else { /* let plugin handle? */
path[0] = DIR_SEPARATOR;
name = partname;
}
/* could work with more relative paths but whatevs */
}
else {
name = partname;
}
strcat(fullname, name);
}
else {
strcpy(fullname, filename);
}
return open_streamfile(sf, fullname);
}
/* ************************************************************************* */
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;
size_t ext_len, cmp_len;
sf->get_name(sf, filename, sizeof(filename));
ext = filename_extension(filename);
ext_len = strlen(ext);
cmp_ext = cmp_exts;
do {
ststr_res = strstr(cmp_ext, ",");
cmp_len = ststr_res == NULL
? strlen(cmp_ext) /* total length if more not found */
: (intptr_t)ststr_res - (intptr_t)cmp_ext; /* find next ext; ststr_res should always be greater than cmp_ext, resulting in a positive cmp_len */
if (ext_len == cmp_len && strncasecmp(ext,cmp_ext, ext_len) == 0)
return 1;
cmp_ext = ststr_res;
if (cmp_ext != NULL)
cmp_ext = cmp_ext + 1; /* skip comma */
} while (cmp_ext != NULL);
return 0;
}
/* ************************************************************************* */
/* copies name as-is (may include full path included) */
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* sf, char* buffer, size_t size) {
char foldername[PATH_LIMIT];
const char* path;
get_streamfile_name(sf, foldername, sizeof(foldername));
//todo Windows CMD accepts both \\ and /, better way to handle this?
path = strrchr(foldername,'\\');
if (!path)
path = strrchr(foldername,'/');
if (path != NULL)
path = path+1;
//todo validate sizes and copy sensible max
if (path) {
strcpy(buffer, path);
} else {
strcpy(buffer, foldername);
}
}
/* 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* 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 "/" */
if (path) {
buffer[path - buffer] = '\0';
} else {
buffer[0] = '\0';
}
}
/* 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
}
}

29
src/util/sf_utils.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef _SF_UTILS_H
#define _SF_UTILS_H
#include "../streamfile.h"
/* Opens a STREAMFILE from a base pathname + new extension
* Can be used to get companion headers. */
STREAMFILE* open_streamfile_by_ext(STREAMFILE* sf, const char* ext);
/* Opens a STREAMFILE from a base path + new filename.
* Can be used to get companion files. Relative paths like
* './filename', '../filename', 'dir/filename' also work. */
STREAMFILE* open_streamfile_by_filename(STREAMFILE* sf, const char* filename);
/* various STREAMFILE helpers functions */
/* Checks if the stream filename is one of the extensions (comma-separated, ex. "adx" or "adx,aix").
* Empty is ok to accept files without extension ("", "adx,,aix"). Returns 0 on failure */
int check_extensions(STREAMFILE* sf, const char* cmp_exts);
/* filename helpers */
void get_streamfile_name(STREAMFILE* sf, char* buf, size_t size);
void get_streamfile_filename(STREAMFILE* sf, char* buf, size_t size);
void get_streamfile_basename(STREAMFILE* sf, char* buf, size_t size);
void get_streamfile_path(STREAMFILE* sf, char* buf, size_t size);
void get_streamfile_ext(STREAMFILE* sf, char* buf, size_t size);
#endif

View File

@ -12,6 +12,7 @@
#include "base/decode.h"
#include "base/render.h"
#include "base/mixing.h"
#include "util/sf_utils.h"
typedef VGMSTREAM* (*init_vgmstream_t)(STREAMFILE*);