diff options
author | Lucas CHOLLET <lucas.chollet@free.fr> | 2022-12-08 22:44:46 +0100 |
---|---|---|
committer | Andrew Kaster <andrewdkaster@gmail.com> | 2022-12-31 04:44:17 -0700 |
commit | f12e81b74a0395022581af443982e8cffb9b5c71 (patch) | |
tree | 173a2ad49e18dd3243c93501d0bf20c7a6d766b2 /AK/CircularBuffer.h | |
parent | 3454891d3877c41e3daf6ff4bf29c602643a897c (diff) | |
download | serenity-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.h | 67 |
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 {}; +}; + +} |