From 7dd49c6293172b494c78918507242cdb55d35137 Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Sun, 21 Jan 2024 12:31:30 +0100 Subject: WIP --- sax/src/buffer.hh | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 sax/src/buffer.hh (limited to 'sax/src/buffer.hh') 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 +#include + +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 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 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 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 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 data); + + // Read as much as possible from buffer to data. + // Returns bytes read (may be zero). + std::size_t read(std::span data); + + // Either fill data with data from buffer or return false. + bool read_all(std::span 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 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 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 HIDDEN make_read_view_buffer( + std::unique_ptr buffer); + +} // namespace sax +} // namespace modxml + +#endif // BUFFER_HH -- cgit v1.2.3-70-g09d2