diff options
Diffstat (limited to 'sax/src/buffer.hh')
| -rw-r--r-- | sax/src/buffer.hh | 108 |
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 |
