Skip to content

Commit 5bf2650

Browse files
authored
Massive speedup to file_equal and file_to_string (#1584)
* Massive speedup to file_equal and file_to_string * Properly cast the result of tellg() and handle filesystem errors more gracefully.
1 parent b7eb2ea commit 5bf2650

1 file changed

Lines changed: 23 additions & 8 deletions

File tree

cppwinrt/text_writer.h

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,26 @@ namespace cppwinrt
1313
{
1414
inline std::string file_to_string(std::string const& filename)
1515
{
16-
std::ifstream file(filename, std::ios::binary);
17-
return static_cast<std::stringstream const&>(std::stringstream() << file.rdbuf()).str();
16+
std::ifstream file(filename, std::ios::binary | std::ios::ate);
17+
if (!file) { return{}; }
18+
19+
const auto stream_size = file.tellg();
20+
if (stream_size == std::ifstream::pos_type(-1))
21+
{
22+
return {};
23+
}
24+
25+
file.seekg(0);
26+
27+
auto size = static_cast<std::size_t>(stream_size);
28+
std::string result(size, '\0');
29+
file.read(result.data(), size);
30+
if (!file)
31+
{
32+
result.resize(static_cast<std::size_t>(file.gcount()));
33+
}
34+
35+
return result;
1836
}
1937

2038
template <typename T>
@@ -218,18 +236,15 @@ namespace cppwinrt
218236

219237
bool file_equal(std::string const& filename) const
220238
{
221-
if (!std::filesystem::exists(filename))
239+
// Non-throwing file_size returns uintmax_t(-1) on errors, which shouldn't ever be the size of m_first or m_second
240+
std::error_code ec;
241+
if (std::filesystem::file_size(filename, ec) != m_first.size() + m_second.size())
222242
{
223243
return false;
224244
}
225245

226246
auto file = file_to_string(filename);
227247

228-
if (file.size() != m_first.size() + m_second.size())
229-
{
230-
return false;
231-
}
232-
233248
if (!std::equal(m_first.begin(), m_first.end(), file.begin(), file.begin() + m_first.size()))
234249
{
235250
return false;

0 commit comments

Comments
 (0)