mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibCore: Introduce MemoryStream
MemoryStream is the Core::Stream API's streamlike access to a chunk of memory, mimicking AK::DuplexMemoryStream. The implementation is very similar, except that no APIs except the SeekableStream operations currently exist. This will be fine for the first users and can be expanded upon later.
This commit is contained in:
parent
caeb8fc691
commit
d786142eca
Notes:
sideshowbarker
2024-07-17 20:30:10 +09:00
Author: https://github.com/kleinesfilmroellchen Commit: https://github.com/SerenityOS/serenity/commit/d786142ecad Pull-request: https://github.com/SerenityOS/serenity/pull/11344 Reviewed-by: https://github.com/alimpfard ✅ Reviewed-by: https://github.com/sin-ack
1 changed files with 98 additions and 0 deletions
98
Userland/Libraries/LibCore/MemoryStream.h
Normal file
98
Userland/Libraries/LibCore/MemoryStream.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2021, kleines Filmröllchen <filmroellchen@serenityos.org>.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Error.h>
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/Span.h>
|
||||
#include <AK/TypedTransfer.h>
|
||||
#include <LibCore/Stream.h>
|
||||
|
||||
namespace Core::Stream {
|
||||
|
||||
class MemoryStream final : public SeekableStream {
|
||||
public:
|
||||
static ErrorOr<NonnullOwnPtr<MemoryStream>> construct(Bytes bytes)
|
||||
{
|
||||
return adopt_nonnull_own_or_enomem<MemoryStream>(new (nothrow) MemoryStream(bytes));
|
||||
}
|
||||
|
||||
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 { }
|
||||
|
||||
virtual ErrorOr<size_t> read(Bytes bytes) override
|
||||
{
|
||||
auto to_read = min(remaining(), bytes.size());
|
||||
if (to_read == 0)
|
||||
return 0;
|
||||
|
||||
m_bytes.slice(m_offset, to_read).copy_to(bytes);
|
||||
m_offset += to_read;
|
||||
return bytes.size();
|
||||
}
|
||||
|
||||
virtual ErrorOr<off_t> seek(i64 offset, SeekMode seek_mode = SeekMode::SetPosition) override
|
||||
{
|
||||
switch (seek_mode) {
|
||||
case SeekMode::SetPosition:
|
||||
if (offset >= static_cast<i64>(m_bytes.size()))
|
||||
return Error::from_string_literal("Offset past the end of the stream memory"sv);
|
||||
|
||||
m_offset = offset;
|
||||
break;
|
||||
case SeekMode::FromCurrentPosition:
|
||||
if (offset + static_cast<i64>(m_offset) >= static_cast<i64>(m_bytes.size()))
|
||||
return Error::from_string_literal("Offset past the end of the stream memory"sv);
|
||||
|
||||
m_offset += offset;
|
||||
break;
|
||||
case SeekMode::FromEndPosition:
|
||||
if (offset >= static_cast<i64>(m_bytes.size()))
|
||||
return Error::from_string_literal("Offset past the start of the stream memory"sv);
|
||||
|
||||
m_offset = m_bytes.size() - offset;
|
||||
break;
|
||||
}
|
||||
return static_cast<off_t>(m_offset);
|
||||
}
|
||||
|
||||
virtual ErrorOr<size_t> write(ReadonlyBytes bytes) override
|
||||
{
|
||||
// FIXME: Can this not error?
|
||||
const auto nwritten = bytes.copy_trimmed_to(m_bytes.slice(m_offset));
|
||||
m_offset += nwritten;
|
||||
return nwritten;
|
||||
}
|
||||
virtual bool write_or_error(ReadonlyBytes bytes) override
|
||||
{
|
||||
if (remaining() < bytes.size())
|
||||
return false;
|
||||
|
||||
MUST(write(bytes));
|
||||
return true;
|
||||
}
|
||||
|
||||
Bytes bytes() { 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 MemoryStream(Bytes bytes)
|
||||
: m_bytes(bytes)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
Bytes m_bytes;
|
||||
size_t m_offset { 0 };
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in a new issue