summaryrefslogtreecommitdiff
path: root/modules/core/buffer.h
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2023-12-04 12:18:14 +0100
committerClaudius "keldu" Holeksa <mail@keldu.de>2023-12-04 12:18:14 +0100
commita14896f9ed209dd3f9597722e5a5697bd7dbf531 (patch)
tree089ca5cbbd206d1921f8f6b53292f5bc1902ca5c /modules/core/buffer.h
parent84ecdcbca9e55b1f57fbb832e12ff4fdbb86e7c9 (diff)
meta: Renamed folder containing source
Diffstat (limited to 'modules/core/buffer.h')
-rw-r--r--modules/core/buffer.h199
1 files changed, 199 insertions, 0 deletions
diff --git a/modules/core/buffer.h b/modules/core/buffer.h
new file mode 100644
index 0000000..f0cf76e
--- /dev/null
+++ b/modules/core/buffer.h
@@ -0,0 +1,199 @@
+#pragma once
+
+#include "error.h"
+
+#include <array>
+#include <cstdint>
+#include <deque>
+#include <list>
+#include <string>
+#include <vector>
+
+namespace saw {
+/*
+ * Access class to reduce templated BufferSegments bloat
+ */
+class buffer {
+protected:
+ ~buffer() = default;
+
+public:
+ virtual size_t read_position() const = 0;
+ virtual size_t read_composite_length() const = 0;
+ virtual size_t read_segment_length(size_t offset = 0) const = 0;
+ virtual void read_advance(size_t bytes) = 0;
+
+ virtual uint8_t &read(size_t i = 0) = 0;
+ virtual const uint8_t &read(size_t i = 0) const = 0;
+
+ virtual size_t write_position() const = 0;
+ virtual size_t write_composite_length() const = 0;
+ virtual size_t write_segment_length(size_t offset = 0) const = 0;
+ virtual void write_advance(size_t bytes) = 0;
+
+ virtual uint8_t &write(size_t i = 0) = 0;
+ virtual const uint8_t &write(size_t i = 0) const = 0;
+
+ /*
+ * Sometime buffers need to grow with a little more control
+ * than with push and pop for more efficient calls.
+ * There is nothing you can do if read hasn't been filled, but at
+ * least write can be increased if it is demanded.
+ */
+ virtual error write_require_length(size_t bytes) = 0;
+
+ error push(const uint8_t &value);
+ error push(const uint8_t &buffer, size_t size);
+ error pop(uint8_t &value);
+ error pop(uint8_t &buffer, size_t size);
+
+};
+
+/**
+ * Converts a buffer to a string for convenience cases
+ */
+std::string convert_to_string(const buffer& buf);
+
+/**
+ *
+ */
+
+/*
+ * A viewer class for buffers.
+ * Working on the reference buffer invalidates the buffer view
+ */
+class buffer_view : public buffer {
+private:
+ buffer *buffer_;
+ size_t read_offset_;
+ size_t write_offset_;
+
+public:
+ buffer_view(buffer &);
+
+ size_t read_position() const override;
+ size_t read_composite_length() const override;
+ size_t read_segment_length(size_t offset = 0) const override;
+ void read_advance(size_t bytes) override;
+
+ uint8_t &read(size_t i = 0) override;
+ const uint8_t &read(size_t i = 0) const override;
+
+ size_t write_position() const override;
+ size_t write_composite_length() const override;
+ size_t write_segment_length(size_t offset = 0) const override;
+ void write_advance(size_t bytes) override;
+
+ uint8_t &write(size_t i = 0) override;
+ const uint8_t &write(size_t i = 0) const override;
+
+ error write_require_length(size_t bytes) override;
+
+ size_t read_offset() const;
+ size_t write_offset() const;
+};
+
+/*
+ * Buffer size meant for default allocation size of the ringbuffer since
+ * this class currently doesn't support proper resizing
+ */
+constexpr size_t RING_BUFFER_MAX_SIZE = 4096;
+/*
+ * Buffer wrapping around if read caught up
+ */
+class ring_buffer final : public buffer {
+private:
+ std::vector<uint8_t> buffer_;
+ size_t read_position_;
+ size_t write_position_;
+ bool write_reached_read_ = false;
+
+public:
+ ring_buffer();
+ ring_buffer(size_t size);
+
+ inline size_t size() const { return buffer_.size(); }
+
+ inline uint8_t &operator[](size_t i) { return buffer_[i]; }
+ inline const uint8_t &operator[](size_t i) const { return buffer_[i]; }
+
+ size_t read_position() const override;
+ size_t read_composite_length() const override;
+ size_t read_segment_length(size_t offset = 0) const override;
+ void read_advance(size_t bytes) override;
+
+ uint8_t &read(size_t i = 0) override;
+ const uint8_t &read(size_t i = 0) const override;
+
+ size_t write_position() const override;
+ size_t write_composite_length() const override;
+ size_t write_segment_length(size_t offset = 0) const override;
+ void write_advance(size_t bytes) override;
+
+ uint8_t &write(size_t i = 0) override;
+ const uint8_t &write(size_t i = 0) const override;
+
+ error write_require_length(size_t bytes) override;
+};
+
+/*
+ * One time buffer
+ */
+class array_buffer : public buffer {
+private:
+ std::vector<uint8_t> buffer_;
+
+ size_t read_position_;
+ size_t write_position_;
+
+public:
+ array_buffer(size_t size);
+
+ size_t read_position() const override;
+ size_t read_composite_length() const override;
+ size_t read_segment_length(size_t offset = 0) const override;
+ void read_advance(size_t bytes) override;
+
+ uint8_t &read(size_t i = 0) override;
+ const uint8_t &read(size_t i = 0) const override;
+
+ size_t write_position() const override;
+ size_t write_composite_length() const override;
+ size_t write_segment_length(size_t offset = 0) const override;
+ void write_advance(size_t bytes) override;
+
+ uint8_t &write(size_t i = 0) override;
+ const uint8_t &write(size_t i = 0) const override;
+
+ error write_require_length(size_t bytes) override;
+};
+
+class chain_array_buffer : public buffer {
+private:
+ std::deque<array_buffer> buffer_;
+
+ size_t read_position_;
+ size_t write_position_;
+
+public:
+ chain_array_buffer();
+
+ size_t read_position() const override;
+ size_t read_composite_length() const override;
+ size_t read_segment_length(size_t offset = 0) const override;
+ void read_advance(size_t bytes) override;
+
+ uint8_t &read(size_t i = 0) override;
+ const uint8_t &read(size_t i = 0) const override;
+
+ size_t write_position() const override;
+ size_t write_composite_length() const override;
+ size_t write_segment_length(size_t offset = 0) const override;
+ void write_advance(size_t bytes) override;
+
+ uint8_t &write(size_t i = 0) override;
+ const uint8_t &write(size_t i = 0) const override;
+
+ error write_require_length(size_t bytes) override;
+};
+} // namespace saw