fixed crash and some memory leaks in FS module
This commit is contained in:
parent
a2d961f060
commit
148552893a
|
@ -34,9 +34,6 @@ FILE* _wfopen(const wchar_t *, const wchar_t *);
|
||||||
wchar_t* wcsrchr(const wchar_t *, wchar_t);
|
wchar_t* wcsrchr(const wchar_t *, wchar_t);
|
||||||
wchar_t* wcscpy(wchar_t *, const wchar_t *);
|
wchar_t* wcscpy(wchar_t *, const wchar_t *);
|
||||||
|
|
||||||
#define UTF8ToString(S) (wchar_t *)SDL_iconv_string("UTF-16LE", "UTF-8", (char *)(S), SDL_strlen(S)+1)
|
|
||||||
#define StringToUTF8(S) SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(S), (SDL_wcslen(S)+1)*sizeof(wchar_t))
|
|
||||||
|
|
||||||
void file_dialog_load(file_dialog_load_callback callback, void* data)
|
void file_dialog_load(file_dialog_load_callback callback, void* data)
|
||||||
{
|
{
|
||||||
OPENFILENAMEW ofn;
|
OPENFILENAMEW ofn;
|
||||||
|
@ -71,7 +68,10 @@ void file_dialog_load(file_dialog_load_callback callback, void* data)
|
||||||
const wchar_t* basename = wcsrchr(filename, L'\\');
|
const wchar_t* basename = wcsrchr(filename, L'\\');
|
||||||
const wchar_t* name = basename ? basename + 1 : filename;
|
const wchar_t* name = basename ? basename + 1 : filename;
|
||||||
|
|
||||||
callback(StringToUTF8(name), buffer, size, data, 0);
|
char resName[MAX_PATH];
|
||||||
|
wcstombs(resName, name, MAX_PATH);
|
||||||
|
callback(resName, buffer, size, data, 0);
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -87,8 +87,7 @@ void file_dialog_save(file_dialog_save_callback callback, const char* name, cons
|
||||||
SDL_zero(ofn);
|
SDL_zero(ofn);
|
||||||
|
|
||||||
wchar_t filename[MAX_PATH];
|
wchar_t filename[MAX_PATH];
|
||||||
memset(filename, 0, sizeof(filename));
|
mbstowcs(filename, name, MAX_PATH);
|
||||||
wcscpy(filename, UTF8ToString(name));
|
|
||||||
|
|
||||||
ofn.lStructSize = sizeof(ofn);
|
ofn.lStructSize = sizeof(ofn);
|
||||||
ofn.lpstrFile = filename;
|
ofn.lpstrFile = filename;
|
||||||
|
|
165
src/fs.c
165
src/fs.c
|
@ -106,29 +106,33 @@ bool fsIsInPublicDir(FileSystem* fs)
|
||||||
|
|
||||||
#if defined(__TIC_WINDOWS__) || defined(__TIC_WINRT__)
|
#if defined(__TIC_WINDOWS__) || defined(__TIC_WINRT__)
|
||||||
|
|
||||||
|
typedef wchar_t fsString;
|
||||||
|
|
||||||
#define __S(x) L ## x
|
#define __S(x) L ## x
|
||||||
#define _S(x) __S(x)
|
#define _S(x) __S(x)
|
||||||
|
|
||||||
static const wchar_t* UTF8ToString(const char* str)
|
static const fsString* utf8ToString(const char* str)
|
||||||
{
|
{
|
||||||
static wchar_t wstr[FILENAME_MAX];
|
fsString* wstr = malloc(FILENAME_MAX * sizeof(fsString));
|
||||||
|
|
||||||
mbstowcs(wstr, str, FILENAME_MAX);
|
mbstowcs(wstr, str, FILENAME_MAX);
|
||||||
|
|
||||||
return wstr;
|
return wstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* StringToUTF8(const wchar_t* wstr)
|
static const char* stringToUtf8(const fsString* wstr)
|
||||||
{
|
{
|
||||||
static char str[FILENAME_MAX];
|
char* str = malloc(FILENAME_MAX * sizeof(char));
|
||||||
|
|
||||||
wcstombs(str, wstr, FILENAME_MAX);
|
wcstombs(str, wstr, FILENAME_MAX);
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* _wfopen(const wchar_t *, const wchar_t *);
|
#define freeString(S) free((void*)S)
|
||||||
int _wremove(const wchar_t *);
|
|
||||||
|
FILE* _wfopen(const fsString *, const fsString *);
|
||||||
|
int _wremove(const fsString *);
|
||||||
|
|
||||||
#define TIC_DIR _WDIR
|
#define TIC_DIR _WDIR
|
||||||
#define tic_dirent _wdirent
|
#define tic_dirent _wdirent
|
||||||
|
@ -145,10 +149,14 @@ int _wremove(const wchar_t *);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
typedef char fsString;
|
||||||
|
|
||||||
#define _S(x) (x)
|
#define _S(x) (x)
|
||||||
|
|
||||||
#define UTF8ToString(S) (S)
|
#define utf8ToString(S) (S)
|
||||||
#define StringToUTF8(S) (S)
|
#define stringToUtf8(S) (S)
|
||||||
|
|
||||||
|
#define freeString(S)
|
||||||
|
|
||||||
#define TIC_DIR DIR
|
#define TIC_DIR DIR
|
||||||
#define tic_dirent dirent
|
#define tic_dirent dirent
|
||||||
|
@ -309,38 +317,62 @@ void fsEnumFiles(FileSystem* fs, ListCallback callback, void* data)
|
||||||
|
|
||||||
const char* path = getFilePath(fs, "");
|
const char* path = getFilePath(fs, "");
|
||||||
|
|
||||||
if ((dir = tic_opendir(UTF8ToString(path))) != NULL)
|
{
|
||||||
|
const fsString* pathString = utf8ToString(path);
|
||||||
|
|
||||||
|
if ((dir = tic_opendir(pathString)) != NULL)
|
||||||
{
|
{
|
||||||
while ((ent = tic_readdir(dir)) != NULL)
|
while ((ent = tic_readdir(dir)) != NULL)
|
||||||
{
|
{
|
||||||
if (ent->d_type == DT_DIR && *ent->d_name != '.')
|
if (ent->d_type == DT_DIR && *ent->d_name != _S('.'))
|
||||||
{
|
{
|
||||||
if (!callback(StringToUTF8(ent->d_name), NULL, 0, data, true))break;
|
const char* name = stringToUtf8(ent->d_name);
|
||||||
|
bool result = callback(name, NULL, 0, data, true);
|
||||||
|
freeString(name);
|
||||||
|
|
||||||
|
if(!result) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tic_closedir(dir);
|
tic_closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dir = tic_opendir(UTF8ToString(path))) != NULL)
|
freeString(pathString);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const fsString* pathString = utf8ToString(path);
|
||||||
|
|
||||||
|
if ((dir = tic_opendir(pathString)) != NULL)
|
||||||
{
|
{
|
||||||
while ((ent = tic_readdir(dir)) != NULL)
|
while ((ent = tic_readdir(dir)) != NULL)
|
||||||
{
|
{
|
||||||
if (ent->d_type == DT_REG)
|
if (ent->d_type == DT_REG)
|
||||||
{
|
{
|
||||||
if (!callback(StringToUTF8(ent->d_name), NULL, 0, data, false))break;
|
const char* name = stringToUtf8(ent->d_name);
|
||||||
|
bool result = callback(name, NULL, 0, data, false);
|
||||||
|
freeString(name);
|
||||||
|
|
||||||
|
if (!result)break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tic_closedir(dir);
|
tic_closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
freeString(pathString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fsDeleteDir(FileSystem* fs, const char* name)
|
bool fsDeleteDir(FileSystem* fs, const char* name)
|
||||||
{
|
{
|
||||||
#if defined(__TIC_WINRT__) || defined(__TIC_WINDOWS__)
|
#if defined(__TIC_WINRT__) || defined(__TIC_WINDOWS__)
|
||||||
const char* path = getFilePath(fs, name);
|
const char* path = getFilePath(fs, name);
|
||||||
bool result = tic_rmdir(UTF8ToString(path));
|
|
||||||
|
const fsString* pathString = utf8ToString(path);
|
||||||
|
bool result = tic_rmdir(pathString);
|
||||||
|
freeString(pathString);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
bool result = rmdir(getFilePath(fs, name));
|
bool result = rmdir(getFilePath(fs, name));
|
||||||
#endif
|
#endif
|
||||||
|
@ -355,7 +387,10 @@ bool fsDeleteDir(FileSystem* fs, const char* name)
|
||||||
bool fsDeleteFile(FileSystem* fs, const char* name)
|
bool fsDeleteFile(FileSystem* fs, const char* name)
|
||||||
{
|
{
|
||||||
const char* path = getFilePath(fs, name);
|
const char* path = getFilePath(fs, name);
|
||||||
bool result = tic_remove(UTF8ToString(path));
|
|
||||||
|
const fsString* pathString = utf8ToString(path);
|
||||||
|
bool result = tic_remove(pathString);
|
||||||
|
freeString(pathString);
|
||||||
|
|
||||||
#if defined(__EMSCRIPTEN__)
|
#if defined(__EMSCRIPTEN__)
|
||||||
EM_ASM(FS.syncfs(function(){}));
|
EM_ASM(FS.syncfs(function(){}));
|
||||||
|
@ -380,7 +415,10 @@ static void onAddFile(const char* name, const u8* buffer, s32 size, void* data,
|
||||||
{
|
{
|
||||||
const char* destname = getFilePath(fs, name);
|
const char* destname = getFilePath(fs, name);
|
||||||
|
|
||||||
FILE* file = tic_fopen(UTF8ToString(destname), _S("rb"));
|
const fsString* destString = utf8ToString(destname);
|
||||||
|
FILE* file = tic_fopen(destString, _S("rb"));
|
||||||
|
freeString(destString);
|
||||||
|
|
||||||
if(file)
|
if(file)
|
||||||
{
|
{
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
@ -390,7 +428,10 @@ static void onAddFile(const char* name, const u8* buffer, s32 size, void* data,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char* path = getFilePath(fs, name);
|
const char* path = getFilePath(fs, name);
|
||||||
FILE* dest = tic_fopen(UTF8ToString(path), _S("wb"));
|
|
||||||
|
const fsString* pathString = utf8ToString(path);
|
||||||
|
FILE* dest = tic_fopen(pathString, _S("wb"));
|
||||||
|
freeString(pathString);
|
||||||
|
|
||||||
if (dest)
|
if (dest)
|
||||||
{
|
{
|
||||||
|
@ -548,7 +589,11 @@ bool fsIsDir(FileSystem* fs, const char* name)
|
||||||
|
|
||||||
const char* path = getFilePath(fs, name);
|
const char* path = getFilePath(fs, name);
|
||||||
struct tic_stat_struct s;
|
struct tic_stat_struct s;
|
||||||
return tic_stat(UTF8ToString(path), &s) == 0 && S_ISDIR(s.st_mode);
|
const fsString* pathString = utf8ToString(path);
|
||||||
|
bool ret = tic_stat(pathString, &s) == 0 && S_ISDIR(s.st_mode);
|
||||||
|
freeString(pathString);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fsGetFileData(GetCallback callback, const char* name, void* buffer, size_t size, u32 mode, void* data)
|
void fsGetFileData(GetCallback callback, const char* name, void* buffer, size_t size, u32 mode, void* data)
|
||||||
|
@ -601,7 +646,9 @@ void fsGetFile(FileSystem* fs, GetCallback callback, const char* name, void* dat
|
||||||
|
|
||||||
bool fsWriteFile(const char* name, const void* buffer, s32 size)
|
bool fsWriteFile(const char* name, const void* buffer, s32 size)
|
||||||
{
|
{
|
||||||
FILE* file = tic_fopen(UTF8ToString(name), _S("wb"));
|
const fsString* pathString = utf8ToString(name);
|
||||||
|
FILE* file = tic_fopen(pathString, _S("wb"));
|
||||||
|
freeString(pathString);
|
||||||
|
|
||||||
if(file)
|
if(file)
|
||||||
{
|
{
|
||||||
|
@ -626,7 +673,10 @@ bool fsCopyFile(const char* src, const char* dst)
|
||||||
s32 size = 0;
|
s32 size = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
FILE* file = tic_fopen(UTF8ToString(src), _S("rb"));
|
const fsString* pathString = utf8ToString(src);
|
||||||
|
FILE* file = tic_fopen(pathString, _S("rb"));
|
||||||
|
freeString(pathString);
|
||||||
|
|
||||||
if(file)
|
if(file)
|
||||||
{
|
{
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
|
@ -641,7 +691,9 @@ bool fsCopyFile(const char* src, const char* dst)
|
||||||
|
|
||||||
if(buffer)
|
if(buffer)
|
||||||
{
|
{
|
||||||
FILE* file = tic_fopen(UTF8ToString(dst), _S("wb"));
|
const fsString* pathString = utf8ToString(dst);
|
||||||
|
FILE* file = tic_fopen(pathString, _S("wb"));
|
||||||
|
freeString(pathString);
|
||||||
|
|
||||||
if(file)
|
if(file)
|
||||||
{
|
{
|
||||||
|
@ -659,7 +711,10 @@ bool fsCopyFile(const char* src, const char* dst)
|
||||||
|
|
||||||
void* fsReadFile(const char* path, s32* size)
|
void* fsReadFile(const char* path, s32* size)
|
||||||
{
|
{
|
||||||
FILE* file = tic_fopen(UTF8ToString(path), _S("rb"));
|
const fsString* pathString = utf8ToString(path);
|
||||||
|
FILE* file = tic_fopen(pathString, _S("rb"));
|
||||||
|
freeString(pathString);
|
||||||
|
|
||||||
void* buffer = NULL;
|
void* buffer = NULL;
|
||||||
|
|
||||||
if(file)
|
if(file)
|
||||||
|
@ -679,37 +734,43 @@ void* fsReadFile(const char* path, s32* size)
|
||||||
|
|
||||||
static void makeDir(const char* name)
|
static void makeDir(const char* name)
|
||||||
{
|
{
|
||||||
tic_mkdir(UTF8ToString(name));
|
const fsString* pathString = utf8ToString(name);
|
||||||
|
tic_mkdir(pathString);
|
||||||
|
freeString(pathString);
|
||||||
|
|
||||||
#if defined(__EMSCRIPTEN__)
|
#if defined(__EMSCRIPTEN__)
|
||||||
EM_ASM(FS.syncfs(function(){}));
|
EM_ASM(FS.syncfs(function(){}));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* fsFilename(const char *path)
|
static void fsFullname(const char *path, char *fullname)
|
||||||
{
|
{
|
||||||
const char* full = fsFullname(path);
|
|
||||||
const char* base = fsBasename(path);
|
|
||||||
|
|
||||||
return base ? full + strlen(fsBasename(path)) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* fsFullname(const char *path)
|
|
||||||
{
|
|
||||||
char* result = NULL;
|
|
||||||
|
|
||||||
#if defined(__TIC_WINDOWS__) || defined(__TIC_WINRT__)
|
#if defined(__TIC_WINDOWS__) || defined(__TIC_WINRT__)
|
||||||
static wchar_t wpath[FILENAME_MAX];
|
static wchar_t wpath[FILENAME_MAX];
|
||||||
GetFullPathNameW(UTF8ToString(path), sizeof(wpath), wpath, NULL);
|
|
||||||
|
|
||||||
result = StringToUTF8(wpath);
|
const fsString* pathString = utf8ToString(path);
|
||||||
|
GetFullPathNameW(pathString, sizeof(wpath), wpath, NULL);
|
||||||
|
freeString(pathString);
|
||||||
|
|
||||||
|
const char* res = stringToUtf8(wpath);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
result = realpath(path, NULL);
|
const char* res = realpath(path, NULL);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return result;
|
strcpy(fullname, res);
|
||||||
|
free((void*)res);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* fsFilename(const char *path)
|
||||||
|
{
|
||||||
|
static char full[FILENAME_MAX];
|
||||||
|
fsFullname(path, full);
|
||||||
|
|
||||||
|
const char* base = fsBasename(path);
|
||||||
|
|
||||||
|
return base ? full + strlen(fsBasename(path)) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* fsBasename(const char *path)
|
const char* fsBasename(const char *path)
|
||||||
|
@ -723,10 +784,16 @@ const char* fsBasename(const char *path)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
char* full = (char*)fsFullname(path);
|
static char full[FILENAME_MAX];
|
||||||
|
fsFullname(path, full);
|
||||||
|
|
||||||
struct tic_stat_struct s;
|
struct tic_stat_struct s;
|
||||||
if(tic_stat(UTF8ToString(full), &s) == 0)
|
|
||||||
|
const fsString* fullString = utf8ToString(full);
|
||||||
|
s32 ret = tic_stat(fullString, &s);
|
||||||
|
freeString(fullString);
|
||||||
|
|
||||||
|
if(ret == 0)
|
||||||
{
|
{
|
||||||
result = full;
|
result = full;
|
||||||
|
|
||||||
|
@ -757,7 +824,12 @@ const char* fsBasename(const char *path)
|
||||||
bool fsExists(const char* name)
|
bool fsExists(const char* name)
|
||||||
{
|
{
|
||||||
struct tic_stat_struct s;
|
struct tic_stat_struct s;
|
||||||
return tic_stat(UTF8ToString(name), &s) == 0;
|
|
||||||
|
const fsString* pathString = utf8ToString(name);
|
||||||
|
bool ret = tic_stat(pathString, &s) == 0;
|
||||||
|
freeString(pathString);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fsExistsFile(FileSystem* fs, const char* name)
|
bool fsExistsFile(FileSystem* fs, const char* name)
|
||||||
|
@ -769,7 +841,11 @@ u64 fsMDate(FileSystem* fs, const char* name)
|
||||||
{
|
{
|
||||||
struct tic_stat_struct s;
|
struct tic_stat_struct s;
|
||||||
|
|
||||||
if(tic_stat(UTF8ToString(getFilePath(fs, name)), &s) == 0 && S_ISREG(s.st_mode))
|
const fsString* pathString = utf8ToString(getFilePath(fs, name));
|
||||||
|
s32 ret = tic_stat(pathString, &s);
|
||||||
|
freeString(pathString);
|
||||||
|
|
||||||
|
if(ret == 0 && S_ISREG(s.st_mode))
|
||||||
{
|
{
|
||||||
return s.st_mtime;
|
return s.st_mtime;
|
||||||
}
|
}
|
||||||
|
@ -855,7 +931,10 @@ void* fsLoadFile(FileSystem* fs, const char* name, s32* size)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FILE* file = tic_fopen(UTF8ToString(getFilePath(fs, name)), _S("rb"));
|
const fsString* pathString = utf8ToString(getFilePath(fs, name));
|
||||||
|
FILE* file = tic_fopen(pathString, _S("rb"));
|
||||||
|
freeString(pathString);
|
||||||
|
|
||||||
void* ptr = NULL;
|
void* ptr = NULL;
|
||||||
|
|
||||||
if(file)
|
if(file)
|
||||||
|
|
1
src/fs.h
1
src/fs.h
|
@ -64,7 +64,6 @@ u64 fsMDate(FileSystem* fs, const char* name);
|
||||||
|
|
||||||
const char* fsBasename(const char *path);
|
const char* fsBasename(const char *path);
|
||||||
const char* fsFilename(const char *path);
|
const char* fsFilename(const char *path);
|
||||||
const char* fsFullname(const char *path);
|
|
||||||
bool fsExists(const char* name);
|
bool fsExists(const char* name);
|
||||||
void* fsReadFile(const char* path, s32* size);
|
void* fsReadFile(const char* path, s32* size);
|
||||||
bool fsWriteFile(const char* path, const void* data, s32 size);
|
bool fsWriteFile(const char* path, const void* data, s32 size);
|
||||||
|
|
Loading…
Reference in New Issue