Skip to content

Strutil utf conversion improvements #3553

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/include/OpenImageIO/strutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -834,15 +834,29 @@ struct OIIO_UTIL_API StringILess {


/// Conversion of normal char-based strings (presumed to be UTF-8 encoding)
/// to wide char string, wstring.
/// to a UTF-16 encoded wide char string, wstring.
std::wstring OIIO_UTIL_API utf8_to_utf16wstring (string_view utf8str) noexcept;

#if OPENIMAGEIO_VERSION < 30000
/// Old name for utf8_to_utf16wstring. Will be deprecated for OIIO 2.5+ and
/// removed for OIIO 3.0. Use utf8_to_utf16wstring which is more clear that
/// this particular conversion from utf8 to utf16 returns a std::wstring and
/// not a std::u16string.
#if OPENIMAGEIO_VERSION >= 20500
OIIO_DEPRECATED("Use utf8_to_utf16wstring instead")
#endif
std::wstring OIIO_UTIL_API utf8_to_utf16 (string_view utf8str) noexcept;
#endif

/// Conversion from wstring UTF-16 to a UTF-8 std::string. This is the
/// standard way to convert from Windows wide character strings used for
/// filenames into the UTF-8 strings OIIO expects for filenames when passed to
/// functions like ImageInput::open().
std::string OIIO_UTIL_API utf16_to_utf8(const std::wstring& utf16str) noexcept;

/// Conversion from UTF-16 std::u16string to a UTF-8 std::string.
std::string OIIO_UTIL_API utf16_to_utf8(const std::u16string& utf16str) noexcept;



/// Copy at most size characters (including terminating 0 character) from
Expand Down
17 changes: 8 additions & 9 deletions src/libutil/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ inline filesystem::path
u8path(string_view name)
{
#ifdef _WIN32
return filesystem::path(Strutil::utf8_to_utf16(name));
return filesystem::path(Strutil::utf8_to_utf16wstring(name));
#else
return filesystem::path(name.begin(), name.end());
#endif
Expand All @@ -66,7 +66,7 @@ inline filesystem::path
u8path(const std::string& name)
{
#ifdef _WIN32
return filesystem::path(Strutil::utf8_to_utf16(name));
return filesystem::path(Strutil::utf8_to_utf16wstring(name));
#else
return filesystem::path(name);
#endif
Expand Down Expand Up @@ -456,7 +456,7 @@ Filesystem::unique_path(string_view model)
// to convert char* to wchar_t* because they do not know the encoding
// See boost/filesystem/path.hpp
// The only correct way to do this is to do the conversion ourselves
std::wstring modelStr = Strutil::utf8_to_utf16(model);
std::wstring modelStr = Strutil::utf8_to_utf16wstring(model);
# else
std::string modelStr = model.str();
# endif
Expand Down Expand Up @@ -495,9 +495,8 @@ Filesystem::fopen(string_view path, string_view mode)
{
#ifdef _WIN32
// on Windows fopen does not accept UTF-8 paths, so we convert to wide char
std::wstring wpath = Strutil::utf8_to_utf16(path);
std::wstring wmode = Strutil::utf8_to_utf16(mode);

std::wstring wpath = Strutil::utf8_to_utf16wstring(path);
std::wstring wmode = Strutil::utf8_to_utf16wstring(mode);
return ::_wfopen(wpath.c_str(), wmode.c_str());
#else
// on Unix platforms passing in UTF-8 works
Expand Down Expand Up @@ -538,7 +537,7 @@ Filesystem::open(OIIO::ifstream& stream, string_view path,
#ifdef _WIN32
// Windows std::ifstream accepts non-standard wchar_t*
// On MingW, we use our own OIIO::ifstream
std::wstring wpath = Strutil::utf8_to_utf16(path);
std::wstring wpath = Strutil::utf8_to_utf16wstring(path);
stream.open(wpath.c_str(), mode);
stream.seekg(0, std::ios_base::beg); // force seek, otherwise broken
#else
Expand All @@ -555,7 +554,7 @@ Filesystem::open(OIIO::ofstream& stream, string_view path,
#ifdef _WIN32
// Windows std::ofstream accepts non-standard wchar_t*
// On MingW, we use our own OIIO::ofstream
std::wstring wpath = Strutil::utf8_to_utf16(path);
std::wstring wpath = Strutil::utf8_to_utf16wstring(path);
stream.open(wpath.c_str(), mode);
#else
stream.open(path, mode);
Expand All @@ -570,7 +569,7 @@ Filesystem::open(string_view path, int flags)
#ifdef _WIN32
// on Windows _open does not accept UTF-8 paths, so we convert to wide
// char and use _wopen.
std::wstring wpath = Strutil::utf8_to_utf16(path);
std::wstring wpath = Strutil::utf8_to_utf16wstring(path);
return ::_wopen(wpath.c_str(), flags);
#else
// on Unix platforms passing in UTF-8 works
Expand Down
2 changes: 1 addition & 1 deletion src/libutil/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Plugin::plugin_extension(void)
Handle
dlopen(const char* plugin_filename, int)
{
std::wstring w = Strutil::utf8_to_utf16(plugin_filename);
std::wstring w = Strutil::utf8_to_utf16wstring(plugin_filename);
return LoadLibraryW(w.c_str());
}

Expand Down
26 changes: 25 additions & 1 deletion src/libutil/strutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,7 @@ Strutil::replace(string_view str, string_view pattern, string_view replacement,
// appropriate for error messages.

std::wstring
Strutil::utf8_to_utf16(string_view str) noexcept
Strutil::utf8_to_utf16wstring(string_view str) noexcept
{
try {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> conv;
Expand All @@ -882,6 +882,17 @@ Strutil::utf8_to_utf16(string_view str) noexcept



#if OPENIMAGEIO_VERSION < 30000
// DEPRECATED(2.5) and slated for removal in 3.0.
std::wstring
Strutil::utf8_to_utf16(string_view str) noexcept
{
return utf8_to_utf16wstring(str);
}
#endif



std::string
Strutil::utf16_to_utf8(const std::wstring& str) noexcept
{
Expand All @@ -895,6 +906,19 @@ Strutil::utf16_to_utf8(const std::wstring& str) noexcept



std::string
Strutil::utf16_to_utf8(const std::u16string& str) noexcept
{
try {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> conv;
return conv.to_bytes(str);
} catch (const std::exception&) {
return std::string();
}
}



char*
Strutil::safe_strcpy(char* dst, string_view src, size_t size) noexcept
{
Expand Down
3 changes: 2 additions & 1 deletion src/raw.imageio/rawinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,8 @@ RawInput::open_raw(bool unpack, const std::string& name,

#ifdef _WIN32
// Convert to wide chars, just on Windows.
int ret = m_processor->open_file(Strutil::utf8_to_utf16(name).c_str());
int ret = m_processor->open_file(
Strutil::utf8_to_utf16wstring(name).c_str());
#else
int ret = m_processor->open_file(name.c_str());
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/tiff.imageio/tiffinput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ TIFFInput::seek_subimage(int subimage, int miplevel)
reader_unmapproc);
} else {
#ifdef _WIN32
std::wstring wfilename = Strutil::utf8_to_utf16(m_filename);
std::wstring wfilename = Strutil::utf8_to_utf16wstring(m_filename);
m_tif = TIFFOpenW(wfilename.c_str(), "rm");
#else
m_tif = TIFFOpen(m_filename.c_str(), "rm");
Expand Down
3 changes: 2 additions & 1 deletion src/tiff.imageio/tiffoutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,8 @@ TIFFOutput::open(const std::string& name, const ImageSpec& userspec,
writer_unmapproc);
} else {
#ifdef _WIN32
m_tif = TIFFOpenW(Strutil::utf8_to_utf16(name).c_str(), openmode);
m_tif = TIFFOpenW(Strutil::utf8_to_utf16wstring(name).c_str(),
openmode);
#else
m_tif = TIFFOpen(name.c_str(), openmode);
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/zfile.imageio/zfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ gzFile
open_gz(const std::string& filename, const char* mode)
{
#ifdef _WIN32
std::wstring wpath = Strutil::utf8_to_utf16(filename);
std::wstring wpath = Strutil::utf8_to_utf16wstring(filename);
gzFile gz = gzopen_w(wpath.c_str(), mode);
#else
gzFile gz = gzopen(filename.c_str(), mode);
Expand Down