From 8dbc7aa63fc1610f5f93f5f380dcef47d403dbe7 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Wed, 7 Dec 2022 16:22:14 +0100 Subject: [PATCH] LibCore: Move the MemoryStream implementation into a separate file --- Userland/Libraries/LibCore/CMakeLists.txt | 1 + Userland/Libraries/LibCore/MemoryStream.cpp | 127 ++++++++++++++++++++ Userland/Libraries/LibCore/MemoryStream.h | 104 +++------------- 3 files changed, 145 insertions(+), 87 deletions(-) create mode 100644 Userland/Libraries/LibCore/MemoryStream.cpp diff --git a/Userland/Libraries/LibCore/CMakeLists.txt b/Userland/Libraries/LibCore/CMakeLists.txt index 62f3a3e91b2..92cd286d797 100644 --- a/Userland/Libraries/LibCore/CMakeLists.txt +++ b/Userland/Libraries/LibCore/CMakeLists.txt @@ -14,6 +14,7 @@ set(SOURCES IODevice.cpp LockFile.cpp MappedFile.cpp + MemoryStream.cpp MimeData.cpp NetworkJob.cpp Notifier.cpp diff --git a/Userland/Libraries/LibCore/MemoryStream.cpp b/Userland/Libraries/LibCore/MemoryStream.cpp new file mode 100644 index 00000000000..0a9d0d6f07f --- /dev/null +++ b/Userland/Libraries/LibCore/MemoryStream.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2021, kleines Filmröllchen . + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +namespace Core::Stream { + +FixedMemoryStream::FixedMemoryStream(Bytes bytes) + : m_bytes(bytes) +{ +} + +FixedMemoryStream::FixedMemoryStream(ReadonlyBytes bytes) + : m_bytes({ const_cast(bytes.data()), bytes.size() }) + , m_writing_enabled(false) +{ +} + +ErrorOr> FixedMemoryStream::construct(Bytes bytes) +{ + return adopt_nonnull_own_or_enomem(new (nothrow) FixedMemoryStream(bytes)); +} + +ErrorOr> FixedMemoryStream::construct(ReadonlyBytes bytes) +{ + return adopt_nonnull_own_or_enomem(new (nothrow) FixedMemoryStream(bytes)); +} + +bool FixedMemoryStream::is_eof() const +{ + return m_offset >= m_bytes.size(); +} + +bool FixedMemoryStream::is_open() const +{ + return true; +} + +void FixedMemoryStream::close() +{ + // FIXME: It doesn't make sense to close a memory stream. Therefore, we don't do anything here. Is that fine? +} + +ErrorOr FixedMemoryStream::truncate(off_t) +{ + return Error::from_errno(ENOTSUP); +} + +ErrorOr FixedMemoryStream::read(Bytes bytes) +{ + auto to_read = min(remaining(), bytes.size()); + if (to_read == 0) + return Bytes {}; + + m_bytes.slice(m_offset, to_read).copy_to(bytes); + m_offset += to_read; + return bytes.trim(to_read); +} + +ErrorOr FixedMemoryStream::seek(i64 offset, SeekMode seek_mode) +{ + switch (seek_mode) { + case SeekMode::SetPosition: + if (offset > static_cast(m_bytes.size())) + return Error::from_string_literal("Offset past the end of the stream memory"); + + m_offset = offset; + break; + case SeekMode::FromCurrentPosition: + if (offset + static_cast(m_offset) > static_cast(m_bytes.size())) + return Error::from_string_literal("Offset past the end of the stream memory"); + + m_offset += offset; + break; + case SeekMode::FromEndPosition: + if (offset > static_cast(m_bytes.size())) + return Error::from_string_literal("Offset past the start of the stream memory"); + + m_offset = m_bytes.size() - offset; + break; + } + return static_cast(m_offset); +} + +ErrorOr FixedMemoryStream::write(ReadonlyBytes bytes) +{ + VERIFY(m_writing_enabled); + + // FIXME: Can this not error? + auto const nwritten = bytes.copy_trimmed_to(m_bytes.slice(m_offset)); + m_offset += nwritten; + return nwritten; +} + +ErrorOr FixedMemoryStream::write_entire_buffer(ReadonlyBytes bytes) +{ + if (remaining() < bytes.size()) + return Error::from_string_literal("Write of entire buffer ends past the memory area"); + + TRY(write(bytes)); + return {}; +} + +Bytes FixedMemoryStream::bytes() +{ + VERIFY(m_writing_enabled); + return m_bytes; +} +ReadonlyBytes FixedMemoryStream::bytes() const +{ + return m_bytes; +} + +size_t FixedMemoryStream::offset() const +{ + return m_offset; +} + +size_t FixedMemoryStream::remaining() const +{ + return m_bytes.size() - m_offset; +} + +} diff --git a/Userland/Libraries/LibCore/MemoryStream.h b/Userland/Libraries/LibCore/MemoryStream.h index ecaa0e9d53d..ee6b6e19eec 100644 --- a/Userland/Libraries/LibCore/MemoryStream.h +++ b/Userland/Libraries/LibCore/MemoryStream.h @@ -19,99 +19,29 @@ namespace Core::Stream { /// using a single read/write head. class FixedMemoryStream final : public SeekableStream { public: - static ErrorOr> construct(Bytes bytes) - { - return adopt_nonnull_own_or_enomem(new (nothrow) FixedMemoryStream(bytes)); - } + static ErrorOr> construct(Bytes bytes); + static ErrorOr> construct(ReadonlyBytes bytes); - static ErrorOr> construct(ReadonlyBytes bytes) - { - return adopt_nonnull_own_or_enomem(new (nothrow) FixedMemoryStream(bytes)); - } + virtual bool is_eof() const override; + virtual bool is_open() const override; + virtual void close() override; + virtual ErrorOr truncate(off_t) override; + virtual ErrorOr read(Bytes bytes) override; - virtual bool is_eof() const override { return m_offset >= m_bytes.size(); } - virtual bool is_open() const override { return true; } - // FIXME: It doesn't make sense to close an memory stream. Therefore, we don't do anything here. Is that fine? - virtual void close() override { } - // FIXME: It doesn't make sense to truncate a memory stream. Therefore, we don't do anything here. Is that fine? - virtual ErrorOr truncate(off_t) override { return Error::from_errno(ENOTSUP); } + virtual ErrorOr seek(i64 offset, SeekMode seek_mode = SeekMode::SetPosition) override; - virtual ErrorOr read(Bytes bytes) override - { - auto to_read = min(remaining(), bytes.size()); - if (to_read == 0) - return Bytes {}; + virtual ErrorOr write(ReadonlyBytes bytes) override; + virtual ErrorOr write_entire_buffer(ReadonlyBytes bytes) override; - m_bytes.slice(m_offset, to_read).copy_to(bytes); - m_offset += to_read; - return bytes.trim(to_read); - } - - virtual ErrorOr seek(i64 offset, SeekMode seek_mode = SeekMode::SetPosition) override - { - switch (seek_mode) { - case SeekMode::SetPosition: - if (offset > static_cast(m_bytes.size())) - return Error::from_string_literal("Offset past the end of the stream memory"); - - m_offset = offset; - break; - case SeekMode::FromCurrentPosition: - if (offset + static_cast(m_offset) > static_cast(m_bytes.size())) - return Error::from_string_literal("Offset past the end of the stream memory"); - - m_offset += offset; - break; - case SeekMode::FromEndPosition: - if (offset > static_cast(m_bytes.size())) - return Error::from_string_literal("Offset past the start of the stream memory"); - - m_offset = m_bytes.size() - offset; - break; - } - return static_cast(m_offset); - } - - virtual ErrorOr write(ReadonlyBytes bytes) override - { - VERIFY(m_writing_enabled); - - // FIXME: Can this not error? - auto const nwritten = bytes.copy_trimmed_to(m_bytes.slice(m_offset)); - m_offset += nwritten; - return nwritten; - } - virtual ErrorOr write_entire_buffer(ReadonlyBytes bytes) override - { - if (remaining() < bytes.size()) - return Error::from_string_literal("Write of entire buffer ends past the memory area"); - - TRY(write(bytes)); - return {}; - } - - Bytes bytes() - { - VERIFY(m_writing_enabled); - return m_bytes; - } - ReadonlyBytes bytes() const { return m_bytes; } - size_t offset() const { return m_offset; } - size_t remaining() const { return m_bytes.size() - m_offset; } - -protected: - explicit FixedMemoryStream(Bytes bytes) - : m_bytes(bytes) - { - } - - explicit FixedMemoryStream(ReadonlyBytes bytes) - : m_bytes({ const_cast(bytes.data()), bytes.size() }) - , m_writing_enabled(false) - { - } + Bytes bytes(); + ReadonlyBytes bytes() const; + size_t offset() const; + size_t remaining() const; private: + explicit FixedMemoryStream(Bytes bytes); + explicit FixedMemoryStream(ReadonlyBytes bytes); + Bytes m_bytes; size_t m_offset { 0 }; bool m_writing_enabled { true };