diff --git a/ctrtool/ctrtool.vcxproj b/ctrtool/ctrtool.vcxproj index 628d52f..d16bc57 100644 --- a/ctrtool/ctrtool.vcxproj +++ b/ctrtool/ctrtool.vcxproj @@ -99,6 +99,7 @@ + @@ -130,6 +131,7 @@ + diff --git a/ctrtool/ctrtool.vcxproj.filters b/ctrtool/ctrtool.vcxproj.filters index c51e94e..075c29d 100644 --- a/ctrtool/ctrtool.vcxproj.filters +++ b/ctrtool/ctrtool.vcxproj.filters @@ -114,6 +114,9 @@ Source Files\tinyxml + + Source Files + @@ -203,5 +206,8 @@ Header Files\tinyxml + + Header Files + \ No newline at end of file diff --git a/ctrtool/main.c b/ctrtool/main.c index c5ef33c..25b688d 100644 --- a/ctrtool/main.c +++ b/ctrtool/main.c @@ -102,7 +102,7 @@ int main(int argc, char* argv[]) char keysetfname[512] = "keys.xml"; keyset tmpkeys; unsigned int checkkeysetfile = 0; - + memset(&ctx, 0, sizeof(toolcontext)); ctx.actions = InfoFlag | ExtractFlag; ctx.filetype = FILETYPE_UNKNOWN; diff --git a/ctrtool/oschar.c b/ctrtool/oschar.c new file mode 100644 index 0000000..1ef05dd --- /dev/null +++ b/ctrtool/oschar.c @@ -0,0 +1,204 @@ +#include +#ifndef _WIN32 +#include +#endif +#include "oschar.h" + +int os_fstat(const oschar_t *path) +{ + struct _osstat st; + return os_stat(path, &st); +} + +uint64_t os_fsize(const oschar_t *path) +{ + struct _osstat st; + if (os_stat(path, &st) != 0) + return 0; + else + return st.st_size; +} + +int os_makedir(const oschar_t *dir) +{ +#ifdef _WIN32 + return _wmkdir(dir); +#else + return mkdir(dir, 0777); +#endif +} + +uint32_t utf16_strlen(const utf16char_t *str) +{ + uint32_t i; + for (i = 0; str[i] != 0x0; i++); + return i; +} + +void utf16_fputs(const utf16char_t *str, FILE *out) +{ + oschar_t *_str = os_CopyConvertUTF16Str(str); + os_fputs(_str, out); + free(_str); +} + +char* strcopy_8to8(const char *src) +{ + uint32_t src_len; + char *dst; + + if (!src) + return NULL; + + src_len = strlen(src); + + // Allocate memory for expanded string + dst = calloc(src_len + 1, sizeof(char)); + if (!dst) + return NULL; + + // Copy elements from src into dst + strncpy(dst, src, src_len); + + return dst; +} + +utf16char_t* strcopy_8to16(const char *src) +{ + uint32_t src_len, i; + utf16char_t *dst; + + if (!src) + return NULL; + + src_len = strlen(src); + + // Allocate memory for expanded string + dst = calloc(src_len + 1, sizeof(utf16char_t)); + if (!dst) + return NULL; + + // Copy elements from src into dst + for (i = 0; i < src_len; i++) + dst[i] = src[i]; + + return dst; +} + + +utf16char_t* strcopy_16to16(const utf16char_t *src) +{ + uint32_t src_len, i; + utf16char_t *dst; + + if (!src) + return NULL; + + src_len = utf16_strlen(src); + + // Allocate memory for expanded string + dst = calloc(src_len + 1, sizeof(utf16char_t)); + if (!dst) + return NULL; + + // Copy elements from src into dst + for (i = 0; i < src_len; i++) + dst[i] = src[i]; + + return dst; +} + +#ifndef _WIN32 +utf16char_t* strcopy_UTF8toUTF16(const char *src) +{ + uint32_t src_len, dst_len; + size_t in_bytes, out_bytes; + utf16char_t *dst; + char *in, *out; + + if (!src) + return NULL; + + src_len = strlen(src); + dst_len = src_len + 1; + + // Allocate memory for string + dst = calloc(dst_len, sizeof(utf16char_t)); + if (!dst) + return NULL; + + in = (char*)src; + out = (char*)dst; + in_bytes = src_len*sizeof(char); + out_bytes = dst_len*sizeof(utf16char_t); + + iconv_t cd = iconv_open("UTF-16LE", "UTF-8"); + iconv(cd, &in, &in_bytes, &out, &out_bytes); + return dst; +} + +char* strcopy_UTF16toUTF8(const utf16char_t *src) +{ + uint32_t src_len, dst_len; + size_t in_bytes, out_bytes; + char *dst; + char *in, *out; + + if (!src) + return NULL; + + src_len = utf16_strlen(src); + dst_len = src_len * 2; + + // Allocate memory for string + dst = calloc(dst_len, sizeof(char)); // twice the size, as UTF-8 will use up to two bytes for converted UTF16 chars afaik + if (!dst) + return NULL; + + in = (char*)src; + out = (char*)dst; + in_bytes = src_len*sizeof(uint16_t); + out_bytes = dst_len*sizeof(char); + + iconv_t cd = iconv_open("UTF-8", "UTF-16LE"); + iconv(cd, &in, &in_bytes, &out, &out_bytes); + return dst; +} +#endif + +oschar_t* os_AppendToPath(const oschar_t *src, const oschar_t *add) +{ + uint32_t len; + oschar_t *new_path; + + len = os_strlen(src) + os_strlen(add) + 0x10; + new_path = calloc(len, sizeof(oschar_t)); + +#ifdef _WIN32 + _snwprintf(new_path, len, L"%s%c%s", src, OS_PATH_SEPARATOR, add); +#else + snprintf(new_path, len, "%s%c%s", src, OS_PATH_SEPARATOR, add); +#endif + + return new_path; +} + +oschar_t* os_AppendUTF16StrToPath(const oschar_t *src, const utf16char_t *add) +{ + uint32_t len; + oschar_t *new_path, *_add; + + _add = os_CopyConvertUTF16Str(add); + + len = os_strlen(src) + os_strlen(_add) + 0x10; + new_path = calloc(len, sizeof(oschar_t)); + +#ifdef _WIN32 + _snwprintf(new_path, len, L"%s%c%s", src, OS_PATH_SEPARATOR, _add); +#else + snprintf(new_path, len, "%s%c%s", src, OS_PATH_SEPARATOR, _add); +#endif + + free(_add); + return new_path; +} \ No newline at end of file diff --git a/ctrtool/oschar.h b/ctrtool/oschar.h new file mode 100644 index 0000000..570a6ca --- /dev/null +++ b/ctrtool/oschar.h @@ -0,0 +1,97 @@ +#pragma once +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#include +#endif + +// Nintendo uses UTF16-LE chars for extended ASCII support +typedef uint16_t utf16char_t; + +// Native OS char type for unicode support +#ifdef _WIN32 +typedef wchar_t oschar_t; // UTF16-LE +#else +typedef char oschar_t; // UTF8 +#endif + + // Simple redirect macros for functions and types +#ifdef _WIN32 +#define os_strlen wcslen +#define os_strcmp wcscmp +#define os_fputs fputws + +#define os_CopyStr strcopy_16to16 +#define os_CopyConvertCharStr strcopy_8to16 +#define os_CopyConvertUTF16Str strcopy_16to16 +#define utf16_CopyStr strcopy_16to16 +#define utf16_CopyConvertOsStr strcopy_16to16 + +#define _osdirent _wdirent +#define _OSDIR _WDIR +#define os_readdir _wreaddir +#define os_opendir _wopendir +#define os_closedir _wclosedir +#define os_chdir _wchdir + +#define _osstat _stat64 +#define os_stat _wstat64 + +#define os_fopen _wfopen +#define OS_MODE_READ L"rb" +#define OS_MODE_WRITE L"wb" +#define OS_MODE_EDIT L"rb+" +#define OS_PATH_SEPARATOR '\\' +#else +#define os_strlen strlen +#define os_strcmp strcmp +#define os_fputs fputs + +#define os_CopyStr strcopy_8to8 +#define os_CopyConvertUTF16Str strcopy_UTF16toUTF8 +#define os_CopyConvertCharStr strcopy_8to8 +#define utf16_CopyStr strcopy_16to16 +#define utf16_CopyConvertOsStr strcopy_UTF8toUTF16 + +#define _osdirent dirent +#define _OSDIR DIR +#define os_readdir readdir +#define os_opendir opendir +#define os_closedir closedir +#define os_chdir chdir + +#define _osstat stat +#define os_stat stat + +#define os_fopen fopen +#define OS_MODE_READ "rb" +#define OS_MODE_WRITE "wb" +#define OS_MODE_EDIT "rb+" +#define OS_PATH_SEPARATOR '/' +#endif + +/* File related */ +int os_fstat(const oschar_t* path); +uint64_t os_fsize(const oschar_t* path); +int os_makedir(const oschar_t *dir); + +/* UTF16 String property functions */ +uint32_t utf16_strlen(const utf16char_t* str); +void utf16_fputs(const utf16char_t *str, FILE *out); + +/* String Copy and Conversion */ +char* strcopy_8to8(const char *src); +utf16char_t* strcopy_8to16(const char *src); +utf16char_t* strcopy_16to16(const utf16char_t *src); +#ifndef _WIN32 +utf16char_t* strcopy_UTF8toUTF16(const char *src); +char* strcopy_UTF16toUTF8(const utf16char_t *src); +#endif + +/* String Append and Create */ +oschar_t* os_AppendToPath(const oschar_t *src, const oschar_t *add); +oschar_t* os_AppendUTF16StrToPath(const oschar_t *src, const utf16char_t *add); \ No newline at end of file diff --git a/ctrtool/romfs.c b/ctrtool/romfs.c index df95fdc..3ff49df 100644 --- a/ctrtool/romfs.c +++ b/ctrtool/romfs.c @@ -96,8 +96,13 @@ void romfs_process(romfs_context* ctx, u32 actions) if (actions & InfoFlag) romfs_print(ctx); - romfs_visit_dir(ctx, 0, 0, actions, settings_get_romfs_dir_path(ctx->usersettings)); + if (settings_get_romfs_dir_path(ctx->usersettings)->valid) + ctx->extractdir = os_CopyConvertCharStr(settings_get_romfs_dir_path(ctx->usersettings)->pathname); + else + ctx->extractdir = NULL; + romfs_visit_dir(ctx, 0, 0, actions, ctx->extractdir); + free(ctx->extractdir); } int romfs_dirblock_read(romfs_context* ctx, u32 diroffset, u32 dirsize, void* buffer) @@ -171,12 +176,12 @@ int romfs_fileblock_readentry(romfs_context* ctx, u32 fileoffset, romfs_fileentr -void romfs_visit_dir(romfs_context* ctx, u32 diroffset, u32 depth, u32 actions, filepath* rootpath) +void romfs_visit_dir(romfs_context* ctx, u32 diroffset, u32 depth, u32 actions, const oschar_t* rootpath) { u32 siblingoffset; u32 childoffset; u32 fileoffset; - filepath currentpath; + oschar_t* currentpath; romfs_direntry* entry = &ctx->direntry; @@ -190,32 +195,39 @@ void romfs_visit_dir(romfs_context* ctx, u32 diroffset, u32 depth, u32 actions, // fwprintf(stdout, L"%ls\n", entry->name); - if (rootpath && rootpath->valid) + if (rootpath && os_strlen(rootpath)) { - filepath_copy(¤tpath, rootpath); - filepath_append_utf16(¤tpath, entry->name); - if (currentpath.valid) + if (utf16_strlen((const utf16char_t*)entry->name) > 0) + currentpath = os_AppendUTF16StrToPath(rootpath, (const utf16char_t*)entry->name); + else // root dir, use the provided extract path instead of the empty root name. + currentpath = os_CopyStr(rootpath); + + if (currentpath) { - makedir(currentpath.pathname); + os_makedir(currentpath); } else { - fprintf(stderr, "Error creating directory in root %s\n", rootpath->pathname); + fputs("Error creating directory in root ", stderr); + os_fputs(rootpath, stderr); + fputs("\n", stderr); return; } } else { - filepath_init(¤tpath); - + currentpath = os_CopyConvertUTF16Str((const utf16char_t*)entry->name); if (settings_get_list_romfs_files(ctx->usersettings)) { u32 i; for(i=0; iname); + os_fputs(currentpath, stdout); + fputs("\n", stdout); } + free(currentpath); + currentpath = NULL; } @@ -224,20 +236,22 @@ void romfs_visit_dir(romfs_context* ctx, u32 diroffset, u32 depth, u32 actions, fileoffset = getle32(entry->fileoffset); if (fileoffset != (~0)) - romfs_visit_file(ctx, fileoffset, depth+1, actions, ¤tpath); + romfs_visit_file(ctx, fileoffset, depth+1, actions, currentpath); if (childoffset != (~0)) - romfs_visit_dir(ctx, childoffset, depth+1, actions, ¤tpath); + romfs_visit_dir(ctx, childoffset, depth+1, actions, currentpath); if (siblingoffset != (~0)) romfs_visit_dir(ctx, siblingoffset, depth, actions, rootpath); + + free(currentpath); } -void romfs_visit_file(romfs_context* ctx, u32 fileoffset, u32 depth, u32 actions, filepath* rootpath) +void romfs_visit_file(romfs_context* ctx, u32 fileoffset, u32 depth, u32 actions, const oschar_t* rootpath) { u32 siblingoffset = 0; - filepath currentpath; + oschar_t* currentpath = NULL; romfs_fileentry* entry = &ctx->fileentry; @@ -250,55 +264,63 @@ void romfs_visit_file(romfs_context* ctx, u32 fileoffset, u32 depth, u32 actions // getle64(entry->datasize), getle32(entry->unknown)); // fwprintf(stdout, L"%ls\n", entry->name); - if (rootpath && rootpath->valid) + if (rootpath && os_strlen(rootpath)) { - filepath_copy(¤tpath, rootpath); - filepath_append_utf16(¤tpath, entry->name); - if (currentpath.valid) + currentpath = os_AppendUTF16StrToPath(rootpath, (const utf16char_t*)entry->name); + if (currentpath) { - fprintf(stdout, "Saving %s...\n", currentpath.pathname); - romfs_extract_datafile(ctx, getle64(entry->dataoffset), getle64(entry->datasize), ¤tpath); + fputs("Saving ", stdout); + os_fputs(currentpath, stdout); + fputs("...\n", stdout); + romfs_extract_datafile(ctx, getle64(entry->dataoffset), getle64(entry->datasize), currentpath); } else { - fprintf(stderr, "Error creating directory in root %s\n", rootpath->pathname); + fputs("Error creating file in root ", stderr); + os_fputs(rootpath, stderr); + fputs("\n", stderr); return; } } else { - filepath_init(¤tpath); + currentpath = os_CopyConvertUTF16Str((const utf16char_t*)entry->name); if (settings_get_list_romfs_files(ctx->usersettings)) { u32 i; for(i=0; iname); + os_fputs(currentpath, stdout); + fputs("\n", stdout); } + free(currentpath); + currentpath = NULL; } siblingoffset = getle32(entry->siblingoffset); if (siblingoffset != (~0)) romfs_visit_file(ctx, siblingoffset, depth, actions, rootpath); + + free(currentpath); } -void romfs_extract_datafile(romfs_context* ctx, u64 offset, u64 size, filepath* path) +void romfs_extract_datafile(romfs_context* ctx, u64 offset, u64 size, const oschar_t* path) { FILE* outfile = 0; u32 max; u8 buffer[4096]; - if (path == 0 || path->valid == 0) + if (path == NULL || os_strlen(path) == 0) goto clean; offset += ctx->datablockoffset; fseeko64(ctx->file, offset, SEEK_SET); - outfile = fopen(path->pathname, "wb"); - if (outfile == 0) + outfile = os_fopen(path, OS_MODE_WRITE); + if (outfile == NULL) { fprintf(stderr, "Error opening file for writing\n"); goto clean; diff --git a/ctrtool/romfs.h b/ctrtool/romfs.h index fa84bdf..c560ab4 100644 --- a/ctrtool/romfs.h +++ b/ctrtool/romfs.h @@ -4,7 +4,7 @@ #include "types.h" #include "info.h" #include "ctr.h" -#include "filepath.h" +#include "oschar.h" #include "settings.h" #include "ivfc.h" @@ -55,6 +55,7 @@ typedef struct typedef struct { FILE* file; + oschar_t* extractdir; settings* usersettings; u64 offset; u64 size; @@ -81,9 +82,9 @@ int romfs_dirblock_read(romfs_context* ctx, u32 diroffset, u32 dirsize, void* b int romfs_dirblock_readentry(romfs_context* ctx, u32 diroffset, romfs_direntry* entry); int romfs_fileblock_read(romfs_context* ctx, u32 fileoffset, u32 filesize, void* buffer); int romfs_fileblock_readentry(romfs_context* ctx, u32 fileoffset, romfs_fileentry* entry); -void romfs_visit_dir(romfs_context* ctx, u32 diroffset, u32 depth, u32 actions, filepath* rootpath); -void romfs_visit_file(romfs_context* ctx, u32 fileoffset, u32 depth, u32 actions, filepath* rootpath); -void romfs_extract_datafile(romfs_context* ctx, u64 offset, u64 size, filepath* path); +void romfs_visit_dir(romfs_context* ctx, u32 diroffset, u32 depth, u32 actions, const oschar_t* rootpath); +void romfs_visit_file(romfs_context* ctx, u32 fileoffset, u32 depth, u32 actions, const oschar_t* rootpath); +void romfs_extract_datafile(romfs_context* ctx, u64 offset, u64 size, const oschar_t* path); void romfs_process(romfs_context* ctx, u32 actions); void romfs_print(romfs_context* ctx); diff --git a/ctrtool/utils.c b/ctrtool/utils.c index c043586..bda20d9 100644 --- a/ctrtool/utils.c +++ b/ctrtool/utils.c @@ -1,6 +1,8 @@ #include +#include #include +#include #include #include #include "utils.h" @@ -202,4 +204,4 @@ u64 _fsize(const char *filename) else return st.st_size; #endif -} +} \ No newline at end of file diff --git a/makerom/makerom.vcxproj b/makerom/makerom.vcxproj index 7ec49cd..896eb09 100644 --- a/makerom/makerom.vcxproj +++ b/makerom/makerom.vcxproj @@ -67,7 +67,7 @@ make clean make rebuild WIN32;_DEBUG;$(NMakePreprocessorDefinitions) - C:\Program Files\mingw-w64\x86_64-5.2.0-win32-seh-rt_v4-rev0\mingw64\x86_64-w64-mingw32\include;$(IncludePath) + C:\Program Files\mingw-w64\x86_64-4.9.2-win32-seh-rt_v4-rev2\mingw64\x86_64-w64-mingw32\include make @@ -104,6 +104,7 @@ + @@ -188,7 +189,6 @@ - @@ -201,6 +201,7 @@ + @@ -236,7 +237,6 @@ - diff --git a/makerom/makerom.vcxproj.filters b/makerom/makerom.vcxproj.filters index 6603f55..bcb59c1 100644 --- a/makerom/makerom.vcxproj.filters +++ b/makerom/makerom.vcxproj.filters @@ -156,9 +156,6 @@ Header Files - - Header Files - Header Files @@ -339,6 +336,9 @@ Header Files + + Header Files + @@ -407,9 +407,6 @@ Source Files - - Source Files - Source Files @@ -479,6 +476,9 @@ Source Files\polarssl + + Source Files + diff --git a/makerom/ncsd.c b/makerom/ncsd.c index 29e4f76..ba2a23b 100644 --- a/makerom/ncsd.c +++ b/makerom/ncsd.c @@ -153,7 +153,7 @@ int ImportNcchForCci(cci_settings *set) bool CanCiaBeCci(u64 titleId, u16 count, tmd_content_chunk *content) { - if(GetTidCategory(titleId) != PROGRAM_ID_CATEGORY_APPLICATION && GetTidCategory(titleId) != PROGRAM_ID_CATEGORY_SYSTEM_APPLICATION) + if(GetTidCategory(titleId) != PROGRAM_ID_CATEGORY_APPLICATION) return false; if(count > CCI_MAX_CONTENT) @@ -222,6 +222,7 @@ int ProcessCiaForCci(cci_settings *set) return 0; } +/* This need to be more automagical */ void GetTitleSaveSize(cci_settings *set) { if(set->rsf->SystemControlInfo.SaveDataSize) diff --git a/makerom/oschar.c b/makerom/oschar.c new file mode 100644 index 0000000..1ef05dd --- /dev/null +++ b/makerom/oschar.c @@ -0,0 +1,204 @@ +#include +#ifndef _WIN32 +#include +#endif +#include "oschar.h" + +int os_fstat(const oschar_t *path) +{ + struct _osstat st; + return os_stat(path, &st); +} + +uint64_t os_fsize(const oschar_t *path) +{ + struct _osstat st; + if (os_stat(path, &st) != 0) + return 0; + else + return st.st_size; +} + +int os_makedir(const oschar_t *dir) +{ +#ifdef _WIN32 + return _wmkdir(dir); +#else + return mkdir(dir, 0777); +#endif +} + +uint32_t utf16_strlen(const utf16char_t *str) +{ + uint32_t i; + for (i = 0; str[i] != 0x0; i++); + return i; +} + +void utf16_fputs(const utf16char_t *str, FILE *out) +{ + oschar_t *_str = os_CopyConvertUTF16Str(str); + os_fputs(_str, out); + free(_str); +} + +char* strcopy_8to8(const char *src) +{ + uint32_t src_len; + char *dst; + + if (!src) + return NULL; + + src_len = strlen(src); + + // Allocate memory for expanded string + dst = calloc(src_len + 1, sizeof(char)); + if (!dst) + return NULL; + + // Copy elements from src into dst + strncpy(dst, src, src_len); + + return dst; +} + +utf16char_t* strcopy_8to16(const char *src) +{ + uint32_t src_len, i; + utf16char_t *dst; + + if (!src) + return NULL; + + src_len = strlen(src); + + // Allocate memory for expanded string + dst = calloc(src_len + 1, sizeof(utf16char_t)); + if (!dst) + return NULL; + + // Copy elements from src into dst + for (i = 0; i < src_len; i++) + dst[i] = src[i]; + + return dst; +} + + +utf16char_t* strcopy_16to16(const utf16char_t *src) +{ + uint32_t src_len, i; + utf16char_t *dst; + + if (!src) + return NULL; + + src_len = utf16_strlen(src); + + // Allocate memory for expanded string + dst = calloc(src_len + 1, sizeof(utf16char_t)); + if (!dst) + return NULL; + + // Copy elements from src into dst + for (i = 0; i < src_len; i++) + dst[i] = src[i]; + + return dst; +} + +#ifndef _WIN32 +utf16char_t* strcopy_UTF8toUTF16(const char *src) +{ + uint32_t src_len, dst_len; + size_t in_bytes, out_bytes; + utf16char_t *dst; + char *in, *out; + + if (!src) + return NULL; + + src_len = strlen(src); + dst_len = src_len + 1; + + // Allocate memory for string + dst = calloc(dst_len, sizeof(utf16char_t)); + if (!dst) + return NULL; + + in = (char*)src; + out = (char*)dst; + in_bytes = src_len*sizeof(char); + out_bytes = dst_len*sizeof(utf16char_t); + + iconv_t cd = iconv_open("UTF-16LE", "UTF-8"); + iconv(cd, &in, &in_bytes, &out, &out_bytes); + return dst; +} + +char* strcopy_UTF16toUTF8(const utf16char_t *src) +{ + uint32_t src_len, dst_len; + size_t in_bytes, out_bytes; + char *dst; + char *in, *out; + + if (!src) + return NULL; + + src_len = utf16_strlen(src); + dst_len = src_len * 2; + + // Allocate memory for string + dst = calloc(dst_len, sizeof(char)); // twice the size, as UTF-8 will use up to two bytes for converted UTF16 chars afaik + if (!dst) + return NULL; + + in = (char*)src; + out = (char*)dst; + in_bytes = src_len*sizeof(uint16_t); + out_bytes = dst_len*sizeof(char); + + iconv_t cd = iconv_open("UTF-8", "UTF-16LE"); + iconv(cd, &in, &in_bytes, &out, &out_bytes); + return dst; +} +#endif + +oschar_t* os_AppendToPath(const oschar_t *src, const oschar_t *add) +{ + uint32_t len; + oschar_t *new_path; + + len = os_strlen(src) + os_strlen(add) + 0x10; + new_path = calloc(len, sizeof(oschar_t)); + +#ifdef _WIN32 + _snwprintf(new_path, len, L"%s%c%s", src, OS_PATH_SEPARATOR, add); +#else + snprintf(new_path, len, "%s%c%s", src, OS_PATH_SEPARATOR, add); +#endif + + return new_path; +} + +oschar_t* os_AppendUTF16StrToPath(const oschar_t *src, const utf16char_t *add) +{ + uint32_t len; + oschar_t *new_path, *_add; + + _add = os_CopyConvertUTF16Str(add); + + len = os_strlen(src) + os_strlen(_add) + 0x10; + new_path = calloc(len, sizeof(oschar_t)); + +#ifdef _WIN32 + _snwprintf(new_path, len, L"%s%c%s", src, OS_PATH_SEPARATOR, _add); +#else + snprintf(new_path, len, "%s%c%s", src, OS_PATH_SEPARATOR, _add); +#endif + + free(_add); + return new_path; +} \ No newline at end of file diff --git a/makerom/oschar.h b/makerom/oschar.h new file mode 100644 index 0000000..570a6ca --- /dev/null +++ b/makerom/oschar.h @@ -0,0 +1,97 @@ +#pragma once +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#include +#endif + +// Nintendo uses UTF16-LE chars for extended ASCII support +typedef uint16_t utf16char_t; + +// Native OS char type for unicode support +#ifdef _WIN32 +typedef wchar_t oschar_t; // UTF16-LE +#else +typedef char oschar_t; // UTF8 +#endif + + // Simple redirect macros for functions and types +#ifdef _WIN32 +#define os_strlen wcslen +#define os_strcmp wcscmp +#define os_fputs fputws + +#define os_CopyStr strcopy_16to16 +#define os_CopyConvertCharStr strcopy_8to16 +#define os_CopyConvertUTF16Str strcopy_16to16 +#define utf16_CopyStr strcopy_16to16 +#define utf16_CopyConvertOsStr strcopy_16to16 + +#define _osdirent _wdirent +#define _OSDIR _WDIR +#define os_readdir _wreaddir +#define os_opendir _wopendir +#define os_closedir _wclosedir +#define os_chdir _wchdir + +#define _osstat _stat64 +#define os_stat _wstat64 + +#define os_fopen _wfopen +#define OS_MODE_READ L"rb" +#define OS_MODE_WRITE L"wb" +#define OS_MODE_EDIT L"rb+" +#define OS_PATH_SEPARATOR '\\' +#else +#define os_strlen strlen +#define os_strcmp strcmp +#define os_fputs fputs + +#define os_CopyStr strcopy_8to8 +#define os_CopyConvertUTF16Str strcopy_UTF16toUTF8 +#define os_CopyConvertCharStr strcopy_8to8 +#define utf16_CopyStr strcopy_16to16 +#define utf16_CopyConvertOsStr strcopy_UTF8toUTF16 + +#define _osdirent dirent +#define _OSDIR DIR +#define os_readdir readdir +#define os_opendir opendir +#define os_closedir closedir +#define os_chdir chdir + +#define _osstat stat +#define os_stat stat + +#define os_fopen fopen +#define OS_MODE_READ "rb" +#define OS_MODE_WRITE "wb" +#define OS_MODE_EDIT "rb+" +#define OS_PATH_SEPARATOR '/' +#endif + +/* File related */ +int os_fstat(const oschar_t* path); +uint64_t os_fsize(const oschar_t* path); +int os_makedir(const oschar_t *dir); + +/* UTF16 String property functions */ +uint32_t utf16_strlen(const utf16char_t* str); +void utf16_fputs(const utf16char_t *str, FILE *out); + +/* String Copy and Conversion */ +char* strcopy_8to8(const char *src); +utf16char_t* strcopy_8to16(const char *src); +utf16char_t* strcopy_16to16(const utf16char_t *src); +#ifndef _WIN32 +utf16char_t* strcopy_UTF8toUTF16(const char *src); +char* strcopy_UTF16toUTF8(const utf16char_t *src); +#endif + +/* String Append and Create */ +oschar_t* os_AppendToPath(const oschar_t *src, const oschar_t *add); +oschar_t* os_AppendUTF16StrToPath(const oschar_t *src, const utf16char_t *add); \ No newline at end of file diff --git a/makerom/romfs_fs.c b/makerom/romfs_fs.c index 4c09265..19c121a 100644 --- a/makerom/romfs_fs.c +++ b/makerom/romfs_fs.c @@ -1,6 +1,5 @@ #include "lib.h" #include "romfs_fs.h" -#include "utf.h" /* This is the FS interface for ROMFS generation */ /* Tested working on Windows/Linux/OSX */ @@ -8,109 +7,6 @@ int PopulateDir(romfs_dir *dir); int InitDir(romfs_dir *dir); int ManageDir(romfs_dir *dir); -u32 fs_strlen(const fs_char *str) -{ -#ifdef _WIN32 - return strlen_char16(str); -#else - return strlen(str); -#endif -} - -u32 romfs_strlen(const romfs_char *str) -{ - return strlen_char16(str); -} - -int fs_strcmp(const fs_char *str1, const fs_char *str2) -{ -#ifdef _WIN32 - return wcscmp(str1, str2); -#else - return strcmp(str1, str2); -#endif -} - - -FILE* fs_fopen(fs_char *path) -{ -#ifdef _WIN32 - return _wfopen(path, L"rb"); -#else - return fopen(path, "rb"); -#endif -} - -u64 fs_fsize(fs_char *path) -{ -#ifdef _WIN32 - return wGetFileSize64(path); -#else - return GetFileSize64(path); -#endif -} - -fs_char* fs_AppendToPath(const fs_char *src, const fs_char *add) -{ - u32 src_len, add_len; - fs_char *new_path; - - src_len = fs_strlen(src); - add_len = fs_strlen(add); - new_path = calloc(src_len + add_len + 0x10, sizeof(fs_char)); - -#ifdef _WIN32 - _snwprintf(new_path, src_len + add_len + 0x10, L"%s%c%s", src, FS_PATH_SEPARATOR, add); -#else - snprintf(new_path, src_len + add_len + 0x10, "%s%c%s", src, FS_PATH_SEPARATOR, add); -#endif - - return new_path; -} - -fs_char* fs_CopyStr(const fs_char *src) -{ -#ifdef _WIN32 - return strcopy_16to16(src); -#else - return strcopy_8to8(src); -#endif -} - -romfs_char* romfs_CopyConvertStr(const fs_char *src) -{ -#ifdef _WIN32 - return strcopy_16to16(src); -#else - return strcopy_utf8to16(src); -#endif -} - - -romfs_char* romfs_CopyStr(const romfs_char *src) -{ - return strcopy_16to16(src); -} - -void fs_fputs(const fs_char *str, FILE *out) -{ -#ifdef _WIN32 - fwprintf(out,L"%s", str); -#else - fprintf(out,"%s", str); -#endif -} - -void romfs_fputs(const romfs_char *str, FILE *out) -{ -#ifdef _WIN32 - fwprintf(out,L"%s", str); -#else - const char *name = (const char*)str; - for (u32 i = 0; i < romfs_strlen(str)*2; i += 2) - fputc(name[i],out); -#endif -} int InitDir(romfs_dir *dir) { @@ -148,13 +44,9 @@ int ManageDir(romfs_dir *dir) int OpenRootDir(const char *path, romfs_dir *dir) { // Create native FS path -#ifdef _WIN32 - dir->path = strcopy_8to16(path); -#else - dir->path = strcopy_8to8(path); -#endif + dir->path = os_CopyConvertCharStr(path); // Copy romfs name (empty string) - dir->name = romfs_CopyStr(ROMFS_EMPTY_PATH); + dir->name = utf16_CopyStr(ROMFS_EMPTY_PATH); dir->namesize = 0; return PopulateDir(dir); @@ -162,26 +54,26 @@ int OpenRootDir(const char *path, romfs_dir *dir) int PopulateDir(romfs_dir *dir) { - fs_DIR *dp, *tmp_dp; - struct fs_dirent *entry; + _OSDIR *dp, *tmp_dp; + struct _osdirent *entry; if (InitDir(dir)) return MEM_ERROR; // Open Directory - if((dp = fs_opendir(dir->path)) == NULL) + if((dp = os_opendir(dir->path)) == NULL) { printf("[ROMFS] Failed to open directory: \""); - fs_fputs(dir->path, stdout); + os_fputs(dir->path, stdout); printf("\"\n"); return -1; } // Process Entries - while ((entry = fs_readdir(dp)) != NULL) + while ((entry = os_readdir(dp)) != NULL) { // Skip if "." or ".." - if (fs_strcmp(entry->d_name, FS_CURRENT_DIR_PATH) == 0 || fs_strcmp(entry->d_name, FS_PARENT_DIR_PATH) == 0) + if (os_strcmp(entry->d_name, OS_CURRENT_DIR_PATH) == 0 || os_strcmp(entry->d_name, OS_PARENT_DIR_PATH) == 0) continue; // Ensures that there is always memory for child directory and file structs @@ -189,15 +81,15 @@ int PopulateDir(romfs_dir *dir) return MEM_ERROR; // Get native FS path - fs_char *path = fs_AppendToPath(dir->path, entry->d_name); + oschar_t *path = os_AppendToPath(dir->path, entry->d_name); // Opening directory with fs path to test if directory - if ((tmp_dp = fs_opendir(path)) != NULL) { - fs_closedir(tmp_dp); + if ((tmp_dp = os_opendir(path)) != NULL) { + os_closedir(tmp_dp); dir->child[dir->u_child].path = path; - dir->child[dir->u_child].name = romfs_CopyConvertStr(entry->d_name); - dir->child[dir->u_child].namesize = fs_strlen(entry->d_name)*sizeof(romfs_char); + dir->child[dir->u_child].name = utf16_CopyConvertOsStr(entry->d_name); + dir->child[dir->u_child].namesize = os_strlen(entry->d_name)*sizeof(utf16char_t); dir->u_child++; // Populate directory @@ -206,14 +98,14 @@ int PopulateDir(romfs_dir *dir) // Otherwise this is a file else { dir->file[dir->u_file].path = path; - dir->file[dir->u_file].name = romfs_CopyConvertStr(entry->d_name); - dir->file[dir->u_file].namesize = fs_strlen(entry->d_name)*sizeof(romfs_char); - dir->file[dir->u_file].size = fs_fsize(path); + dir->file[dir->u_file].name = utf16_CopyConvertOsStr(entry->d_name); + dir->file[dir->u_file].namesize = os_strlen(entry->d_name)*sizeof(utf16char_t); + dir->file[dir->u_file].size = os_fsize(path); dir->u_file++; } } - fs_closedir(dp); + os_closedir(dp); return 0; } @@ -225,7 +117,7 @@ void PrintDir(romfs_dir *dir, u32 depth) printf(" "); if (depth > 0) - romfs_fputs(dir->name, stdout); + utf16_fputs(dir->name, stdout); else printf("romfs:"); putchar('\n'); @@ -236,7 +128,7 @@ void PrintDir(romfs_dir *dir, u32 depth) { for(u32 j = 0; j < depth+1; j++) printf(" "); - romfs_fputs(dir->file[i].name, stdout); + utf16_fputs(dir->file[i].name, stdout); printf(" (0x%"PRIx64")\n", dir->file[i].size); } } diff --git a/makerom/romfs_fs.h b/makerom/romfs_fs.h index 0826f21..cd7704f 100644 --- a/makerom/romfs_fs.h +++ b/makerom/romfs_fs.h @@ -1,39 +1,18 @@ #pragma once - -#ifdef _WIN32 - #define romfs_char u16 - #define fs_char wchar_t - #define fs_dirent _wdirent - #define fs_DIR _WDIR - #define fs_readdir _wreaddir - #define fs_chdir _wchdir - #define fs_opendir _wopendir - #define fs_closedir _wclosedir - #define FS_PATH_SEPARATOR '\\' -#else - #define romfs_char u16 - #define fs_char char - #define fs_dirent dirent - #define fs_DIR DIR - #define fs_readdir readdir - #define fs_chdir chdir - #define fs_opendir opendir - #define fs_closedir closedir - #define FS_PATH_SEPARATOR '/' -#endif +#include "oschar.h" struct romfs_file { - fs_char *path; - romfs_char *name; + oschar_t *path; + utf16char_t *name; u32 namesize; u64 size; }; struct romfs_dir { - fs_char *path; - romfs_char *name; + oschar_t *path; + utf16char_t *name; u32 namesize; struct romfs_dir *child; @@ -48,22 +27,10 @@ struct romfs_dir typedef struct romfs_file romfs_file; typedef struct romfs_dir romfs_dir; -static const romfs_char ROMFS_EMPTY_PATH[2] = { 0 }; -static const fs_char FS_EMPTY_PATH[2] = { 0 }; -static const fs_char FS_CURRENT_DIR_PATH[2] = { '.' }; -static const fs_char FS_PARENT_DIR_PATH[3] = { '.', '.' }; - -u32 romfs_strlen(const romfs_char *str); -u32 fs_strlen(const fs_char *str); -int fs_strcmp(const fs_char *str1, const fs_char *str2); -FILE* fs_fopen(fs_char *path); -u64 fs_fsize(fs_char *path); - -fs_char* fs_AppendToPath(const fs_char *src, const fs_char *add); -fs_char* fs_CopyStr(const fs_char *src); -romfs_char* romfs_CopyStr(const romfs_char *src); -void fs_fputs(const fs_char *str, FILE *out); -void romfs_fputs(const romfs_char *str, FILE *out); +static const utf16char_t ROMFS_EMPTY_PATH[2] = { 0 }; +static const oschar_t OS_EMPTY_PATH[2] = { 0 }; +static const oschar_t OS_CURRENT_DIR_PATH[2] = { '.' }; +static const oschar_t OS_PARENT_DIR_PATH[3] = { '.', '.' }; int OpenRootDir(const char *path, romfs_dir *dir); void PrintDir(romfs_dir *dir, u32 depth); diff --git a/makerom/romfs_gen.c b/makerom/romfs_gen.c index 9d8a97e..30a7d91 100644 --- a/makerom/romfs_gen.c +++ b/makerom/romfs_gen.c @@ -19,7 +19,7 @@ void PopulateRomfs(romfs_buildctx *ctx); void BuildRomfsHeader(romfs_buildctx *ctx); void BuildIvfcHeader(romfs_buildctx *ctx); void GenIvfcHashTree(romfs_buildctx *ctx); -u32 CalcPathHash(u32 parent, const romfs_char* path); +u32 CalcPathHash(u32 parent, const utf16char_t* path); int PrepareBuildRomFsBinary(ncch_settings *ncchset, romfs_buildctx *ctx) @@ -32,7 +32,6 @@ int PrepareBuildRomFsBinary(ncch_settings *ncchset, romfs_buildctx *ctx) /* Import FS and process */ OpenRootDir(ncchset->rsfSet->RomFs.RootPath,fs_raw); FilterRomFS(fs_raw,ctx->fs,filter_criteria); - /* free unfiltered FS */ FreeDir(fs_raw); @@ -186,10 +185,10 @@ int FilterRomFS(romfs_dir *fs_raw, romfs_dir *fs_filtered, void *filter_criteria if(!IsDirWanted(fs_raw,filter_criteria)) return 0; - fs_filtered->path = fs_CopyStr(fs_raw->path); + fs_filtered->path = os_CopyStr(fs_raw->path); fs_filtered->namesize = fs_raw->namesize; - fs_filtered->name = romfs_CopyStr(fs_raw->name); + fs_filtered->name = utf16_CopyStr(fs_raw->name); fs_filtered->u_child = 0; fs_filtered->m_child = fs_raw->u_child; @@ -212,10 +211,10 @@ int FilterRomFS(romfs_dir *fs_raw, romfs_dir *fs_filtered, void *filter_criteria { if(IsFileWanted(&fs_raw->file[i],filter_criteria)) { - fs_filtered->file[fs_filtered->u_file].path = fs_CopyStr(fs_raw->file[i].path); + fs_filtered->file[fs_filtered->u_file].path = os_CopyStr(fs_raw->file[i].path); fs_filtered->file[fs_filtered->u_file].namesize = fs_raw->file[i].namesize; - fs_filtered->file[fs_filtered->u_file].name = romfs_CopyStr(fs_raw->file[i].name); + fs_filtered->file[fs_filtered->u_file].name = utf16_CopyStr(fs_raw->file[i].name); fs_filtered->file[fs_filtered->u_file].size = fs_raw->file[i].size; @@ -277,13 +276,13 @@ void BuildRomfsHeader(romfs_buildctx *ctx) } } -u32 GetFileHashTableIndex(romfs_buildctx *ctx, u32 parent, const romfs_char *path) +u32 GetFileHashTableIndex(romfs_buildctx *ctx, u32 parent, const utf16char_t *path) { u32 hash = CalcPathHash(parent, path); return hash % ctx->m_fileHashTable; } -u32 GetDirHashTableIndex(romfs_buildctx *ctx, u32 parent, const romfs_char* path) +u32 GetDirHashTableIndex(romfs_buildctx *ctx, u32 parent, const utf16char_t* path) { u32 hash = CalcPathHash(parent, path); return hash % ctx->m_dirHashTable; @@ -317,11 +316,11 @@ void AddFileToRomfs(romfs_buildctx *ctx, romfs_file *file, u32 parent, u32 sibli if (ctx->verbose) { printf("[ROMFS] Reading \""); - fs_fputs(file->path, stdout); + os_fputs(file->path, stdout); printf("\"... "); } - FILE *fp = fs_fopen(file->path); + FILE *fp = os_fopen(file->path, OS_MODE_READ); fread(data_pos, file->size, 1, fp); fclose(fp); @@ -463,9 +462,9 @@ void GenIvfcHashTree(romfs_buildctx *ctx) return; } -u32 CalcPathHash(u32 parent, const romfs_char* path) +u32 CalcPathHash(u32 parent, const utf16char_t* path) { - u32 len = romfs_strlen(path); + u32 len = utf16_strlen(path); u32 hash = parent ^ 123456789; for( u32 i = 0; i < len; i++ ) { diff --git a/makerom/romfs_gen.h b/makerom/romfs_gen.h index b355934..75db968 100644 --- a/makerom/romfs_gen.h +++ b/makerom/romfs_gen.h @@ -1,4 +1,5 @@ #pragma once +#include "romfs.h" int PrepareBuildRomFsBinary(ncch_settings *ncchset, romfs_buildctx *ctx); int BuildRomFsBinary(romfs_buildctx *ctx); diff --git a/makerom/types.h b/makerom/types.h index 4f8696f..e9984b5 100644 --- a/makerom/types.h +++ b/makerom/types.h @@ -44,4 +44,4 @@ typedef uint64_t u64; typedef int8_t s8; typedef int16_t s16; typedef int32_t s32; -typedef int64_t s64; +typedef int64_t s64; \ No newline at end of file diff --git a/makerom/utf.c b/makerom/utf.c deleted file mode 100644 index 6ecadef..0000000 --- a/makerom/utf.c +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - -/* --------------------------------------------------------------------- - - Conversions between UTF32, UTF-16, and UTF-8. Source code file. - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Sept 2001: fixed const & error conditions per - mods suggested by S. Parent & A. Lillich. - June 2002: Tim Dodd added detection and handling of incomplete - source sequences, enhanced error detection, added casts - to eliminate compiler warnings. - July 2003: slight mods to back out aggressive FFFE detection. - Jan 2004: updated switches in from-UTF8 conversions. - Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. - - See the header file "utf.h" for complete documentation. - ------------------------------------------------------------------------- */ - - -#include "utf.h" -#ifdef CVTUTF_DEBUG -#include -#endif - -static const int halfShift = 10; /* used for shifting by 10 bits */ - -static const UTF32 halfBase = 0x0010000UL; -static const UTF32 halfMask = 0x3FFUL; - -#define UNI_SUR_HIGH_START (UTF32)0xD800 -#define UNI_SUR_HIGH_END (UTF32)0xDBFF -#define UNI_SUR_LOW_START (UTF32)0xDC00 -#define UNI_SUR_LOW_END (UTF32)0xDFFF -#define false 0 -#define true 1 - -/* --------------------------------------------------------------------- */ - -/* - * Index into the table below with the first byte of a UTF-8 sequence to - * get the number of trailing bytes that are supposed to follow it. - * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is - * left as-is for anyone who may want to do such conversion, which was - * allowed in earlier algorithms. - */ -static const char trailingBytesForUTF8[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 -}; - -/* - * Magic values subtracted from a buffer value during UTF8 conversion. - * This table contains as many values as there might be trailing bytes - * in a UTF-8 sequence. - */ -static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, - 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; - -/* - * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed - * into the first byte, depending on how many bytes follow. There are - * as many entries in this table as there are UTF-8 sequence types. - * (I.e., one byte sequence, two byte... etc.). Remember that sequencs - * for *legal* UTF-8 will be 4 or fewer bytes total. - */ -static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -/* --------------------------------------------------------------------- */ - -/* The interface converts a whole buffer to avoid function-call overhead. - * Constants have been gathered. Loops & conditionals have been removed as - * much as possible for efficiency, in favor of drop-through switches. - * (See "Note A" at the bottom of the file for equivalent code.) - * If your compiler supports it, the "isLegalUTF8" call can be turned - * into an inline function. - */ - - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF32toUTF16 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF32* source = *sourceStart; - UTF16* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - if (target >= targetEnd) { - result = targetExhausted; break; - } - ch = *source++; - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_LEGAL_UTF32) { - if (flags == strictConversion) { - result = sourceIllegal; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - --source; /* Back up source pointer! */ - result = targetExhausted; break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF16toUTF32 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF16* source = *sourceStart; - UTF32* target = *targetStart; - UTF32 ch, ch2; - while (source < sourceEnd) { - const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - if (target >= targetEnd) { - source = oldSource; /* Back up source pointer! */ - result = targetExhausted; break; - } - *target++ = ch; - } - *sourceStart = source; - *targetStart = target; -#ifdef CVTUTF_DEBUG -if (result == sourceIllegal) { - fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); - fflush(stderr); -} -#endif - return result; -} -ConversionResult ConvertUTF16toUTF8 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF16* source = *sourceStart; - UTF8* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - UTF32 ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* Figure out how many bytes the result will require */ - if (ch < (UTF32)0x80) { bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; - } else if (ch < (UTF32)0x110000) { bytesToWrite = 4; - } else { bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - } - - target += bytesToWrite; - if (target > targetEnd) { - source = oldSource; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF32toUTF8 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF32* source = *sourceStart; - UTF8* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - ch = *source++; - if (flags == strictConversion ) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* - * Figure out how many bytes the result will require. Turn any - * illegally large UTF32 things (> Plane 17) into replacement chars. - */ - if (ch < (UTF32)0x80) { bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; - } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4; - } else { bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - result = sourceIllegal; - } - - target += bytesToWrite; - if (target > targetEnd) { - --source; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -/* - * Utility routine to tell whether a sequence of bytes is legal UTF-8. - * This must be called with the length pre-determined by the first byte. - * If not calling this from ConvertUTF8to*, then the length can be set by: - * length = trailingBytesForUTF8[*source]+1; - * and the sequence is illegal right away if there aren't that many bytes - * available. - * If presented with a length > 4, this returns false. The Unicode - * definition of UTF-8 goes up to 4-byte sequences. - */ - -static Boolean isLegalUTF8(const UTF8 *source, int length) { - UTF8 a; - const UTF8 *srcptr = source+length; - switch (length) { - default: return false; - /* Everything else falls through when "true"... */ - case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 2: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - - switch (*source) { - /* no fall-through in this inner switch */ - case 0xE0: if (a < 0xA0) return false; break; - case 0xED: if (a > 0x9F) return false; break; - case 0xF0: if (a < 0x90) return false; break; - case 0xF4: if (a > 0x8F) return false; break; - default: if (a < 0x80) return false; - } - - case 1: if (*source >= 0x80 && *source < 0xC2) return false; - } - if (*source > 0xF4) return false; - return true; -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return whether a UTF-8 sequence is legal or not. - * This is not used here; it's just exported. - */ -Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { - int length = trailingBytesForUTF8[*source]+1; - if (length > sourceEnd - source) { - return false; - } - return isLegalUTF8(source, length); -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return the total number of bytes in a codepoint - * represented in UTF-8, given the value of the first byte. - */ -unsigned getNumBytesForUTF8(UTF8 first) { - return trailingBytesForUTF8[first] + 1; -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return whether a UTF-8 string is legal or not. - * This is not used here; it's just exported. - */ -Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd) { - while (*source != sourceEnd) { - int length = trailingBytesForUTF8[**source] + 1; - if (length > sourceEnd - *source || !isLegalUTF8(*source, length)) - return false; - *source += length; - } - return true; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF8toUTF16 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF8* source = *sourceStart; - UTF16* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (extraBytesToRead >= sourceEnd - source) { - result = sourceExhausted; break; - } - /* Do this check whether lenient or strict */ - if (!isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_UTF16) { - if (flags == strictConversion) { - result = sourceIllegal; - source -= (extraBytesToRead+1); /* return to the start */ - break; /* Bail out; shouldn't continue */ - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF8toUTF32 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF8* source = *sourceStart; - UTF32* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (extraBytesToRead >= sourceEnd - source) { - result = sourceExhausted; break; - } - /* Do this check whether lenient or strict */ - if (!isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; - case 4: ch += *source++; ch <<= 6; - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up the source pointer! */ - result = targetExhausted; break; - } - if (ch <= UNI_MAX_LEGAL_UTF32) { - /* - * UTF-16 surrogate values are illegal in UTF-32, and anything - * over Plane 17 (> 0x10FFFF) is illegal. - */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = ch; - } - } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ - result = sourceIllegal; - *target++ = UNI_REPLACEMENT_CHAR; - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- - - Note A. - The fall-through switches in UTF-8 reading code save a - temp variable, some decrements & conditionals. The switches - are equivalent to the following loop: - { - int tmpBytesToRead = extraBytesToRead+1; - do { - ch += *source++; - --tmpBytesToRead; - if (tmpBytesToRead) ch <<= 6; - } while (tmpBytesToRead > 0); - } - In UTF-8 writing code, the switches on "bytesToWrite" are - similarly unrolled loops. - - --------------------------------------------------------------------- */ diff --git a/makerom/utf.h b/makerom/utf.h deleted file mode 100644 index 0b74f16..0000000 --- a/makerom/utf.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - -/* --------------------------------------------------------------------- - - Conversions between UTF32, UTF-16, and UTF-8. Header file. - - Several funtions are included here, forming a complete set of - conversions between the three formats. UTF-7 is not included - here, but is handled in a separate source file. - - Each of these routines takes pointers to input buffers and output - buffers. The input buffers are const. - - Each routine converts the text between *sourceStart and sourceEnd, - putting the result into the buffer between *targetStart and - targetEnd. Note: the end pointers are *after* the last item: e.g. - *(sourceEnd - 1) is the last item. - - The return result indicates whether the conversion was successful, - and if not, whether the problem was in the source or target buffers. - (Only the first encountered problem is indicated.) - - After the conversion, *sourceStart and *targetStart are both - updated to point to the end of last text successfully converted in - the respective buffers. - - Input parameters: - sourceStart - pointer to a pointer to the source buffer. - The contents of this are modified on return so that - it points at the next thing to be converted. - targetStart - similarly, pointer to pointer to the target buffer. - sourceEnd, targetEnd - respectively pointers to the ends of the - two buffers, for overflow checking only. - - These conversion functions take a ConversionFlags argument. When this - flag is set to strict, both irregular sequences and isolated surrogates - will cause an error. When the flag is set to lenient, both irregular - sequences and isolated surrogates are converted. - - Whether the flag is strict or lenient, all illegal sequences will cause - an error return. This includes sequences such as: , , - or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code - must check for illegal sequences. - - When the flag is set to lenient, characters over 0x10FFFF are converted - to the replacement character; otherwise (when the flag is set to strict) - they constitute an error. - - Output parameters: - The value "sourceIllegal" is returned from some routines if the input - sequence is malformed. When "sourceIllegal" is returned, the source - value will point to the illegal value that caused the problem. E.g., - in UTF-8 when a sequence is malformed, it points to the start of the - malformed sequence. - - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Fixes & updates, Sept 2001. - ------------------------------------------------------------------------- */ - -#pragma once - -/* --------------------------------------------------------------------- - The following 4 definitions are compiler-specific. - The C standard does not guarantee that wchar_t has at least - 16 bits, so wchar_t is no less portable than unsigned short! - All should be unsigned values to avoid sign extension during - bit mask & shift operations. ------------------------------------------------------------------------- */ - -typedef unsigned int UTF32; /* at least 32 bits */ -typedef unsigned short UTF16; /* at least 16 bits */ -typedef unsigned char UTF8; /* typically 8 bits */ -typedef unsigned char Boolean; /* 0 or 1 */ - -/* Some fundamental constants */ -#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD -#define UNI_MAX_BMP (UTF32)0x0000FFFF -#define UNI_MAX_UTF16 (UTF32)0x0010FFFF -#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF -#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF - -#define UNI_MAX_UTF8_BYTES_PER_CODE_POINT 4 - -#define UNI_UTF16_BYTE_ORDER_MARK_NATIVE 0xFEFF -#define UNI_UTF16_BYTE_ORDER_MARK_SWAPPED 0xFFFE - -typedef enum { - conversionOK, /* conversion successful */ - sourceExhausted, /* partial character in source, but hit end */ - targetExhausted, /* insuff. room in target for conversion */ - sourceIllegal /* source sequence is illegal/malformed */ -} ConversionResult; - -typedef enum { - strictConversion = 0, - lenientConversion -} ConversionFlags; - -ConversionResult ConvertUTF32toUTF16 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF16toUTF32 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF16toUTF8 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF32toUTF8 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); - -Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); - -unsigned getNumBytesForUTF8(UTF8 first); - -Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd); - -ConversionResult ConvertUTF8toUTF16 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF8toUTF32 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); diff --git a/makerom/utils.c b/makerom/utils.c index 849126c..92303ed 100644 --- a/makerom/utils.c +++ b/makerom/utils.c @@ -1,5 +1,7 @@ #include "lib.h" -#include "utf.h" +#ifndef _WIN32 +#include +#endif #include "polarssl/base64.h" @@ -106,95 +108,6 @@ void memdump(FILE* fout, const char* prefix, const u8* data, u32 size) } } -u32 strlen_char16(const u16 *str) -{ - u32 i; - for (i = 0; str[i] != 0x0; i++); - return i; -} - -char* strcopy_8to8(const char *src) -{ - if (!src) - return NULL; - - u32 src_len = strlen(src); - - // Allocate memory for expanded string - char *dst = calloc(src_len + 1, sizeof(u8)); - if (!dst) - return NULL; - - // Copy elements from src into dst - strncpy(dst, src, src_len); - - return dst; -} - -u16* strcopy_8to16(const char *src) -{ - if (!src) - return NULL; - - u32 src_len = strlen(src); - - // Allocate memory for expanded string - u16 *dst = calloc(src_len+1, sizeof(u16)); - if (!dst) - return NULL; - - // Copy elements from src into dst - for (u32 i = 0; i < src_len; i++) - dst[i] = src[i]; - - return dst; -} - - -u16* strcopy_16to16(const u16 *src) -{ - if (!src) - return NULL; - - u32 src_len = strlen_char16(src); - - // Allocate memory for expanded string - u16 *dst = calloc(src_len + 1, sizeof(u16)); - if (!dst) - return NULL; - - // Copy elements from src into dst - for (u32 i = 0; i < src_len; i++) - dst[i] = src[i]; - - return dst; -} - -#ifndef _WIN32 -u16* strcopy_utf8to16(const char *src) -{ - if (!src) - return NULL; - - u32 src_len = strlen(src); - - // Allocate memory for expanded string - u16 *dst = calloc(src_len + 1, sizeof(u16)); - if (!dst) - return NULL; - - UTF16 *target_start = dst; - UTF16 *target_end = (target_start + (src_len*sizeof(u16))); - - UTF8 *src_start = (UTF8*)src; - UTF8 *src_end = (UTF8*)(src + src_len*sizeof(char)); - - ConvertUTF8toUTF16((const UTF8 **)&src_start, src_end, &target_start, target_end, strictConversion); - - return dst; -} -#endif - // Base64 bool IsValidB64Char(char chr) { @@ -347,15 +260,6 @@ int TruncateFile64(char *filename, u64 filelen) #endif } -// Wide Char IO -#ifdef _WIN32 -u64 wGetFileSize64(u16 *filename) -{ - struct _stat64 st; - _wstat64((wchar_t*)filename, &st); - return st.st_size; -} -#endif //IO Misc u8* ImportFile(char *file, u64 size) diff --git a/makerom/utils.h b/makerom/utils.h index e21a8af..6370e41 100644 --- a/makerom/utils.h +++ b/makerom/utils.h @@ -20,13 +20,6 @@ u64 max64(u64 a, u64 b); // Strings void memdump(FILE* fout, const char* prefix, const const u8* data, u32 size); char* replace_filextention(const char *input, const char *extention); -u32 strlen_char16(const u16 *str); -char* strcopy_8to8(const char *src); -u16* strcopy_8to16(const char *src); -u16* strcopy_16to16(const u16 *src); -#ifndef _WIN32 -u16* strcopy_utf8to16(const char *src); -#endif // Base64 bool IsValidB64Char(char chr); @@ -45,14 +38,8 @@ u64 u64GetRand(void); bool AssertFile(char *filename); u64 GetFileSize64(char *filename); int makedir(const char* dir); -char *getcwdir(char *buffer,int maxlen); int TruncateFile64(char *filename, u64 filelen); -//Wide Char IO -#ifdef _WIN32 -u64 wGetFileSize64(u16 *filename); -#endif - //IO Misc u8* ImportFile(char *file, u64 size); void WriteBuffer(const void *buffer, u64 size, u64 offset, FILE *output);