Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix a bug when a text was written to a file in binary format on Windows
Browse files Browse the repository at this point in the history
bugdea1er committed Jan 2, 2025
1 parent e4bac59 commit 3b9f290
Showing 2 changed files with 53 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/file.cpp
Original file line number Diff line number Diff line change
@@ -109,7 +109,7 @@ std::ifstream file::input_stream() const {
}

std::ofstream file::output_stream(std::ios::openmode mode) const {
binary ? mode |= std::ios::binary : mode ^= std::ios::binary;
binary ? mode |= std::ios::binary : mode &= ~std::ios::binary;
return std::ofstream(path(), mode);
}

60 changes: 52 additions & 8 deletions tests/file.cpp
Original file line number Diff line number Diff line change
@@ -156,17 +156,25 @@ TEST(file, write_text) {
tmpfile.write("Hello\n");

{
auto stream = std::ifstream(tmpfile.path());
auto stream = std::ifstream(tmpfile.path(), std::ios::binary);
auto content = std::string(std::istreambuf_iterator<char>(stream), {});
#ifdef _WIN32
EXPECT_EQ(content, "Hello\r\n");
#else
EXPECT_EQ(content, "Hello\n");
#endif
}

tmpfile.write("world!\n");

{
auto stream = std::ifstream(tmpfile.path());
auto stream = std::ifstream(tmpfile.path(), std::ios::binary);
auto content = std::string(std::istreambuf_iterator<char>(stream), {});
#ifdef _WIN32
EXPECT_EQ(content, "world!\r\n");
#else
EXPECT_EQ(content, "world!\n");
#endif
}
}

@@ -195,22 +203,30 @@ TEST(file, append_binary) {
/// Tests text file appending
TEST(file, append_text) {
file tmpfile = file::text();
std::ofstream(tmpfile.path()) << "Hello,\n ";
std::ofstream(tmpfile.path()) << "Hello,";

tmpfile.append("world");
tmpfile.append("\n world");

{
auto stream = std::ifstream(tmpfile.path());
auto stream = std::ifstream(tmpfile.path(), std::ios::binary);
auto content = std::string(std::istreambuf_iterator<char>(stream), {});
#ifdef _WIN32
EXPECT_EQ(content, "Hello,\r\n world");
#else
EXPECT_EQ(content, "Hello,\n world");
#endif
}

tmpfile.append("!");
tmpfile.append("!\n");

{
auto stream = std::ifstream(tmpfile.path());
auto stream = std::ifstream(tmpfile.path(), std::ios::binary);
auto content = std::string(std::istreambuf_iterator<char>(stream), {});
EXPECT_EQ(content, "Hello,\n world!");
#ifdef _WIN32
EXPECT_EQ(content, "Hello,\r\n world!\r\n");
#else
EXPECT_EQ(content, "Hello,\n world!\n");
#endif
}
}

@@ -338,6 +354,34 @@ TEST(file, output_stream_append_text) {
}
}

/// Tests text file appending to output_stream even when binary was requested
TEST(file, output_stream_append_text_binary) {
file tmpfile = file::text();
std::ofstream(tmpfile.path()) << "Hello,\n ";

{
std::ofstream ostream = tmpfile.output_stream(std::ios::app | std::ios::binary);
ostream << "world" << std::flush;
}

{
auto stream = std::ifstream(tmpfile.path(), std::ios::binary);
auto content = std::string(std::istreambuf_iterator<char>(stream), {});
EXPECT_EQ(content, "Hello,\r\n world");
}

{
std::ofstream ostream = tmpfile.output_stream(std::ios::app | std::ios::binary);
ostream << "!" << std::flush;
}

{
auto stream = std::ifstream(tmpfile.path(), std::ios::binary);
auto content = std::string(std::istreambuf_iterator<char>(stream), {});
EXPECT_EQ(content, "Hello,\r\n world!");
}
}

/// Tests that destructor removes a file
TEST(file, destructor) {
fs::path path;

0 comments on commit 3b9f290

Please sign in to comment.