/* * Copyright (c) 2020, the SerenityOS developers. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include namespace Core { class InputFileStream final : public InputStream { public: explicit InputFileStream(NonnullRefPtr file) : m_file(file) { } static ErrorOr open(StringView filename, OpenMode mode = OpenMode::ReadOnly, mode_t permissions = 0644) { VERIFY(has_flag(mode, OpenMode::ReadOnly)); auto file = TRY(File::open(filename, mode, permissions)); return InputFileStream { move(file) }; } static ErrorOr> open_buffered(StringView filename, OpenMode mode = OpenMode::ReadOnly, mode_t permissions = 0644) { VERIFY(has_flag(mode, OpenMode::ReadOnly)); auto file = TRY(File::open(filename, mode, permissions)); return Buffered { move(file) }; } size_t read(Bytes bytes) override { if (has_any_error()) return 0; auto const buffer = m_file->read(bytes.size()); return buffer.bytes().copy_to(bytes); } bool read_or_error(Bytes bytes) override { if (read(bytes) < bytes.size()) { set_fatal_error(); return false; } return true; } bool seek(size_t offset, SeekMode whence = SeekMode::SetPosition) { return m_file->seek(offset, whence); } bool discard_or_error(size_t count) override { return m_file->seek(count, SeekMode::FromCurrentPosition); } bool unreliable_eof() const override { return m_file->eof(); } void close() { if (!m_file->close()) set_fatal_error(); } private: NonnullRefPtr m_file; }; class OutputFileStream : public OutputStream { public: explicit OutputFileStream(NonnullRefPtr file) : m_file(file) { } static ErrorOr open(StringView filename, OpenMode mode = OpenMode::WriteOnly, mode_t permissions = 0644) { VERIFY(has_flag(mode, OpenMode::WriteOnly)); auto file = TRY(File::open(filename, mode, permissions)); return OutputFileStream { move(file) }; } static ErrorOr> open_buffered(StringView filename, OpenMode mode = OpenMode::WriteOnly, mode_t permissions = 0644) { VERIFY(has_flag(mode, OpenMode::WriteOnly)); auto file = TRY(File::open(filename, mode, permissions)); return Buffered { move(file) }; } static OutputFileStream standard_output() { return OutputFileStream { Core::File::standard_output() }; } static OutputFileStream standard_error() { return OutputFileStream { Core::File::standard_error() }; } static Buffered stdout_buffered() { return Buffered { Core::File::standard_output() }; } size_t write(ReadonlyBytes bytes) override { if (!m_file->write(bytes.data(), bytes.size())) { set_fatal_error(); return 0; } return bytes.size(); } bool write_or_error(ReadonlyBytes bytes) override { if (write(bytes) < bytes.size()) { set_fatal_error(); return false; } return true; } void close() { if (!m_file->close()) set_fatal_error(); } private: NonnullRefPtr m_file; }; }