subrepo: subdir: "components/f4ll" merged: "3e904a2" upstream: origin: "ssh://git@codeberg.org/abody/f4ll.git" branch: "master" commit: "3e904a2" git-subrepo: version: "0.4.9" origin: "???" commit: "???"
150 lines
No EOL
2.8 KiB
C++
150 lines
No EOL
2.8 KiB
C++
#include <f4ll/ringbuffer.h>
|
|
|
|
namespace f4ll {
|
|
|
|
ringbuffer_ext::ringbuffer_ext(uint8_t *bptr, size_type bsize)
|
|
: m_buffer(bptr),
|
|
m_bsize(bsize)
|
|
{
|
|
}
|
|
|
|
iringbuffer::size_type ringbuffer_ext::put(uint8_t const *data, size_type len)
|
|
{
|
|
size_type chunk1 = 0;
|
|
size_type chunk2 = 0;
|
|
|
|
if (!data || !len) {
|
|
return 0;
|
|
}
|
|
|
|
size_type max_len = unused();
|
|
len = len < max_len ? len : max_len;
|
|
|
|
chunk1 = m_bsize - m_head_shadow;
|
|
if (chunk1 >= len) {
|
|
chunk1 = len;
|
|
} else {
|
|
chunk2 = len - chunk1;
|
|
}
|
|
|
|
std::memcpy(m_buffer + m_head_shadow, data, chunk1);
|
|
m_head_shadow += chunk1;
|
|
if (m_head_shadow == m_bsize) {
|
|
m_head_shadow = 0;
|
|
}
|
|
|
|
if (chunk2) {
|
|
std::memcpy(m_buffer, data + chunk1, chunk2);
|
|
m_head_shadow += chunk2;
|
|
if (m_head_shadow == m_bsize) {
|
|
m_head_shadow = 0;
|
|
}
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
void ringbuffer_ext::commit()
|
|
{
|
|
m_head = m_head_shadow;
|
|
}
|
|
|
|
bool ringbuffer_ext::get_chunk(uint8_t const *&data, size_type &len) const
|
|
{
|
|
size_type head = m_head;
|
|
size_type tail = m_tail;
|
|
size_type chunk_size = head >= tail ? head - tail : m_bsize - tail;
|
|
|
|
if (!chunk_size) {
|
|
len = 0;
|
|
return tail != head;
|
|
}
|
|
|
|
data = m_buffer + tail;
|
|
len = chunk_size;
|
|
|
|
tail += chunk_size;
|
|
if (tail == m_bsize) {
|
|
tail = 0;
|
|
}
|
|
|
|
return tail != head;
|
|
}
|
|
|
|
void ringbuffer_ext::consumed(size_type len)
|
|
{
|
|
if (!len) {
|
|
return;
|
|
}
|
|
m_tail += len;
|
|
if (m_tail == m_bsize) {
|
|
m_tail = 0;
|
|
}
|
|
}
|
|
|
|
iringbuffer::size_type ringbuffer_ext::max_chunk_len() const
|
|
{
|
|
if (m_tail <= m_head_shadow) {
|
|
return m_bsize - m_head_shadow - (m_tail ? 0 : 1);
|
|
} else {
|
|
return m_tail - m_head_shadow - 1;
|
|
}
|
|
}
|
|
|
|
uint8_t *ringbuffer_ext::get_free_chunk(size_type &len)
|
|
{
|
|
len = max_chunk_len();
|
|
|
|
return m_buffer + m_head_shadow;
|
|
}
|
|
|
|
bool ringbuffer_ext::produced(size_type len)
|
|
{
|
|
size_type max_len = max_chunk_len();
|
|
if (len > max_len) {
|
|
return false;
|
|
}
|
|
m_head_shadow += len;
|
|
if (m_head_shadow == m_bsize) {
|
|
m_head_shadow = 0;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
iringbuffer::size_type ringbuffer_ext::uncommited() const
|
|
{
|
|
return marker_diff(m_head_shadow, m_head);
|
|
}
|
|
|
|
iringbuffer::size_type ringbuffer_ext::commited() const
|
|
{
|
|
return marker_diff(m_head, m_tail);
|
|
}
|
|
|
|
void ringbuffer_ext::discard()
|
|
{
|
|
m_head_shadow = m_head;
|
|
}
|
|
|
|
iringbuffer::size_type ringbuffer_ext::size() const
|
|
{
|
|
return m_bsize;
|
|
}
|
|
|
|
iringbuffer::size_type ringbuffer_ext::used() const
|
|
{
|
|
return marker_diff(m_head_shadow, m_tail);
|
|
}
|
|
|
|
iringbuffer::size_type ringbuffer_ext::unused() const
|
|
{
|
|
return m_bsize - used() - 1;
|
|
}
|
|
|
|
iringbuffer::size_type ringbuffer_ext::marker_diff(size_type m1, size_type m2) const
|
|
{
|
|
return (m1 >= m2) ? (m1 - m2) : (m_bsize - m2 + m1);
|
|
}
|
|
|
|
//
|
|
} |