Add circular buffer to coral library
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			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,
 | 
							unavailable,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Readable resource interface.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	struct reader {
 | 
						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 {
 | 
						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;
 | 
							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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user