// // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // Official repository: https://github.com/boostorg/beast // #ifndef BOOST_BEAST_FILE_TEST_HPP #define BOOST_BEAST_FILE_TEST_HPP #include #include #include #include #include #include #include #include namespace boost { namespace beast { template void test_file() { BOOST_STATIC_ASSERT( is_file::value); BOOST_STATIC_ASSERT( ! std::is_copy_constructible::value); BOOST_STATIC_ASSERT( ! std::is_copy_assignable::value); namespace fs = boost::filesystem; class temp_path { fs::path path_; std::string str_; public: temp_path() : path_(fs::unique_path()) , str_(path_.string()) { } operator fs::path const&() { return path_; } operator char const*() { return str_.c_str(); } }; auto const create = [](fs::path const& path) { auto const s = path.string(); BEAST_EXPECT(! fs::exists(path)); FILE* f = ::fopen(s.c_str(), "w"); if( BEAST_EXPECT(f != nullptr)) ::fclose(f); }; auto const remove = [](fs::path const& path) { error_code ec; fs::remove(path); }; temp_path path; // bad file descriptor { File f; char buf[1]; BEAST_EXPECT(! f.is_open()); BEAST_EXPECT(! fs::exists(path)); { error_code ec; f.size(ec); BEAST_EXPECT(ec == errc::bad_file_descriptor); } { error_code ec; f.pos(ec); BEAST_EXPECT(ec == errc::bad_file_descriptor); } { error_code ec; f.seek(0, ec); BEAST_EXPECT(ec == errc::bad_file_descriptor); } { error_code ec; f.read(buf, 0, ec); BEAST_EXPECT(ec == errc::bad_file_descriptor); } { error_code ec; f.write(buf, 0, ec); BEAST_EXPECT(ec == errc::bad_file_descriptor); } } // file_mode::read { { File f; error_code ec; create(path); f.open(path, file_mode::read, ec); BEAST_EXPECT(! ec); } remove(path); } // file_mode::scan { { File f; error_code ec; create(path); f.open(path, file_mode::scan, ec); BEAST_EXPECT(! ec); } remove(path); } // file_mode::write { { File f; error_code ec; BEAST_EXPECT(! fs::exists(path)); f.open(path, file_mode::write, ec); BEAST_EXPECT(! ec); BEAST_EXPECT(fs::exists(path)); } { File f; error_code ec; BEAST_EXPECT(fs::exists(path)); f.open(path, file_mode::write, ec); BEAST_EXPECT(! ec); BEAST_EXPECT(fs::exists(path)); } remove(path); } // file_mode::write_new { { File f; error_code ec; BEAST_EXPECT(! fs::exists(path)); f.open(path, file_mode::write_new, ec); BEAST_EXPECT(! ec); BEAST_EXPECT(fs::exists(path)); } { File f; error_code ec; BEAST_EXPECT(fs::exists(path)); f.open(path, file_mode::write_new, ec); BEAST_EXPECT(ec); } remove(path); } // file_mode::write_existing { { File f; error_code ec; BEAST_EXPECT(! fs::exists(path)); f.open(path, file_mode::write_existing, ec); BEAST_EXPECT(ec); BEAST_EXPECT(! fs::exists(path)); } { File f; error_code ec; create(path); BEAST_EXPECT(fs::exists(path)); f.open(path, file_mode::write_existing, ec); BEAST_EXPECT(! ec); } remove(path); } // file_mode::append { { File f; error_code ec; BEAST_EXPECT(! fs::exists(path)); f.open(path, file_mode::append, ec); BEAST_EXPECT(! ec); BEAST_EXPECT(fs::exists(path)); } { File f; error_code ec; BEAST_EXPECT(fs::exists(path)); f.open(path, file_mode::append, ec); BEAST_EXPECT(! ec); BEAST_EXPECT(fs::exists(path)); } remove(path); } // file_mode::append_existing { { File f; error_code ec; BEAST_EXPECT(! fs::exists(path)); f.open(path, file_mode::append_existing, ec); BEAST_EXPECT(ec); BEAST_EXPECT(! fs::exists(path)); } remove(path); { File f; error_code ec; create(path); BEAST_EXPECT(fs::exists(path)); f.open(path, file_mode::append_existing, ec); BEAST_EXPECT(! ec); } remove(path); } // special members { { File f1; error_code ec; f1.open(path, file_mode::write, ec); BEAST_EXPECT(! ec); BEAST_EXPECT(f1.is_open()); // move constructor File f2(std::move(f1)); BEAST_EXPECT(! f1.is_open()); BEAST_EXPECT(f2.is_open()); // move assignment File f3; f3 = std::move(f2); BEAST_EXPECT(! f2.is_open()); BEAST_EXPECT(f3.is_open()); } remove(path); } // re-open { { File f; error_code ec; f.open(path, file_mode::write, ec); BEAST_EXPECT(! ec); f.open(path, file_mode::write, ec); BEAST_EXPECT(! ec); } remove(path); } // re-assign { temp_path path2; { error_code ec; File f1; f1.open(path, file_mode::write, ec); BEAST_EXPECT(! ec); File f2; f2.open(path2, file_mode::write, ec); BEAST_EXPECT(! ec); f2 = std::move(f1); BEAST_EXPECT(! f1.is_open()); BEAST_EXPECT(f2.is_open()); } remove(path); remove(path2); } // self-move { { File f; error_code ec; f.open(path, file_mode::write, ec); BEAST_EXPECT(! ec); f = std::move(f); BEAST_EXPECT(f.is_open()); } remove(path); } // native_handle { { File f; auto none = f.native_handle(); error_code ec; f.open(path, file_mode::write, ec); BEAST_EXPECT(! ec); auto fd = f.native_handle(); BEAST_EXPECT(fd != none); f.native_handle(none); BEAST_EXPECT(! f.is_open()); } remove(path); } // read and write { string_view const s = "Hello, world!"; // write { File f; error_code ec; f.open(path, file_mode::write, ec); BEAST_EXPECT(! ec); f.write(s.data(), s.size(), ec); BEAST_EXPECT(! ec); auto size = f.size(ec); BEAST_EXPECT(! ec); BEAST_EXPECT(size == s.size()); auto pos = f.pos(ec); BEAST_EXPECT(! ec); BEAST_EXPECT(pos == size); f.close(ec); BEAST_EXPECT(! ec); } // read { File f; error_code ec; f.open(path, file_mode::read, ec); BEAST_EXPECT(! ec); std::string buf; buf.resize(s.size()); f.read(&buf[0], buf.size(), ec); BEAST_EXPECT(! ec); BEAST_EXPECT(buf == s); f.seek(1, ec); BEAST_EXPECT(! ec); buf.resize(3); f.read(&buf[0], buf.size(), ec); BEAST_EXPECT(! ec); BEAST_EXPECT(buf == "ell"); auto pos = f.pos(ec); BEAST_EXPECT(! ec); BEAST_EXPECT(pos == 4); } remove(path); } BEAST_EXPECT(! fs::exists(path)); } } // beast } // boost #endif