25template <
typename T,
template<
typename>
class BufferType>
36 size_t max_components = 0) {
38 component_size_ = component_size;
39 max_components_ = max_components;
42 for (
size_t i = 0; i < initial_components; i++) {
44 LOGE(
"Failed to allocate initial buffer component %d", (
int)i);
56 for (
auto* buffer : buffer_components) {
59 buffer_components.clear();
70 bool read(T &result)
override {
76 size_t buffer_idx = read_pos / component_size_;
77 size_t local_pos = read_pos % component_size_;
80 bool success = buffer_components[buffer_idx]->read(result);
70 bool read(T &result)
override {
…}
96 bool peek(T &result)
override {
102 size_t buffer_idx = read_pos / component_size_;
103 size_t local_pos = read_pos % component_size_;
106 return buffer_components[buffer_idx]->peek(result);
96 bool peek(T &result)
override {
…}
127 size_t buffer_idx = write_pos / component_size_;
128 size_t local_pos = write_pos % component_size_;
131 bool success = buffer_components[buffer_idx]->write(data);
149 if (
isEmpty() || data ==
nullptr) {
156 while (remaining > 0) {
158 size_t buffer_idx = read_pos / component_size_;
159 size_t local_pos = read_pos % component_size_;
162 int can_read = min(remaining, (
int)(component_size_ - local_pos));
165 buffer_components[buffer_idx]->reset();
166 for (
size_t i = 0; i < local_pos; i++) {
168 buffer_components[buffer_idx]->read(dummy);
172 int actually_read = buffer_components[buffer_idx]->readArray(data + total_read, can_read);
175 total_read += actually_read;
176 read_pos += actually_read;
177 remaining -= actually_read;
180 if (actually_read < can_read) {
199 if (data ==
nullptr) {
203 int total_written = 0;
206 while (remaining > 0) {
215 size_t buffer_idx = write_pos / component_size_;
216 size_t local_pos = write_pos % component_size_;
219 int can_write = min(remaining, (
int)(component_size_ - local_pos));
222 buffer_components[buffer_idx]->reset();
223 for (
size_t i = 0; i < local_pos; i++) {
224 buffer_components[buffer_idx]->write(T());
228 int actually_written = buffer_components[buffer_idx]->writeArray(data + total_written, can_write);
231 total_written += actually_written;
232 write_pos += actually_written;
233 remaining -= actually_written;
236 if (actually_written < can_write) {
241 return total_written;
254 for (
auto* buffer : buffer_components) {
265 return write_pos - read_pos;
281 if (max_components_ == 0 || buffer_components.size() < max_components_) {
282 return existing_space + 1000000;
285 return existing_space;
297 if (max_components_ == 0) {
322 if (
isEmpty() || buffer_components.empty()) {
326 size_t buffer_idx = read_pos / component_size_;
327 return buffer_components[buffer_idx]->address();
349 size_t needed_components = (new_size + component_size_ - 1) / component_size_;
352 if (max_components_ != 0 && needed_components > max_components_) {
353 needed_components = max_components_;
357 while (buffer_components.size() > needed_components) {
358 delete buffer_components.back();
359 buffer_components.pop_back();
363 while (buffer_components.size() < needed_components) {
371 if (write_pos > total_capacity) {
372 write_pos = total_capacity;
374 if (read_pos > write_pos) {
375 read_pos = write_pos;
387 return buffer_components.size();
396 return component_size_;
401 size_t component_size_ = 0;
402 size_t max_components_ = 0;
404 size_t write_pos = 0;
415 if (max_components_ != 0 && buffer_components.size() >= max_components_) {
416 LOGW(
"Maximum number of buffer components reached: %d", (
int)max_components_);
421 BufferType<T>* new_buffer =
new BufferType<T>(component_size_);
422 if (new_buffer ==
nullptr) {
423 LOGE(
"Failed to allocate new buffer component");
428 new_buffer->resize(component_size_);
431 buffer_components.push_back(new_buffer);
432 LOGI(
"Added buffer component #%d", (
int)buffer_components.size());
443 return buffer_components.size() * component_size_;
452 if (buffer_components.empty()) {
456 size_t buffer_idx = write_pos / component_size_;
457 size_t local_pos = write_pos % component_size_;
459 return local_pos >= component_size_ || buffer_idx >= buffer_components.size();