summaryrefslogtreecommitdiff
path: root/AK/CircularBuffer.h
diff options
context:
space:
mode:
authorLucas CHOLLET <lucas.chollet@free.fr>2022-12-08 22:44:46 +0100
committerAndrew Kaster <andrewdkaster@gmail.com>2022-12-31 04:44:17 -0700
commitf12e81b74a0395022581af443982e8cffb9b5c71 (patch)
tree173a2ad49e18dd3243c93501d0bf20c7a6d766b2 /AK/CircularBuffer.h
parent3454891d3877c41e3daf6ff4bf29c602643a897c (diff)
downloadserenity-f12e81b74a0395022581af443982e8cffb9b5c71.zip
AK: Add `CircularBuffer`
The class is very similar to `CircularDuplexStream` in its behavior. Main differences are that `CircularBuffer`: - does not inherit from `AK::Stream` - uses `ErrorOr` for its API - is heap allocated (and OOM-Safe) This patch also add some tests.
Diffstat (limited to 'AK/CircularBuffer.h')
-rw-r--r--AK/CircularBuffer.h67
1 files changed, 67 insertions, 0 deletions
diff --git a/AK/CircularBuffer.h b/AK/CircularBuffer.h
new file mode 100644
index 0000000000..0f121986f4
--- /dev/null
+++ b/AK/CircularBuffer.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2022, Lucas Chollet <lucas.chollet@free.fr>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/ByteBuffer.h>
+#include <AK/Error.h>
+#include <AK/Noncopyable.h>
+
+namespace AK {
+
+class CircularBuffer {
+ AK_MAKE_NONCOPYABLE(CircularBuffer);
+
+public:
+ static ErrorOr<CircularBuffer> create_empty(size_t size);
+ static ErrorOr<CircularBuffer> create_initialized(ByteBuffer);
+
+ CircularBuffer(CircularBuffer&& other)
+ {
+ operator=(move(other));
+ }
+
+ CircularBuffer& operator=(CircularBuffer&& other)
+ {
+ if (&other == this)
+ return *this;
+
+ swap(m_buffer, other.m_buffer);
+ swap(m_reading_head, other.m_reading_head);
+ swap(m_used_space, other.m_used_space);
+
+ return *this;
+ }
+
+ ~CircularBuffer() = default;
+
+ size_t write(ReadonlyBytes bytes);
+ Bytes read(Bytes bytes);
+ ErrorOr<void> discard(size_t discarded_bytes);
+
+ [[nodiscard]] size_t empty_space() const;
+ [[nodiscard]] size_t used_space() const;
+ [[nodiscard]] size_t capacity() const;
+
+ Optional<size_t> offset_of(StringView needle, Optional<size_t> until = {}) const;
+
+ void clear();
+
+private:
+ CircularBuffer(ByteBuffer);
+
+ [[nodiscard]] bool is_wrapping_around() const;
+
+ [[nodiscard]] Bytes next_write_span();
+ [[nodiscard]] ReadonlyBytes next_read_span() const;
+
+ ByteBuffer m_buffer {};
+
+ size_t m_reading_head {};
+ size_t m_used_space {};
+};
+
+}