Add circular buffer to coral library
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
37b2586eaa
commit
cea0a4e0ed
115
source/coral.cpp
115
source/coral.cpp
|
@ -452,12 +452,34 @@ export namespace coral {
|
|||
unavailable,
|
||||
};
|
||||
|
||||
/**
|
||||
* Readable resource interface.
|
||||
*/
|
||||
struct reader {
|
||||
virtual expected<usize, io_error> read(slice<u8> const & buffer) = 0;
|
||||
virtual ~reader() {}
|
||||
|
||||
/**
|
||||
* Attempts to fill `data` with whatever data the reader has to offer, returning the number
|
||||
* of bytes actually read.
|
||||
*
|
||||
* Should the read operation fail for any reason, a [io_error] is returned instead.
|
||||
*/
|
||||
virtual expected<usize, io_error> read(slice<u8> const & data) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Writable resource interface.
|
||||
*/
|
||||
struct writer {
|
||||
virtual expected<usize, io_error> write(slice<u8 const> const & buffer) = 0;
|
||||
virtual ~writer() {}
|
||||
|
||||
/**
|
||||
* Attempts to write `data` out to the writer, returning the number of bytes actually
|
||||
* written.
|
||||
*
|
||||
* Should the write operation fail for any reason, a [io_error] is returned instead.
|
||||
*/
|
||||
virtual expected<usize, io_error> write(slice<u8 const> const & data) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -617,4 +639,93 @@ export namespace coral {
|
|||
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplexing byte buffer of `capacity` size that may be used for memory-backed I/O
|
||||
* operations and lightweight data construction.
|
||||
*/
|
||||
template<usize capacity> struct ring_buffer : public writer, public reader {
|
||||
ring_buffer(coral::u8 fill_value) : data{fill_value} {}
|
||||
|
||||
/**
|
||||
* Returns the base pointer of the buffer data.
|
||||
*/
|
||||
u8 * begin() {
|
||||
return this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base pointer of the buffer data.
|
||||
*/
|
||||
u8 const * begin() const {
|
||||
return this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tail pointer of the buffer data.
|
||||
*/
|
||||
u8 * end() {
|
||||
return this->data + this->cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tail pointer of the buffer data.
|
||||
*/
|
||||
u8 const * end() const {
|
||||
return this->data + this->cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if the buffer has been completely filled with data.
|
||||
*/
|
||||
bool is_full() const {
|
||||
return this->filled == capacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->filled, data.length)};
|
||||
|
||||
this->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;
|
||||
}
|
||||
|
||||
return readable_data.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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->filled))};
|
||||
|
||||
this->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;
|
||||
}
|
||||
|
||||
return writable_data.length;
|
||||
}
|
||||
|
||||
private:
|
||||
usize filled = 0;
|
||||
|
||||
usize read_index = 0;
|
||||
|
||||
usize write_index = 0;
|
||||
|
||||
u8 data[capacity];
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue