diff options
author | Orgad Shaneh <orgad.shaneh@audiocodes.com> | 2022-10-05 23:10:24 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-05 22:10:24 +0200 |
commit | a6072098415e3ccf8a2ac6542db35d1f72f8d08b (patch) | |
tree | 0cc82573e53dcf3e24f182147497d72ca3a8e761 | |
parent | e9ddf6800eaed6ce45bcb01f976995ef423c6ae2 (diff) | |
download | ccache-a6072098415e3ccf8a2ac6542db35d1f72f8d08b.tar.gz |
fix: Remove usage of deprecated codecvt header (#1172)
Based on https://stackoverflow.com/a/69410299/764870.
-rw-r--r-- | src/util/file.cpp | 36 | ||||
-rw-r--r-- | unittest/test_util_file.cpp | 8 |
2 files changed, 38 insertions, 6 deletions
diff --git a/src/util/file.cpp b/src/util/file.cpp index b3d3771f..964d6846 100644 --- a/src/util/file.cpp +++ b/src/util/file.cpp @@ -21,6 +21,7 @@ #include <Fd.hpp> #include <Logging.hpp> #include <Stat.hpp> +#include <Win32Util.hpp> #include <fmtmacros.hpp> #include <util/Bytes.hpp> @@ -47,7 +48,6 @@ #include <sys/types.h> #include <cerrno> -#include <codecvt> #include <cstring> #include <fstream> #include <locale> @@ -171,11 +171,35 @@ read_file(const std::string& path, size_t size_hint) // it's actually needed. if (has_utf16_le_bom(result)) { result.erase(0, 2); // Remove BOM. - std::u16string result_as_u16((result.size() / 2) + 1, '\0'); - result_as_u16 = reinterpret_cast<const char16_t*>(result.c_str()); - std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> - converter; - result = converter.to_bytes(result_as_u16); + if (result.empty()) + return result; + + std::wstring result_as_u16((result.size() / 2) + 1, '\0'); + result_as_u16 = reinterpret_cast<const wchar_t*>(result.c_str()); + + const int size = WideCharToMultiByte(CP_UTF8, + WC_ERR_INVALID_CHARS, + result_as_u16.c_str(), + int(result_as_u16.size()), + nullptr, + 0, + nullptr, + nullptr); + if (size <= 0) + return nonstd::make_unexpected( + FMT("Failed to convert {} from UTF-16LE to UTF-8: {}", + path, + Win32Util::error_message(GetLastError()))); + + result = std::string(size, '\0'); + WideCharToMultiByte(CP_UTF8, + 0, + result_as_u16.c_str(), + int(result_as_u16.size()), + &result.at(0), + size, + nullptr, + nullptr); } } #endif diff --git a/unittest/test_util_file.cpp b/unittest/test_util_file.cpp index 9b99d150..cc677137 100644 --- a/unittest/test_util_file.cpp +++ b/unittest/test_util_file.cpp @@ -120,6 +120,14 @@ TEST_CASE("util::read_file<std::string> with UTF-16 little endian encoding") auto read_data = util::read_file<std::string>("test"); REQUIRE(read_data); CHECK(*read_data == "abc"); + + data.push_back('\0'); + data.push_back(static_cast<unsigned char>(0xd8)); + data.push_back('d'); + data.push_back('\0'); + CHECK(util::write_file("test", data)); + read_data = util::read_file<std::string>("test"); + REQUIRE(!read_data); } #endif |