96 lines
2.0 KiB
C++
96 lines
2.0 KiB
C++
#include "kutil/assert.h"
|
|
#include "kutil/bip_buffer.h"
|
|
|
|
namespace kutil {
|
|
|
|
bip_buffer::bip_buffer() :
|
|
m_start_a(0),
|
|
m_start_b(0),
|
|
m_size_a(0),
|
|
m_size_b(0),
|
|
m_buffer_size(0),
|
|
m_buffer(nullptr)
|
|
{}
|
|
|
|
bip_buffer::bip_buffer(uint8_t *buffer, size_t size) :
|
|
m_start_a(0),
|
|
m_start_b(0),
|
|
m_size_a(0),
|
|
m_size_b(0),
|
|
m_buffer_size(size),
|
|
m_buffer(buffer)
|
|
{}
|
|
|
|
size_t bip_buffer::reserve(size_t size, void **area)
|
|
{
|
|
if (m_size_r) {
|
|
*area = nullptr;
|
|
return 0;
|
|
}
|
|
|
|
size_t remaining = 0;
|
|
if (m_size_b) {
|
|
// If B exists, we're appending there. Get space between
|
|
// the end of B and start of A.
|
|
remaining = m_start_a - m_start_b - m_size_b;
|
|
m_start_r = m_start_b + m_size_b;
|
|
} else {
|
|
// B doesn't exist, check the space both before and after A.
|
|
// If the end of A has enough room for this write, put it there.
|
|
remaining = m_buffer_size - m_start_a - m_size_a;
|
|
m_start_r = m_start_a + m_size_a;
|
|
|
|
// Otherwise use the bigger of the areas in front of and after A
|
|
if (remaining < size && m_start_a > remaining) {
|
|
remaining = m_start_a;
|
|
m_start_r = 0;
|
|
}
|
|
}
|
|
|
|
if (!remaining) {
|
|
*area = nullptr;
|
|
return 0;
|
|
}
|
|
|
|
m_size_r = (remaining < size) ? remaining : size;
|
|
*area = &m_buffer[m_start_r];
|
|
return m_size_r;
|
|
}
|
|
|
|
void bip_buffer::commit(size_t size)
|
|
{
|
|
kassert(size <= m_size_r, "Tried to commit more than reserved");
|
|
|
|
if (m_start_r == m_start_a + m_size_a) {
|
|
// We were adding to A
|
|
m_size_a += size;
|
|
} else {
|
|
// We were adding to B
|
|
kassert(m_start_r == m_start_b + m_size_b, "Bad m_start_r!");
|
|
m_size_b += size;
|
|
}
|
|
|
|
m_start_r = m_size_r = 0;
|
|
}
|
|
|
|
size_t bip_buffer::get_block(void **area) const
|
|
{
|
|
*area = m_size_a ? &m_buffer[m_start_a] : nullptr;
|
|
return m_size_a;
|
|
}
|
|
|
|
void bip_buffer::consume(size_t size)
|
|
{
|
|
kassert(size <= m_size_a, "Consumed more bytes than exist in A");
|
|
if (size >= m_size_a) {
|
|
m_size_a = m_size_b;
|
|
m_start_a = m_start_b;
|
|
m_size_b = m_start_b = 0;
|
|
} else {
|
|
m_size_a -= size;
|
|
m_start_a += size;
|
|
}
|
|
}
|
|
|
|
} // namespace kutil
|