#include 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); } // }