OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches

Opening files by UTF-8 path on every platform. More...

#include <concepts>
#include <cstdio>
#include <filesystem>
#include <string>
#include <type_traits>
Include dependency graph for FileIO.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Namespaces

namespace  openswmm
 
namespace  openswmm::io
 

Functions

std::filesystem::path openswmm::io::utf8_path (const std::string &utf8)
 Convert borrowed path bytes into an owned native filesystem path.
 
template<class P>
requires std::same_as<std::remove_cvref_t<P>, std::filesystem::path>
std::filesystem::path openswmm::io::utf8_path (P &&)=delete
 Passing an fs::path to utf8_path() is always a mistake — refuse it at compile time, on EVERY platform.
 
std::string openswmm::io::path_utf8 (const std::filesystem::path &p, bool generic=false)
 Copy a native path into the engine byte-string representation.
 
template<class S>
requires (!std::same_as<std::remove_cvref_t<S>, std::filesystem::path>)
std::string openswmm::io::path_utf8 (S &&, bool=false)=delete
 The mirror guard: path_utf8() takes a path, never a string.
 
std::FILE * openswmm::io::fopen_path (const std::filesystem::path &p, const char *mode)
 Open a borrowed native path using platform C stdio.
 
std::FILE * openswmm::io::fopen_utf8 (const std::string &utf8, const char *mode)
 Convert engine path bytes and open a C stdio stream.
 

Detailed Description

Opening files by UTF-8 path on every platform.

Paths reach the engine as UTF-8 std::string — that is what the GUI hands over (QString::toUtf8), what the C API documents, and what a UTF-8 .inp carries in [FILES].

On POSIX a path is an opaque byte string, so UTF-8 bytes go straight through. On Windows they do not: the narrow char* file APIs — std::fopen, and the const char* fstream constructors — interpret their argument in the process's ACTIVE ANSI CODE PAGE (CP936/GBK on a Chinese system, CP1252 on a Western one), never as UTF-8. A path such as

C:/…/模拟情景8/模拟情景[8].inp

is therefore mangled before it reaches the filesystem and the open fails with a plain "no such file" — issue #7.

std::filesystem::path is the fix because on Windows it stores wchar_t natively and the standard fstream/fopen-equivalent overloads that take a path use the wide APIs. The trap is that path(const std::string&) assumes the NATIVE NARROW encoding, so simply switching to fs::path fixes nothing; the input has to be declared as UTF-8, which is what utf8_path() below does.

Author
Caleb Buahin caleb.nosp@m..bua.nosp@m.hin@g.nosp@m.mail.nosp@m..com
License
Apache-2.0