summaryrefslogtreecommitdiff
path: root/sax/src/buffer.hh
diff options
context:
space:
mode:
Diffstat (limited to 'sax/src/buffer.hh')
-rw-r--r--sax/src/buffer.hh108
1 files changed, 108 insertions, 0 deletions
diff --git a/sax/src/buffer.hh b/sax/src/buffer.hh
new file mode 100644
index 0000000..d9fb9fc
--- /dev/null
+++ b/sax/src/buffer.hh
@@ -0,0 +1,108 @@
+#ifndef BUFFER_HH
+#define BUFFER_HH
+
+#include "macros.hh"
+
+#include <memory>
+#include <span>
+
+namespace modxml {
+namespace sax {
+
+class HIDDEN Buffer {
+ public:
+ virtual ~Buffer() = default;
+
+ Buffer(Buffer const&) = delete;
+ Buffer& operator=(Buffer const&) = delete;
+
+ // Returns a writable span, either at least need large or in case
+ // the buffer is full, an empty span.
+ // Returned span is valid until any other method is called on the buffer.
+ virtual std::span<uint8_t> wspan(std::size_t need = 1) = 0;
+ // Commit size data from the last returned wspan. size must be <= span.size.
+ // Remember that the span is now invalid and you need to call wspan again
+ // to write more.
+ virtual void commit(std::size_t size) = 0;
+
+ // Returns a readable span of all readily available data in buffer.
+ // If there is enought data in the buffer to satisfy want, the returned
+ // span is at least as large.
+ // Returned span is valid until any other method is called on the buffer.
+ virtual std::span<uint8_t const> rspan(std::size_t want = 1) = 0;
+ // Consume size data from buffer. size must be <= span.size.
+ // Remember that the span is now invalid and you need to call rspan again
+ // to read more.
+ virtual void consume(std::size_t size) = 0;
+
+ // Returns the same span as rspan but this is writable, you can modify
+ // the content. You cannot change the size of the span.
+ // If you wish to append data, use wspan() + commit().
+ // If you wish to remove data, use uncommit().
+ // If you wish to insert you have to be clever.
+ // Returned span is valid until any other method is called on the buffer.
+ virtual std::span<uint8_t> mspan(std::size_t want = 1) = 0;
+
+ // Uncommit the last size bytes in the buffer. Returns the bytes
+ // removed. If you used wspan() + commit() to add ten (10) bytes say and then
+ // call uncommit() with a size of seven (7) the first three (3) bytes written
+ // will the left in the buffer.
+ virtual std::size_t uncommit(std::size_t size) = 0;
+
+ // Returns true if buffer is empty.
+ virtual bool empty() const = 0;
+
+ // Returns true if buffer is full. This means filled to max_size.
+ virtual bool full() const = 0;
+
+ // Clear buffer, reset back to initial state.
+ virtual void reset() = 0;
+
+ // Write as much as possible of data to buffer.
+ // Returns bytes written (may be zero).
+ std::size_t write(std::span<uint8_t const> data);
+
+ // Either write all of the data to buffer or none. Returns true if data was
+ // written or data was empty.
+ bool write_all(std::span<uint8_t const> data);
+
+ // Read as much as possible from buffer to data.
+ // Returns bytes read (may be zero).
+ std::size_t read(std::span<uint8_t> data);
+
+ // Either fill data with data from buffer or return false.
+ bool read_all(std::span<uint8_t> data);
+
+ protected:
+ Buffer() = default;
+};
+
+// Create a buffer. default_size is used as an hint but generally that
+// will be the initial size of the buffer. max_size is an hard limit.
+// max_size == 0 is valid but will return an always full and empty buffer.
+std::unique_ptr<Buffer> HIDDEN make_buffer(std::size_t default_size,
+ std::size_t max_size);
+
+class ReadViewBuffer : public Buffer {
+ public:
+ // Returns bytes consumed in this buffer.
+ virtual std::size_t consumed() const = 0;
+
+ // Take ownership back of the wrapped buffer from the read view.
+ // The read view is now unusable.
+ virtual std::unique_ptr<Buffer> release() = 0;
+
+ protected:
+ ReadViewBuffer() = default;
+};
+
+// Create a read view buffer. Writing will go to wrapped buffer. Reading
+// is done on the read view buffer without moving the wrapped buffers read
+// pointer. These views are lightweight.
+std::unique_ptr<ReadViewBuffer> HIDDEN make_read_view_buffer(
+ std::unique_ptr<Buffer> buffer);
+
+} // namespace sax
+} // namespace modxml
+
+#endif // BUFFER_HH