Changeset View
Changeset View
Standalone View
Standalone View
src/fs.cpp
Show First 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | #else | ||||
MultiByteToWideChar(CP_ACP, 0, mb_string.c_str(), mb_string.size(), | MultiByteToWideChar(CP_ACP, 0, mb_string.c_str(), mb_string.size(), | ||||
&*utf16_string.begin(), size); | &*utf16_string.begin(), size); | ||||
// Convert from utf-16 to utf-8 | // Convert from utf-16 to utf-8 | ||||
return std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>() | return std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t>() | ||||
.to_bytes(utf16_string); | .to_bytes(utf16_string); | ||||
#endif | #endif | ||||
} | } | ||||
#ifdef WIN32 | |||||
#ifdef __GLIBCXX__ | |||||
// reference: | |||||
// https://github.com/gcc-mirror/gcc/blob/gcc-7_3_0-release/libstdc%2B%2B-v3/include/std/fstream#L270 | |||||
static std::string openmodeToStr(std::ios_base::openmode mode) { | |||||
switch (mode & ~std::ios_base::ate) { | |||||
case std::ios_base::out: | |||||
case std::ios_base::out | std::ios_base::trunc: | |||||
return "w"; | |||||
case std::ios_base::out | std::ios_base::app: | |||||
case std::ios_base::app: | |||||
return "a"; | |||||
case std::ios_base::in: | |||||
return "r"; | |||||
case std::ios_base::in | std::ios_base::out: | |||||
return "r+"; | |||||
case std::ios_base::in | std::ios_base::out | std::ios_base::trunc: | |||||
return "w+"; | |||||
case std::ios_base::in | std::ios_base::out | std::ios_base::app: | |||||
case std::ios_base::in | std::ios_base::app: | |||||
return "a+"; | |||||
case std::ios_base::out | std::ios_base::binary: | |||||
case std::ios_base::out | std::ios_base::trunc | std::ios_base::binary: | |||||
return "wb"; | |||||
case std::ios_base::out | std::ios_base::app | std::ios_base::binary: | |||||
case std::ios_base::app | std::ios_base::binary: | |||||
return "ab"; | |||||
case std::ios_base::in | std::ios_base::binary: | |||||
return "rb"; | |||||
case std::ios_base::in | std::ios_base::out | std::ios_base::binary: | |||||
return "r+b"; | |||||
case std::ios_base::in | std::ios_base::out | std::ios_base::trunc | | |||||
std::ios_base::binary: | |||||
return "w+b"; | |||||
case std::ios_base::in | std::ios_base::out | std::ios_base::app | | |||||
std::ios_base::binary: | |||||
case std::ios_base::in | std::ios_base::app | std::ios_base::binary: | |||||
return "a+b"; | |||||
default: | |||||
return std::string(); | |||||
} | |||||
} | |||||
void ifstream::open(const fs::path &p, std::ios_base::openmode mode) { | |||||
close(); | |||||
mode |= std::ios_base::in; | |||||
m_file = fsbridge::fopen(p, openmodeToStr(mode).c_str()); | |||||
if (m_file == nullptr) { | |||||
return; | |||||
} | |||||
m_filebuf = __gnu_cxx::stdio_filebuf<char>(m_file, mode); | |||||
rdbuf(&m_filebuf); | |||||
if (mode & std::ios_base::ate) { | |||||
seekg(0, std::ios_base::end); | |||||
} | |||||
} | |||||
void ifstream::close() { | |||||
if (m_file != nullptr) { | |||||
m_filebuf.close(); | |||||
fclose(m_file); | |||||
} | |||||
m_file = nullptr; | |||||
} | |||||
void ofstream::open(const fs::path &p, std::ios_base::openmode mode) { | |||||
close(); | |||||
mode |= std::ios_base::out; | |||||
m_file = fsbridge::fopen(p, openmodeToStr(mode).c_str()); | |||||
if (m_file == nullptr) { | |||||
return; | |||||
} | |||||
m_filebuf = __gnu_cxx::stdio_filebuf<char>(m_file, mode); | |||||
rdbuf(&m_filebuf); | |||||
if (mode & std::ios_base::ate) { | |||||
seekp(0, std::ios_base::end); | |||||
} | |||||
} | |||||
void ofstream::close() { | |||||
if (m_file != nullptr) { | |||||
m_filebuf.close(); | |||||
fclose(m_file); | |||||
} | |||||
m_file = nullptr; | |||||
} | |||||
#else // __GLIBCXX__ | |||||
static_assert( | |||||
sizeof(*fs::path().BOOST_FILESYSTEM_C_STR) == sizeof(wchar_t), | |||||
"Warning: This build is using boost::filesystem ofstream and ifstream " | |||||
"implementations which will fail to open paths containing multibyte " | |||||
"characters. You should delete this static_assert to ignore this warning, " | |||||
"or switch to a different C++ standard library like the Microsoft C++ " | |||||
"Standard Library (where boost uses non-standard extensions to construct " | |||||
"stream objects with wide filenames), or the GNU libstdc++ library (where " | |||||
"a more complicated workaround has been implemented above)."); | |||||
#endif // __GLIBCXX__ | |||||
#endif // WIN32 | |||||
} // namespace fsbridge | } // namespace fsbridge |