Serenity Operating System
1/*
2 * Copyright (c) 2021, kleines Filmröllchen <filmroellchen@serenityos.org>.
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <AK/OwnPtr.h>
10#include <AK/Stream.h>
11#include <AK/Vector.h>
12
13namespace AK {
14
15/// A stream class that allows for reading/writing on a preallocated memory area
16/// using a single read/write head.
17class FixedMemoryStream final : public SeekableStream {
18public:
19 explicit FixedMemoryStream(Bytes bytes);
20 explicit FixedMemoryStream(ReadonlyBytes bytes);
21
22 virtual bool is_eof() const override;
23 virtual bool is_open() const override;
24 virtual void close() override;
25 virtual ErrorOr<void> truncate(size_t) override;
26 virtual ErrorOr<Bytes> read_some(Bytes bytes) override;
27
28 virtual ErrorOr<size_t> seek(i64 offset, SeekMode seek_mode = SeekMode::SetPosition) override;
29
30 virtual ErrorOr<size_t> write_some(ReadonlyBytes bytes) override;
31 virtual ErrorOr<void> write_until_depleted(ReadonlyBytes bytes) override;
32
33 Bytes bytes();
34 ReadonlyBytes bytes() const;
35 size_t offset() const;
36 size_t remaining() const;
37
38private:
39 Bytes m_bytes;
40 size_t m_offset { 0 };
41 bool m_writing_enabled { true };
42};
43
44/// A stream class that allows for writing to an automatically allocating memory area
45/// and reading back the written data afterwards.
46class AllocatingMemoryStream final : public Stream {
47public:
48 virtual ErrorOr<Bytes> read_some(Bytes) override;
49 virtual ErrorOr<size_t> write_some(ReadonlyBytes) override;
50 virtual ErrorOr<void> discard(size_t) override;
51 virtual bool is_eof() const override;
52 virtual bool is_open() const override;
53 virtual void close() override;
54
55 size_t used_buffer_size() const;
56
57 ErrorOr<Optional<size_t>> offset_of(ReadonlyBytes needle) const;
58
59private:
60 // Note: We set the inline buffer capacity to zero to make moving chunks as efficient as possible.
61 using Chunk = AK::Detail::ByteBuffer<0>;
62 static constexpr size_t chunk_size = 4096;
63
64 ErrorOr<ReadonlyBytes> next_read_range();
65 ErrorOr<Bytes> next_write_range();
66 void cleanup_unused_chunks();
67
68 Vector<Chunk> m_chunks;
69 size_t m_read_offset = 0;
70 size_t m_write_offset = 0;
71};
72
73}
74
75#if USING_AK_GLOBALLY
76using AK::AllocatingMemoryStream;
77using AK::FixedMemoryStream;
78#endif