feat: move std::filesystem::path related function to independent namespace.
- create FsPathPatch namespace to hold std::filesystem::path related functions. - add corresponding testbench code for it.
This commit is contained in:
@ -9,6 +9,7 @@ PRIVATE
|
||||
${CMAKE_CURRENT_LIST_DIR}/DialogHelper.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/EncodingHelper.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/ExceptionHelper.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/FsPathPatch.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/IOHelper.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/ParserHelper.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/StringHelper.hpp
|
||||
@ -25,6 +26,7 @@ PRIVATE
|
||||
${CMAKE_CURRENT_LIST_DIR}/DialogHelper.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/EncodingHelper.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/ExceptionHelper.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/FsPathPatch.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/IOHelper.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/ParserHelper.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/StringHelper.cpp
|
||||
@ -72,9 +74,11 @@ FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/DialogHelper.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/EncodingHelper.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/ExceptionHelper.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/FsPathPatch.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/IOHelper.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/ParserHelper.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/StringHelper.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/WinFctHelper.hpp
|
||||
# Windows including guard pair
|
||||
${CMAKE_CURRENT_LIST_DIR}/WinImportPrefix.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/WinImportSuffix.hpp
|
||||
|
41
src/FsPathPatch.cpp
Normal file
41
src/FsPathPatch.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include "FsPathPatch.hpp"
|
||||
|
||||
#include "EncodingHelper.hpp"
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace YYCC::FsPathPatch {
|
||||
|
||||
std::filesystem::path FromUTF8Path(const char* u8_path) {
|
||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||
|
||||
// convert path to wchar
|
||||
std::wstring wpath;
|
||||
if (!YYCC::EncodingHelper::UTF8ToWchar(u8_path, wpath))
|
||||
throw std::invalid_argument("Fail to convert given UTF8 string.");
|
||||
|
||||
// call microsoft specified fopen which support wchar as argument.
|
||||
return std::filesystem::path(wpath);
|
||||
|
||||
#else
|
||||
return std::filesystem::path(u8_path);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string ToUTF8Path(const std::filesystem::path& path) {
|
||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||
|
||||
// get and convert to utf8
|
||||
std::string u8_path;
|
||||
if (!YYCC::EncodingHelper::WcharToUTF8(path.c_str(), u8_path))
|
||||
throw std::invalid_argument("Fail to convert to UTF8 string.");
|
||||
|
||||
// return utf8 path
|
||||
return u8_path;
|
||||
|
||||
#else
|
||||
return path.string();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
41
src/FsPathPatch.hpp
Normal file
41
src/FsPathPatch.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
#include "YYCCInternal.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
/**
|
||||
* @brief The patch namespace resolving \c std::filesystem::path encoding issue.
|
||||
* @details
|
||||
* This patch is Windows oriented.
|
||||
* If you are in Windows, this patch will perform extra operations to achieve goals,
|
||||
* and in other platforms, they just redirect request to corresponding vanilla C++ functions.
|
||||
*
|
||||
* As you know, the underlying char type of \c std::filesystem::path is \c wchar_t on Windows,
|
||||
* and in other platforms, it is simple \c char.
|
||||
* Due to this, if you passing UTF8 char sequence to \c std::filesystem::path on Windows,
|
||||
* the library implementation will assume your input is based on current Windows code page, not UTF8.
|
||||
* And the final path stored in \c std::filesystem::path is not what you expcected.
|
||||
*
|
||||
* This patch namespace always use UTF8 as its argument. There is no ambiguous issue.
|
||||
* You should use the functions provided by this namespace on any platforms
|
||||
* instead of vanilla \c std::filesystem::path functions.
|
||||
*/
|
||||
namespace YYCC::FsPathPatch {
|
||||
|
||||
/**
|
||||
* @brief Constructs the path from a UTF8 character sequence
|
||||
* @param[in] u8_path UTF8 path string for building this std::filesystem::path.
|
||||
* @return std::filesystem::path instance.
|
||||
* @exception std::invalid_argument Fail to parse given UTF8 string (maybe invalid?).
|
||||
*/
|
||||
std::filesystem::path FromUTF8Path(const char* u8_path);
|
||||
|
||||
/**
|
||||
* @brief Returns the UTF8 representation of the pathname
|
||||
* @param path[in] The string to be output.
|
||||
* @return UTF8 encoded string representing given path.
|
||||
* @exception std::invalid_argument Fail to parse to UTF8 string.
|
||||
*/
|
||||
std::string ToUTF8Path(const std::filesystem::path& path);
|
||||
|
||||
}
|
@ -32,22 +32,5 @@ namespace YYCC::IOHelper {
|
||||
#endif
|
||||
}
|
||||
|
||||
std::filesystem::path UTF8Path(const char* u8_path) {
|
||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||
|
||||
// convert path to wchar
|
||||
std::wstring wpath;
|
||||
if (!YYCC::EncodingHelper::UTF8ToWchar(u8_path, wpath))
|
||||
throw std::invalid_argument("Fail to convert given UTF8 string.");
|
||||
|
||||
// call microsoft specified fopen which support wchar as argument.
|
||||
return std::filesystem::path(wpath);
|
||||
|
||||
#else
|
||||
return std::filesystem::path(u8_path);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -34,15 +34,4 @@ namespace YYCC::IOHelper {
|
||||
*/
|
||||
FILE* UTF8FOpen(const char* u8_filepath, const char* u8_mode);
|
||||
|
||||
/**
|
||||
* @brief Build std::filesystem::path from UTF8 string.
|
||||
* @param[in] u8_path UTF8 path string for building this std::filesystem::path.
|
||||
* @return std::filesystem::path instance.
|
||||
* @exception std::invalid_argument Fail to parse given UTF8 string (maybe invalid?).
|
||||
* @remarks
|
||||
* This function is suit for Windows.
|
||||
* On other platforms, it will simply call the constructor of std::filesystem::path.
|
||||
*/
|
||||
std::filesystem::path UTF8Path(const char* u8_path);
|
||||
|
||||
}
|
||||
|
@ -10,3 +10,4 @@
|
||||
#include "ExceptionHelper.hpp"
|
||||
#include "IOHelper.hpp"
|
||||
#include "WinFctHelper.hpp"
|
||||
#include "FsPathPatch.hpp"
|
||||
|
Reference in New Issue
Block a user