From a79468295e80d64607e43125e701673b46c35580 Mon Sep 17 00:00:00 2001 From: Ryan Shepherd Date: Fri, 22 May 2026 14:05:23 -0700 Subject: [PATCH 1/2] Massive speedup to file_equal and file_to_string --- cppwinrt/text_writer.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/cppwinrt/text_writer.h b/cppwinrt/text_writer.h index a274d11ce..96981ee2e 100644 --- a/cppwinrt/text_writer.h +++ b/cppwinrt/text_writer.h @@ -13,8 +13,12 @@ namespace cppwinrt { inline std::string file_to_string(std::string const& filename) { - std::ifstream file(filename, std::ios::binary); - return static_cast(std::stringstream() << file.rdbuf()).str(); + std::ifstream file(filename, std::ios::binary | std::ios::ate); + const auto size = file.tellg(); + file.seekg(0); + std::string result(size, '\0'); + file.read(result.data(), size); + return result; } template @@ -218,18 +222,13 @@ namespace cppwinrt bool file_equal(std::string const& filename) const { - if (!std::filesystem::exists(filename)) + if (!std::filesystem::exists(filename) || std::filesystem::file_size(filename) != m_first.size() + m_second.size()) { return false; } auto file = file_to_string(filename); - if (file.size() != m_first.size() + m_second.size()) - { - return false; - } - if (!std::equal(m_first.begin(), m_first.end(), file.begin(), file.begin() + m_first.size())) { return false; From e637371093d46695d69fa8616e96300a97e1ce4b Mon Sep 17 00:00:00 2001 From: Ryan Shepherd Date: Fri, 22 May 2026 15:36:57 -0700 Subject: [PATCH 2/2] Properly cast the result of tellg() and handle filesystem errors more gracefully. --- cppwinrt/text_writer.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/cppwinrt/text_writer.h b/cppwinrt/text_writer.h index 96981ee2e..c6fc380b3 100644 --- a/cppwinrt/text_writer.h +++ b/cppwinrt/text_writer.h @@ -14,10 +14,24 @@ namespace cppwinrt inline std::string file_to_string(std::string const& filename) { std::ifstream file(filename, std::ios::binary | std::ios::ate); - const auto size = file.tellg(); + if (!file) { return{}; } + + const auto stream_size = file.tellg(); + if (stream_size == std::ifstream::pos_type(-1)) + { + return {}; + } + file.seekg(0); + + auto size = static_cast(stream_size); std::string result(size, '\0'); file.read(result.data(), size); + if (!file) + { + result.resize(static_cast(file.gcount())); + } + return result; } @@ -222,7 +236,9 @@ namespace cppwinrt bool file_equal(std::string const& filename) const { - if (!std::filesystem::exists(filename) || std::filesystem::file_size(filename) != m_first.size() + m_second.size()) + // Non-throwing file_size returns uintmax_t(-1) on errors, which shouldn't ever be the size of m_first or m_second + std::error_code ec; + if (std::filesystem::file_size(filename, ec) != m_first.size() + m_second.size()) { return false; }