/* vim:set ts=2 sw=2 sts=2 et: */ /** * \author Marcus Holland-Moritz (github@mhxnet.de) * \copyright Copyright (c) Marcus Holland-Moritz * * This file is part of dwarfs. * * dwarfs is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * dwarfs is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with dwarfs. If not, see . */ #include #include #include #include #include #include #include namespace dwarfs { namespace { void assign_error_code(std::error_code& ec) { ec.assign(errno, std::generic_category()); } class file_input_stream : public input_stream { public: file_input_stream(std::filesystem::path const& path, std::error_code& ec, std::ios_base::openmode mode) : is_{path.string().c_str(), mode} { if (is_.bad() || is_.fail() || !is_.is_open()) { assign_error_code(ec); } } std::istream& is() override { return is_; } void close(std::error_code& ec) override { is_.close(); if (is_.bad()) { assign_error_code(ec); } } void close() override { std::error_code ec; close(ec); if (ec) { throw std::system_error(ec, "close()"); } } private: std::ifstream is_; }; class file_output_stream : public output_stream { public: file_output_stream(std::filesystem::path const& path, std::error_code& ec, std::ios_base::openmode mode) : os_{path.string().c_str(), mode} { if (os_.bad() || os_.fail() || !os_.is_open()) { assign_error_code(ec); } } std::ostream& os() override { return os_; } void close(std::error_code& ec) override { os_.close(); if (os_.bad()) { assign_error_code(ec); } } void close() override { std::error_code ec; close(ec); if (ec) { throw std::system_error(ec, "close()"); } } private: std::ofstream os_; }; class file_access_generic : public file_access { public: bool exists(std::filesystem::path const& path) const override { return std::filesystem::exists(path); } std::unique_ptr open_input(std::filesystem::path const& path, std::error_code& ec) const override { auto rv = std::make_unique(path, ec, std::ios::in); if (ec) { rv.reset(); } return rv; } std::unique_ptr open_input(std::filesystem::path const& path) const override { std::error_code ec; auto rv = open_input(path, ec); if (ec) { throw std::system_error(ec, fmt::format("open_input('{}')", path.string())); } return rv; } std::unique_ptr open_input_binary(std::filesystem::path const& path, std::error_code& ec) const override { auto rv = std::make_unique(path, ec, std::ios::binary); if (ec) { rv.reset(); } return rv; } std::unique_ptr open_input_binary(std::filesystem::path const& path) const override { std::error_code ec; auto rv = open_input_binary(path, ec); if (ec) { throw std::system_error( ec, fmt::format("open_input_binary('{}')", path.string())); } return rv; } std::unique_ptr open_output(std::filesystem::path const& path, std::error_code& ec) const override { auto rv = std::make_unique(path, ec, std::ios::trunc); if (ec) { rv.reset(); } return rv; } std::unique_ptr open_output(std::filesystem::path const& path) const override { std::error_code ec; auto rv = open_output(path, ec); if (ec) { throw std::system_error(ec, fmt::format("open_output('{}')", path.string())); } return rv; } std::unique_ptr open_output_binary(std::filesystem::path const& path, std::error_code& ec) const override { auto rv = std::make_unique( path, ec, std::ios::binary | std::ios::trunc); if (ec) { rv.reset(); } return rv; } std::unique_ptr open_output_binary(std::filesystem::path const& path) const override { std::error_code ec; auto rv = open_output_binary(path, ec); if (ec) { throw std::system_error( ec, fmt::format("open_output_binary('{}')", path.string())); } return rv; } }; } // namespace std::unique_ptr create_file_access_generic() { return std::make_unique(); } } // namespace dwarfs