212 lines
5.0 KiB
C++
212 lines
5.0 KiB
C++
// Copyright (c) 2015 Artyom Beilis (Tonkikh)
|
|
// Copyright (c) 2019-2021 Alexander Grund
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0.
|
|
// https://www.boost.org/LICENSE_1_0.txt
|
|
|
|
#include <nowide/fstream.hpp>
|
|
|
|
#include "file_test_helpers.hpp"
|
|
#include "test.hpp"
|
|
#include <string>
|
|
|
|
namespace nw = nowide;
|
|
using namespace nowide::test;
|
|
|
|
template<typename T>
|
|
void test_ctor(const T& filename)
|
|
{
|
|
// Fail on non-existing file
|
|
ensure_not_exists(filename);
|
|
{
|
|
nw::ifstream f(filename);
|
|
TEST(!f);
|
|
}
|
|
TEST(!file_exists(filename));
|
|
|
|
create_file(filename, "test");
|
|
|
|
// Default
|
|
{
|
|
nw::ifstream f(filename);
|
|
TEST(f);
|
|
std::string tmp;
|
|
TEST(f >> tmp);
|
|
TEST_EQ(tmp, "test");
|
|
}
|
|
TEST_EQ(read_file(filename), "test");
|
|
|
|
// At end
|
|
{
|
|
nw::ifstream f(filename, std::ios::ate);
|
|
TEST(f);
|
|
std::string tmp;
|
|
TEST(!(f >> tmp));
|
|
TEST(f.eof());
|
|
f.clear();
|
|
f.seekg(0, std::ios::beg);
|
|
TEST(f >> tmp);
|
|
TEST_EQ(tmp, "test");
|
|
}
|
|
TEST_EQ(read_file(filename), "test");
|
|
|
|
create_file(filename, "test\r\n", data_type::binary);
|
|
// Binary mode
|
|
{
|
|
nw::ifstream f(filename, std::ios::binary);
|
|
TEST(f);
|
|
std::string tmp(6, '\0');
|
|
TEST(f.read(&tmp[0], 6));
|
|
TEST_EQ(tmp, "test\r\n");
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
void test_open(const T& filename)
|
|
{
|
|
// Fail on non-existing file
|
|
ensure_not_exists(filename);
|
|
{
|
|
nw::ifstream f;
|
|
f.open(filename);
|
|
TEST(!f);
|
|
}
|
|
TEST(!file_exists(filename));
|
|
|
|
create_file(filename, "test");
|
|
|
|
// Default
|
|
{
|
|
nw::ifstream f;
|
|
f.open(filename);
|
|
TEST(f);
|
|
std::string tmp;
|
|
TEST(f >> tmp);
|
|
TEST_EQ(tmp, "test");
|
|
}
|
|
TEST_EQ(read_file(filename), "test");
|
|
|
|
// At end
|
|
{
|
|
nw::ifstream f;
|
|
f.open(filename, std::ios::ate);
|
|
TEST(f);
|
|
std::string tmp;
|
|
TEST(!(f >> tmp));
|
|
TEST(f.eof());
|
|
f.clear();
|
|
f.seekg(0, std::ios::beg);
|
|
TEST(f >> tmp);
|
|
TEST_EQ(tmp, "test");
|
|
}
|
|
TEST_EQ(read_file(filename), "test");
|
|
|
|
create_file(filename, "test\r\n", data_type::binary);
|
|
// Binary mode
|
|
{
|
|
nw::ifstream f;
|
|
f.open(filename, std::ios::binary);
|
|
TEST(f);
|
|
std::string tmp(6, '\0');
|
|
TEST(f.read(&tmp[0], 6));
|
|
TEST_EQ(tmp, "test\r\n");
|
|
}
|
|
}
|
|
|
|
void test_move_and_swap(const std::string& filename)
|
|
{
|
|
const std::string filename2 = filename + ".2";
|
|
create_file(filename, "Hello\nWorld");
|
|
create_file(filename2, "Foo\nBar");
|
|
remove_file_at_exit _(filename);
|
|
remove_file_at_exit _2(filename2);
|
|
|
|
// Move construct
|
|
{
|
|
nw::ifstream f_old(filename);
|
|
std::string s;
|
|
TEST(f_old >> s && s == "Hello");
|
|
|
|
nw::ifstream f_new(std::move(f_old));
|
|
// old is closed
|
|
TEST(!f_old.is_open());
|
|
// It is unclear if the std streams can be reused after move-from
|
|
#if NOWIDE_USE_FILEBUF_REPLACEMENT
|
|
f_old.open(filename2);
|
|
#else
|
|
f_old = nw::ifstream(filename2);
|
|
#endif
|
|
TEST(f_old);
|
|
TEST(f_old >> s);
|
|
TEST_EQ(s, "Foo");
|
|
TEST(f_old >> s && s == "Bar");
|
|
|
|
// new starts where the old was left of
|
|
TEST(f_new);
|
|
TEST(f_new >> s);
|
|
TEST_EQ(s, "World");
|
|
}
|
|
// Move assign
|
|
{
|
|
nw::ifstream f_new(filename2);
|
|
std::string s;
|
|
TEST(f_new >> s && s == "Foo");
|
|
{
|
|
nw::ifstream f_old(filename);
|
|
TEST(f_old >> s && s == "Hello");
|
|
|
|
f_new = std::move(f_old);
|
|
// old is closed
|
|
TEST(!f_old.is_open());
|
|
// It is unclear if the std streams can be reused after move-from
|
|
#if NOWIDE_USE_FILEBUF_REPLACEMENT
|
|
f_old.open(filename2);
|
|
#else
|
|
f_old = nw::ifstream(filename2);
|
|
#endif
|
|
TEST(f_old);
|
|
TEST(f_old >> s);
|
|
TEST_EQ(s, "Foo");
|
|
TEST(f_old >> s && s == "Bar");
|
|
}
|
|
// new starts where the old was left of
|
|
TEST(f_new);
|
|
TEST(f_new >> s);
|
|
TEST_EQ(s, "World");
|
|
}
|
|
// Swap
|
|
{
|
|
nw::ifstream f_old(filename);
|
|
std::string s;
|
|
TEST(f_old >> s && s == "Hello");
|
|
|
|
nw::ifstream f_new(filename2);
|
|
TEST(f_new >> s && s == "Foo");
|
|
|
|
// After swapping both are valid and where they left
|
|
f_new.swap(f_old);
|
|
TEST(f_old >> s);
|
|
TEST_EQ(s, "Bar");
|
|
|
|
TEST(f_new >> s);
|
|
TEST_EQ(s, "World");
|
|
|
|
f_new.close();
|
|
swap(f_new, f_old);
|
|
TEST(!f_old.is_open());
|
|
TEST(f_new.is_open());
|
|
}
|
|
}
|
|
|
|
// coverity[root_function]
|
|
void test_main(int, char** argv, char**)
|
|
{
|
|
const std::string exampleFilename = std::string(argv[0]) + "-\xd7\xa9-\xd0\xbc-\xce\xbd.txt";
|
|
|
|
test_ctor(exampleFilename.c_str());
|
|
test_ctor(exampleFilename);
|
|
test_open(exampleFilename.c_str());
|
|
test_open(exampleFilename);
|
|
test_move_and_swap(exampleFilename);
|
|
}
|