Replace coral::fixed_buffer with coral::ring_buffer
This commit is contained in:
parent
c53fd30cc2
commit
5755cc6517
@ -4,34 +4,76 @@ import coral;
|
||||
|
||||
export namespace coral {
|
||||
/**
|
||||
* Multiplexing byte-based ring buffer of `capacity` size that may be used for memory-backed I/O operations and
|
||||
* lightweight data construction.
|
||||
* Multiplexing byte-based ring buffer that may be used for memory-backed I/O operations and fast data (re)-
|
||||
* construction.
|
||||
*/
|
||||
template<usize capacity> struct fixed_buffer : public writer, public reader {
|
||||
fixed_buffer() = default;
|
||||
struct ring_buffer : public writer, public reader {
|
||||
/**
|
||||
* Potential results from attempting to allocate a ring buffer dynamically.
|
||||
*
|
||||
* [allocate_result::ok] means nothing went wrong and the allocation was successful.
|
||||
*
|
||||
* [allocate_result::out_of_memory] indicates that there is not enough memory available in the provided
|
||||
* allocator to create a buffer of the requested size.
|
||||
*/
|
||||
enum class [[nodiscard]] allocate_result {
|
||||
ok,
|
||||
out_of_memory,
|
||||
};
|
||||
|
||||
ring_buffer() = default;
|
||||
|
||||
ring_buffer(ring_buffer const &) = delete;
|
||||
|
||||
~ring_buffer() override {
|
||||
if (this->data_allocator != nullptr) this->data_allocator->deallocate(this->data.pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to allocate memory for the ring buffer `capacity` number of bytes large with `data_allocator` as the
|
||||
* allocation strategy.
|
||||
*
|
||||
* See [allocate_result] for more information on error handling.
|
||||
*
|
||||
* *Note*: calling allocate will wipe out the contents of the current buffer.
|
||||
*/
|
||||
allocate_result allocate(allocator & data_allocator, usize capacity) {
|
||||
if (this->data_allocator != nullptr) this->data_allocator->deallocate(this->data.pointer);
|
||||
|
||||
this->clear();
|
||||
|
||||
u8 * const data {this->data_allocator->reallocate(nullptr, capacity)};
|
||||
|
||||
if (data == nullptr) {
|
||||
this->data_allocator = nullptr;
|
||||
this->data = {};
|
||||
|
||||
return allocate_result::out_of_memory;
|
||||
}
|
||||
|
||||
this->data_allocator = &data_allocator;
|
||||
this->data = {data, capacity};
|
||||
|
||||
return allocate_result::ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a mutable [slice] ranging from the head to the last-filled element.
|
||||
*
|
||||
* *Note*: The lifetime and validity of the returned slice is only guaranteed for as long as the source
|
||||
* [fixed_buffer] is not mutated or out-of-scope.
|
||||
* [ring_buffer] is not mutated or out-of-scope.
|
||||
*/
|
||||
slice<u8 const> as_slice() const {
|
||||
return {this->data, this->data_filled};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base pointer of the buffer data.
|
||||
*/
|
||||
u8 const * begin() const {
|
||||
return this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tail pointer of the buffer data.
|
||||
* Clears all written elements from the buffer.
|
||||
*/
|
||||
u8 const * end() const {
|
||||
return this->data + this->cursor;
|
||||
void clear() {
|
||||
this->data_filled = 0;
|
||||
this->read_index = 0;
|
||||
this->write_index = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,14 +87,14 @@ export namespace coral {
|
||||
* Returns `true` if the buffer is completely empty of data, otherwise `false`.
|
||||
*/
|
||||
bool is_empty() const {
|
||||
return this->data_filled == capacity;
|
||||
return this->data_filled == this->data.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if the buffer has been completely filled with data, otherwise `false`.
|
||||
*/
|
||||
bool is_full() const {
|
||||
return this->data_filled == capacity;
|
||||
return this->data_filled == this->data.length;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,7 +106,7 @@ export namespace coral {
|
||||
|
||||
this->data_filled += 1;
|
||||
this->data[this->write_index] = data;
|
||||
this->write_index = (this->write_index + 1) % capacity;
|
||||
this->write_index = (this->write_index + 1) % this->data.length;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -73,13 +115,13 @@ export namespace coral {
|
||||
* Reads whatever data is in the buffer into `data`, returning the number of bytes read from the buffer.
|
||||
*/
|
||||
expected<usize, io_error> read(slice<u8> const & data) override {
|
||||
slice const readable_data {this->data, min(this->data_filled, data.length)};
|
||||
slice const readable_data {this->data.sliced(0, min(this->data_filled, data.length))};
|
||||
|
||||
this->data_filled -= readable_data.length;
|
||||
|
||||
for (usize index = 0; index < readable_data.length; index += 1) {
|
||||
data[index] = this->data[this->read_index];
|
||||
this->read_index = (this->read_index + 1) % capacity;
|
||||
this->read_index = (this->read_index + 1) % this->data.length;
|
||||
}
|
||||
|
||||
return readable_data.length;
|
||||
@ -89,23 +131,20 @@ export namespace coral {
|
||||
* Returns the remaining unfilled buffer space in bytes.
|
||||
*/
|
||||
usize remaining() const {
|
||||
return capacity - this->data_filled;
|
||||
return this->data.length - this->data_filled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to write `data` to the buffer, returning the number of bytes written or [io_error::unavailable] if
|
||||
* it has been completely filled and no more bytes can be written.
|
||||
* Write `data` to the buffer, returning the number of bytes written to the buffer.
|
||||
*/
|
||||
expected<usize, io_error> write(slice<u8 const> const & data) override {
|
||||
if (this->is_full()) return io_error::unavailable;
|
||||
|
||||
slice const writable_data {data.sliced(0, min(data.length, this->remaining()))};
|
||||
|
||||
this->data_filled += writable_data.length;
|
||||
|
||||
for (usize index = 0; index < writable_data.length; index += 1) {
|
||||
this->data[this->write_index] = data[index];
|
||||
this->write_index = (this->write_index + 1) % capacity;
|
||||
this->write_index = (this->write_index + 1) % this->data.length;
|
||||
}
|
||||
|
||||
return writable_data.length;
|
||||
@ -118,7 +157,9 @@ export namespace coral {
|
||||
|
||||
usize write_index {0};
|
||||
|
||||
u8 data[capacity]{0};
|
||||
allocator * data_allocator {nullptr};
|
||||
|
||||
slice<u8> data {};
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user