blob: d9fb9fc4959d1934d64bd9bbbdea5332b77d87a1 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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
|