/* Simple byte-based ring buffer. Licensed under public domain (C) BearOso. */
#pragma once
#include <memory>
#include <algorithm>
#include <cstring>
class ring_buffer
{
protected:
int size;
int buffer_size;
int start;
std::unique_ptr<unsigned char[]> buffer;
public:
ring_buffer(int buf_size)
{
this->buffer_size = buf_size;
this->buffer.reset(new unsigned char[this->buffer_size]);
this->clear();
}
bool push(unsigned char *src, int bytes)
{
if (this->space_empty() < bytes)
return false;
int end = (this->start + this->size) % this->buffer_size;
int first_write_size = std::min(bytes, this->buffer_size - end);
std::copy_n(&src[0], first_write_size, &this->buffer[end]);
if (bytes > first_write_size)
std::copy(&src[first_write_size], &src[bytes], &this->buffer[0]);
this->size += bytes;
return true;
}
int space_empty()
{
return this->buffer_size - this->size;
}
int space_filled()
{
return this->size;
}
void clear()
{
this->start = this->size = 0;
std::fill_n(&this->buffer[0], this->buffer_size, 0);
}
void resize(int new_size)
{
this->buffer_size = new_size;
this->buffer.reset(new unsigned char[this->buffer_size]);
this->clear();
}
};