libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
bufferview.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <cstdint>
14#include <initializer_list>
15#include <promeki/buffer.h>
16#include <promeki/list.h>
17
18PROMEKI_NAMESPACE_BEGIN
19
77class BufferView {
78 public:
79 // ---- Per-slice proxy ------------------------------
80
91 class Entry {
92 friend class BufferView;
93
94 public:
96 Entry() = default;
97
99 const Buffer &buffer() const;
100
113 size_t bufferIndex() const;
114
116 size_t offset() const;
117
119 size_t size() const;
120
129 uint8_t *data();
130
132 const uint8_t *data() const;
133
135 bool isValid() const;
136
138 bool isNull() const { return !isValid(); }
139
140 private:
141 const BufferView *_list = nullptr;
142 size_t _idx = 0;
143
144 Entry(const BufferView *list, size_t idx) : _list(list), _idx(idx) {}
145 };
146
147 // ---- Iteration -----------------------------------
148
153 class Iterator {
154 friend class BufferView;
155
156 public:
157 Iterator() = default;
158 Entry operator*() const { return Entry(_list, _idx); }
159 Iterator &operator++() {
160 ++_idx;
161 return *this;
162 }
163 Iterator operator++(int) {
164 Iterator t(*this);
165 ++_idx;
166 return t;
167 }
168 bool operator==(const Iterator &o) const { return _list == o._list && _idx == o._idx; }
169 bool operator!=(const Iterator &o) const { return !(*this == o); }
170
171 private:
172 const BufferView *_list = nullptr;
173 size_t _idx = 0;
174
175 Iterator(const BufferView *list, size_t idx) : _list(list), _idx(idx) {}
176 };
177
178 // ---- Construction --------------------------------
179
181 BufferView() = default;
182
194 BufferView(Buffer buf, size_t offset, size_t size);
195
206 BufferView(std::initializer_list<BufferView> init);
207
208 // ---- List operations -----------------------------
209
211 size_t count() const { return _views.size(); }
212
214 bool isEmpty() const { return _views.isEmpty(); }
215
217 Entry operator[](size_t i) const { return Entry(this, i); }
218
219 Iterator begin() const { return Iterator(this, 0); }
220 Iterator end() const { return Iterator(this, _views.size()); }
221
222 // ---- Single-slice convenience accessors ----------
223 //
224 // These treat the list as a single byte blob. When
225 // the list holds exactly one slice they forward to
226 // that slice; on an empty list they return empty /
227 // zero / nullptr values. Call sites that manipulate
228 // multi-slice lists should use @c operator[] or
229 // iteration rather than these helpers.
230
232 const Buffer &buffer() const;
233
235 size_t offset() const;
236
244 uint8_t *data();
245
247 const uint8_t *data() const;
248
253 bool isValid() const;
254
256 bool isNull() const { return !isValid(); }
257
265 void pushToBack(Buffer buf, size_t offset, size_t size);
266
271 void append(const BufferView &other);
272
274 void clear();
275
276 // ---- Domain operations ---------------------------
277
286 size_t size() const;
287
289 size_t totalSize() const { return size(); }
290
302 bool isExclusive() const;
303
313 void ensureExclusive();
314
328 [[nodiscard]] Error seal() const;
329
330 private:
331 struct View {
332 size_t bufferIdx = 0;
333 size_t offset = 0;
334 size_t size = 0;
335 };
336
337 Buffer::List _buffers;
338 List<View> _views;
339
340 // Returns the index of @p buf in @c _buffers, inserting if not found.
341 // When @p buf is null, returns the largest representable size_t
342 // (conceptually "no buffer"); no null entry is stored.
343 size_t internBuffer(const Buffer &buf);
344};
345
346PROMEKI_NAMESPACE_END
347
348#endif // PROMEKI_ENABLE_CORE