summaryrefslogtreecommitdiff
path: root/src/Util.cpp
diff options
context:
space:
mode:
authorvvainola <vilivainola@gmail.com>2022-02-19 17:22:16 +0200
committerGitHub <noreply@github.com>2022-02-19 16:22:16 +0100
commit1ee99b7bbdae21b5aef9b28e21cdf9b14b59c5ce (patch)
treeaeaae270b8a6c47660f70efa85c7de74961dd547 /src/Util.cpp
parent3a2f970842417ea605d24b07af652be91c7eff31 (diff)
downloadccache-1ee99b7bbdae21b5aef9b28e21cdf9b14b59c5ce.tar.gz
fix: Support UTF-16LE .rsp files (#1005)
Diffstat (limited to 'src/Util.cpp')
-rw-r--r--src/Util.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/Util.cpp b/src/Util.cpp
index f03ba6fb..d9c5fdbf 100644
--- a/src/Util.cpp
+++ b/src/Util.cpp
@@ -48,7 +48,9 @@ extern "C" {
#include <algorithm>
#include <climits>
+#include <codecvt>
#include <fstream>
+#include <locale>
#ifndef HAVE_DIRENT_H
# include <filesystem>
@@ -207,6 +209,14 @@ rewrite_stderr_to_absolute_paths(string_view text)
return result;
}
+bool
+has_utf16_le_bom(string_view text)
+{
+ return text.size() > 1
+ && ((static_cast<uint8_t>(text[0]) == 0xff
+ && static_cast<uint8_t>(text[1]) == 0xfe));
+}
+
} // namespace
namespace Util {
@@ -1078,6 +1088,21 @@ read_file(const std::string& path, size_t size_hint)
return result;
}
+std::string
+read_text_file(const std::string& path, size_t size_hint)
+{
+ std::string result = read_file(path, size_hint);
+ // Convert to UTF-8 if the contents start with UTF-16 little-endian BOM
+ 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);
+ }
+ return result;
+}
+
#ifndef _WIN32
std::string
read_link(const std::string& path)