summaryrefslogtreecommitdiff
path: root/AK/MemoryStream.h
diff options
context:
space:
mode:
authorTim Schumacher <timschumi@gmx.de>2023-01-25 20:19:05 +0100
committerAndrew Kaster <andrewdkaster@gmail.com>2023-01-29 19:16:44 -0700
commit093cf428a3d7473f429a589f1573d9ac1c41d762 (patch)
tree7314dbfc855b44470a78756e1e41f43bdd56d083 /AK/MemoryStream.h
parent11550f582ba99d317717ef76fef23118fa226ee1 (diff)
downloadserenity-093cf428a3d7473f429a589f1573d9ac1c41d762.zip
AK: Move memory streams from `LibCore`
Diffstat (limited to 'AK/MemoryStream.h')
-rw-r--r--AK/MemoryStream.h81
1 files changed, 81 insertions, 0 deletions
diff --git a/AK/MemoryStream.h b/AK/MemoryStream.h
new file mode 100644
index 0000000000..c19de82cff
--- /dev/null
+++ b/AK/MemoryStream.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2021, kleines Filmröllchen <filmroellchen@serenityos.org>.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/OwnPtr.h>
+#include <AK/Stream.h>
+#include <AK/Vector.h>
+
+namespace AK {
+
+/// A stream class that allows for reading/writing on a preallocated memory area
+/// using a single read/write head.
+class FixedMemoryStream final : public SeekableStream {
+public:
+ static ErrorOr<NonnullOwnPtr<FixedMemoryStream>> construct(Bytes bytes);
+ static ErrorOr<NonnullOwnPtr<FixedMemoryStream>> construct(ReadonlyBytes bytes);
+
+ virtual bool is_eof() const override;
+ virtual bool is_open() const override;
+ virtual void close() override;
+ virtual ErrorOr<void> truncate(off_t) override;
+ virtual ErrorOr<Bytes> read(Bytes bytes) override;
+
+ virtual ErrorOr<size_t> seek(i64 offset, SeekMode seek_mode = SeekMode::SetPosition) override;
+
+ virtual ErrorOr<size_t> write(ReadonlyBytes bytes) override;
+ virtual ErrorOr<void> write_entire_buffer(ReadonlyBytes bytes) override;
+
+ 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 };
+};
+
+/// A stream class that allows for writing to an automatically allocating memory area
+/// and reading back the written data afterwards.
+class AllocatingMemoryStream final : public Stream {
+public:
+ virtual ErrorOr<Bytes> read(Bytes) override;
+ virtual ErrorOr<size_t> write(ReadonlyBytes) override;
+ virtual ErrorOr<void> discard(size_t) override;
+ virtual bool is_eof() const override;
+ virtual bool is_open() const override;
+ virtual void close() override;
+
+ size_t used_buffer_size() const;
+
+ ErrorOr<Optional<size_t>> offset_of(ReadonlyBytes needle) const;
+
+private:
+ // Note: We set the inline buffer capacity to zero to make moving chunks as efficient as possible.
+ using Chunk = AK::Detail::ByteBuffer<0>;
+ static constexpr size_t chunk_size = 4096;
+
+ ErrorOr<ReadonlyBytes> next_read_range();
+ ErrorOr<Bytes> next_write_range();
+ void cleanup_unused_chunks();
+
+ Vector<Chunk> m_chunks;
+ size_t m_read_offset = 0;
+ size_t m_write_offset = 0;
+};
+
+}
+
+#if USING_AK_GLOBALLY
+using AK::AllocatingMemoryStream;
+using AK::FixedMemoryStream;
+#endif