merge bitcoin#23522: Improve fs::PathToString documentation

This commit is contained in:
Kittywhiskers Van Gogh 2024-07-20 10:43:13 +00:00
parent 20d359b570
commit b0d2484a0b
No known key found for this signature in database
GPG Key ID: 30CD0C065E5C4AAD
3 changed files with 34 additions and 21 deletions

View File

@ -1256,6 +1256,12 @@ A few guidelines for introducing and reviewing new RPC interfaces:
- *Rationale*: User-facing consistency. - *Rationale*: User-facing consistency.
- Use `fs::path::u8string()` and `fs::u8path()` functions when converting path
to JSON strings, not `fs::PathToString` and `fs::PathFromString`
- *Rationale*: JSON strings are Unicode strings, not byte strings, and
RFC8259 requires JSON to be encoded as UTF-8.
Internal interface guidelines Internal interface guidelines
----------------------------- -----------------------------

View File

@ -137,6 +137,10 @@ CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bo
TryCreateDirectories(path); TryCreateDirectories(path);
LogPrintf("Opening LevelDB in %s\n", fs::PathToString(path)); LogPrintf("Opening LevelDB in %s\n", fs::PathToString(path));
} }
// PathToString() return value is safe to pass to leveldb open function,
// because on POSIX leveldb passes the byte string directly to ::open(), and
// on Windows it converts from UTF-8 to UTF-16 before calling ::CreateFileW
// (see env_posix.cc and env_windows.cc).
leveldb::Status status = leveldb::DB::Open(options, fs::PathToString(path), &pdb); leveldb::Status status = leveldb::DB::Open(options, fs::PathToString(path), &pdb);
dbwrapper_private::HandleError(status); dbwrapper_private::HandleError(status);
LogPrintf("Opened LevelDB successfully\n"); LogPrintf("Opened LevelDB successfully\n");

View File

@ -94,31 +94,34 @@ static inline path operator+(path p1, path p2)
/** /**
* Convert path object to byte string. On POSIX, paths natively are byte * Convert path object to byte string. On POSIX, paths natively are byte
* strings so this is trivial. On Windows, paths natively are Unicode, so an * strings, so this is trivial. On Windows, paths natively are Unicode, so an
* encoding step is necessary. * encoding step is necessary. The inverse of \ref PathToString is \ref
* PathFromString. The strings returned and parsed by these functions can be
* used to call POSIX APIs, and for roundtrip conversion, logging, and
* debugging.
* *
* The inverse of \ref PathToString is \ref PathFromString. The strings * Because \ref PathToString and \ref PathFromString functions don't specify an
* returned and parsed by these functions can be used to call POSIX APIs, and * encoding, they are meant to be used internally, not externally. They are not
* for roundtrip conversion, logging, and debugging. But they are not * appropriate to use in applications requiring UTF-8, where
* guaranteed to be valid UTF-8, and are generally meant to be used internally, * fs::path::u8string() and fs::u8path() methods should be used instead. Other
* not externally. When communicating with external programs and libraries that * applications could require still different encodings. For example, JSON, XML,
* require UTF-8, fs::path::u8string() and fs::u8path() methods can be used. * or URI applications might prefer to use higher level escapes (\uXXXX or
* For other applications, if support for non UTF-8 paths is required, or if * &XXXX; or %XX) instead of multibyte encoding. Rust, Python, Java applications
* higher-level JSON or XML or URI or C-style escapes are preferred, it may be * may require encoding paths with their respective UTF-8 derivatives WTF-8,
* also be appropriate to use different path encoding functions. * PEP-383, and CESU-8 (see https://en.wikipedia.org/wiki/UTF-8#Derivatives).
*
* Implementation note: On Windows, the std::filesystem::path(string)
* constructor and std::filesystem::path::string() method are not safe to use
* here, because these methods encode the path using C++'s narrow multibyte
* encoding, which on Windows corresponds to the current "code page", which is
* unpredictable and typically not able to represent all valid paths. So
* std::filesystem::path::u8string() and std::filesystem::u8path() functions
* are used instead on Windows. On POSIX, u8string/u8path functions are not
* safe to use because paths are not always valid UTF-8, so plain string
* methods which do not transform the path there are used.
*/ */
static inline std::string PathToString(const path& path) static inline std::string PathToString(const path& path)
{ {
// Implementation note: On Windows, the std::filesystem::path(string)
// constructor and std::filesystem::path::string() method are not safe to
// use here, because these methods encode the path using C++'s narrow
// multibyte encoding, which on Windows corresponds to the current "code
// page", which is unpredictable and typically not able to represent all
// valid paths. So std::filesystem::path::u8string() and
// std::filesystem::u8path() functions are used instead on Windows. On
// POSIX, u8string/u8path functions are not safe to use because paths are
// not always valid UTF-8, so plain string methods which do not transform
// the path there are used.
#ifdef WIN32 #ifdef WIN32
return path.u8string(); return path.u8string();
#else #else