From 168ecf8825813c570793510a0314130c3fb18385 Mon Sep 17 00:00:00 2001 From: Exzap <13877693+Exzap@users.noreply.github.com> Date: Fri, 9 Sep 2022 22:50:33 +0200 Subject: [PATCH] FSC: Use utf8 path strings instead of wchar Also introduced helper function _utf8ToPath() to convert a utf8-encoded string to fs::path --- src/Cafe/Filesystem/fsc.cpp | 18 +++++++--------- src/Cafe/Filesystem/fsc.h | 8 +++---- src/Cafe/Filesystem/fscDeviceHostFS.cpp | 26 +++++++++++------------ src/Cafe/Filesystem/fscDeviceRedirect.cpp | 5 ++--- src/Cafe/Filesystem/fscDeviceWua.cpp | 6 ++---- src/Cafe/Filesystem/fscDeviceWud.cpp | 7 +++--- src/Cafe/TitleList/TitleList.cpp | 2 +- src/Common/precompiled.h | 7 +++--- src/config/ActiveSettings.h | 2 +- 9 files changed, 38 insertions(+), 43 deletions(-) diff --git a/src/Cafe/Filesystem/fsc.cpp b/src/Cafe/Filesystem/fsc.cpp index 1c541a7f..d7d9971f 100644 --- a/src/Cafe/Filesystem/fsc.cpp +++ b/src/Cafe/Filesystem/fsc.cpp @@ -183,7 +183,7 @@ void fsc_unmountAll() } // lookup virtual path and find mounted device and relative device directory -bool fsc_lookupPath(const char* path, std::wstring& devicePathOut, fscDeviceC** fscDeviceOut, void** ctxOut, sint32 priority = FSC_PRIORITY_BASE) +bool fsc_lookupPath(const char* path, std::string& devicePathOut, fscDeviceC** fscDeviceOut, void** ctxOut, sint32 priority = FSC_PRIORITY_BASE) { FSCPath parsedPath(path); FSCMountPathNode* nodeParent = s_fscRootNodePerPrio[priority]; @@ -214,11 +214,11 @@ bool fsc_lookupPath(const char* path, std::wstring& devicePathOut, fscDeviceC** { if (nodeParent->device) { - devicePathOut = boost::nowide::widen(nodeParent->deviceTargetPath); + devicePathOut = nodeParent->deviceTargetPath; for (size_t f = i; f < parsedPath.GetNodeCount(); f++) { auto nodeName = parsedPath.GetNodeName(f); - devicePathOut.append(boost::nowide::widen(nodeName)); + devicePathOut.append(nodeName); if (f < (parsedPath.GetNodeCount() - 1)) devicePathOut.push_back('/'); } @@ -353,11 +353,9 @@ private: FSCVirtualFile* fsc_open(const char* path, FSC_ACCESS_FLAG accessFlags, sint32* fscStatus, sint32 maxPriority) { cemu_assert_debug(HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE) || HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR)); // must open either file or directory - FSCVirtualFile* dirList[FSC_PRIORITY_COUNT]; uint8 dirListCount = 0; - - std::wstring devicePath; + std::string devicePath; fscDeviceC* fscDevice = NULL; *fscStatus = FSC_STATUS_UNDEFINED; void* ctx; @@ -448,7 +446,7 @@ bool fsc_createDir(char* path, sint32* fscStatus) fscDeviceC* fscDevice = NULL; *fscStatus = FSC_STATUS_UNDEFINED; void* ctx; - std::wstring devicePath; + std::string devicePath; fscEnter(); if( fsc_lookupPath(path, devicePath, &fscDevice, &ctx) ) { @@ -465,8 +463,8 @@ bool fsc_createDir(char* path, sint32* fscStatus) */ bool fsc_rename(char* srcPath, char* dstPath, sint32* fscStatus) { - std::wstring srcDevicePath; - std::wstring dstDevicePath; + std::string srcDevicePath; + std::string dstDevicePath; void* srcCtx; void* dstCtx; fscDeviceC* fscSrcDevice = NULL; @@ -485,7 +483,7 @@ bool fsc_rename(char* srcPath, char* dstPath, sint32* fscStatus) */ bool fsc_remove(char* path, sint32* fscStatus) { - std::wstring devicePath; + std::string devicePath; fscDeviceC* fscDevice = NULL; *fscStatus = FSC_STATUS_UNDEFINED; void* ctx; diff --git a/src/Cafe/Filesystem/fsc.h b/src/Cafe/Filesystem/fsc.h index a475bfb2..9420d69d 100644 --- a/src/Cafe/Filesystem/fsc.h +++ b/src/Cafe/Filesystem/fsc.h @@ -57,25 +57,25 @@ struct FSCDirEntry class fscDeviceC { public: - virtual FSCVirtualFile* fscDeviceOpenByPath(std::wstring_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) + virtual FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) { cemu_assert_unimplemented(); return nullptr; } - virtual bool fscDeviceCreateDir(std::wstring_view path, void* ctx, sint32* fscStatus) + virtual bool fscDeviceCreateDir(std::string_view path, void* ctx, sint32* fscStatus) { cemu_assert_unimplemented(); return false; } - virtual bool fscDeviceRemoveFileOrDir(std::wstring_view path, void* ctx, sint32* fscStatus) + virtual bool fscDeviceRemoveFileOrDir(std::string_view path, void* ctx, sint32* fscStatus) { cemu_assert_unimplemented(); return false; } - virtual bool fscDeviceRename(std::wstring_view srcPath, std::wstring_view dstPath, void* ctx, sint32* fscStatus) + virtual bool fscDeviceRename(std::string_view srcPath, std::string_view dstPath, void* ctx, sint32* fscStatus) { cemu_assert_unimplemented(); return false; diff --git a/src/Cafe/Filesystem/fscDeviceHostFS.cpp b/src/Cafe/Filesystem/fscDeviceHostFS.cpp index d3f93927..bd446f50 100644 --- a/src/Cafe/Filesystem/fscDeviceHostFS.cpp +++ b/src/Cafe/Filesystem/fscDeviceHostFS.cpp @@ -221,36 +221,36 @@ FSCVirtualFile* FSCVirtualFile_Host::OpenFile(const fs::path& path, FSC_ACCESS_F class fscDeviceHostFSC : public fscDeviceC { public: - FSCVirtualFile* fscDeviceOpenByPath(std::wstring_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override + FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override { *fscStatus = FSC_STATUS_OK; - FSCVirtualFile* vf = FSCVirtualFile_Host::OpenFile(path, accessFlags, *fscStatus); + FSCVirtualFile* vf = FSCVirtualFile_Host::OpenFile(_utf8ToPath(path), accessFlags, *fscStatus); cemu_assert_debug((bool)vf == (*fscStatus == FSC_STATUS_OK)); return vf; } - bool fscDeviceCreateDir(std::wstring_view path, void* ctx, sint32* fscStatus) override + bool fscDeviceCreateDir(std::string_view path, void* ctx, sint32* fscStatus) override { - fs::path dirPath(path); - if (fs::exists(path)) + fs::path dirPath = _utf8ToPath(path); + if (fs::exists(dirPath)) { if (!fs::is_directory(dirPath)) - cemuLog_force("CreateDir: {} already exists but is not a directory", _utf8Wrapper(dirPath)); + cemuLog_force("CreateDir: {} already exists but is not a directory", path); *fscStatus = FSC_STATUS_ALREADY_EXISTS; return false; } std::error_code ec; bool r = fs::create_directories(dirPath, ec); - if(!r) - cemuLog_force("CreateDir: Failed to create {}", _utf8Wrapper(dirPath)); + if (!r) + cemuLog_force("CreateDir: Failed to create {}", path); *fscStatus = FSC_STATUS_OK; return true; } - bool fscDeviceRemoveFileOrDir(std::wstring_view path, void* ctx, sint32* fscStatus) override + bool fscDeviceRemoveFileOrDir(std::string_view path, void* ctx, sint32* fscStatus) override { *fscStatus = FSC_STATUS_OK; - fs::path _path(path); + fs::path _path = _utf8ToPath(path); std::error_code ec; if (!fs::exists(_path, ec)) { @@ -266,11 +266,11 @@ public: return true; } - bool fscDeviceRename(std::wstring_view srcPath, std::wstring_view dstPath, void* ctx, sint32* fscStatus) override + bool fscDeviceRename(std::string_view srcPath, std::string_view dstPath, void* ctx, sint32* fscStatus) override { *fscStatus = FSC_STATUS_OK; - fs::path _srcPath(srcPath); - fs::path _dstPath(dstPath); + fs::path _srcPath = _utf8ToPath(srcPath); + fs::path _dstPath = _utf8ToPath(dstPath); std::error_code ec; if (!fs::exists(_srcPath, ec)) { diff --git a/src/Cafe/Filesystem/fscDeviceRedirect.cpp b/src/Cafe/Filesystem/fscDeviceRedirect.cpp index d5245006..d25bff86 100644 --- a/src/Cafe/Filesystem/fscDeviceRedirect.cpp +++ b/src/Cafe/Filesystem/fscDeviceRedirect.cpp @@ -29,11 +29,10 @@ void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& t class fscDeviceTypeRedirect : public fscDeviceC { - FSCVirtualFile* fscDeviceOpenByPath(std::wstring_view pathW, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override + FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override { RedirectEntry* redirectionEntry; - std::string pathTmp = boost::nowide::narrow(pathW); - if (redirectTree.getFile(pathTmp, redirectionEntry)) + if (redirectTree.getFile(path, redirectionEntry)) return FSCVirtualFile_Host::OpenFile(redirectionEntry->dstPath, accessFlags, *fscStatus); return nullptr; } diff --git a/src/Cafe/Filesystem/fscDeviceWua.cpp b/src/Cafe/Filesystem/fscDeviceWua.cpp index 1aceaf90..f9014bdb 100644 --- a/src/Cafe/Filesystem/fscDeviceWua.cpp +++ b/src/Cafe/Filesystem/fscDeviceWua.cpp @@ -119,14 +119,12 @@ private: class fscDeviceWUAC : public fscDeviceC { - FSCVirtualFile* fscDeviceOpenByPath(std::wstring_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override + FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override { ZArchiveReader* archive = (ZArchiveReader*)ctx; cemu_assert_debug(!HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::WRITE_PERMISSION)); // writing to WUA is not supported - std::string pathU8 = boost::nowide::narrow(path.data(), path.size()); - - ZArchiveNodeHandle fileHandle = archive->LookUp(pathU8, true, true); + ZArchiveNodeHandle fileHandle = archive->LookUp(path, true, true); if (fileHandle == ZARCHIVE_INVALID_NODE) { *fscStatus = FSC_STATUS_FILE_NOT_FOUND; diff --git a/src/Cafe/Filesystem/fscDeviceWud.cpp b/src/Cafe/Filesystem/fscDeviceWud.cpp index c86c6dbe..bf43bf3e 100644 --- a/src/Cafe/Filesystem/fscDeviceWud.cpp +++ b/src/Cafe/Filesystem/fscDeviceWud.cpp @@ -120,16 +120,15 @@ private: class fscDeviceWUDC : public fscDeviceC { - FSCVirtualFile* fscDeviceOpenByPath(std::wstring_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override + FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override { FSTVolume* mountedVolume = (FSTVolume*)ctx; cemu_assert_debug(!HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::WRITE_PERMISSION)); // writing to FST is never allowed - std::string pathU8 = boost::nowide::narrow(path.data(), path.size()); if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE)) { FSTFileHandle fstFileHandle; - if (mountedVolume->OpenFile(pathU8, fstFileHandle, true)) + if (mountedVolume->OpenFile(path, fstFileHandle, true)) { *fscStatus = FSC_STATUS_OK; return new FSCDeviceWudFileCtx(mountedVolume, fstFileHandle); @@ -138,7 +137,7 @@ class fscDeviceWUDC : public fscDeviceC if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR)) { FSTDirectoryIterator dirIterator; - if (mountedVolume->OpenDirectoryIterator(pathU8, dirIterator)) + if (mountedVolume->OpenDirectoryIterator(path, dirIterator)) { *fscStatus = FSC_STATUS_OK; return new FSCDeviceWudFileCtx(mountedVolume, dirIterator); diff --git a/src/Cafe/TitleList/TitleList.cpp b/src/Cafe/TitleList/TitleList.cpp index 315103dd..baa4df55 100644 --- a/src/Cafe/TitleList/TitleList.cpp +++ b/src/Cafe/TitleList/TitleList.cpp @@ -79,7 +79,7 @@ void CafeTitleList::LoadCacheFile() cacheEntry.titleDataFormat = format; cacheEntry.region = region; cacheEntry.titleName = name; - cacheEntry.path = _asUtf8(path); + cacheEntry.path = _utf8ToPath(path); cacheEntry.subPath = sub_path; cacheEntry.group_id = group_id; cacheEntry.app_type = app_type; diff --git a/src/Common/precompiled.h b/src/Common/precompiled.h index 57929c2a..9581861b 100644 --- a/src/Common/precompiled.h +++ b/src/Common/precompiled.h @@ -435,10 +435,11 @@ inline std::string _utf8Wrapper(const fs::path& path) return _utf8Wrapper(path.generic_u8string()); } -inline std::u8string_view _asUtf8(std::string_view input) +// convert utf8 encoded string to fs::path +inline fs::path _utf8ToPath(std::string_view input) { - std::basic_string_view v((char8_t*)input.data(), input.size()); - return v; + std::basic_string_view v((char8_t*)input.data(), input.size()); + return fs::path(v); } class RunAtCemuBoot // -> replaces this with direct function calls. Linkers other than MSVC may optimize way object files entirely if they are not referenced from outside. So a source file self-registering using this would be causing issues diff --git a/src/config/ActiveSettings.h b/src/config/ActiveSettings.h index 95ceae16..69f6d34a 100644 --- a/src/config/ActiveSettings.h +++ b/src/config/ActiveSettings.h @@ -47,7 +47,7 @@ public: { cemu_assert_debug(format.empty() || (format[0] != '/' && format[0] != '\\')); auto tmp = fmt::format(fmt::runtime(format), std::forward(args)...); - return GetMlcPath() / fs::path(_asUtf8(tmp)); + return GetMlcPath() / _utf8ToPath(tmp); } template