template Buffer::Buffer(size_t capacity) : m_capacity(capacity) , m_len(0) , m_wi(0) , m_ri(0) , m_bid(0) , m_data{nullptr, nullptr} { resize(capacity); } template Buffer::~Buffer() { resize(0); } template void Buffer::resize(size_t size) { const size_t N = sizeof(m_data)/sizeof(m_data[0]); for (int i=0; i < N; i++) { if (m_data[i] != nullptr) { delete m_data[i]; m_data[i] = nullptr; } } m_capacity = size; clear(); if (size == 0) { return; } for (int i=0; i < N; i++) { m_data[i] = new T[size]; } } template void Buffer::fill(T value) { T *pData = data_w(); for (m_wi=0; m_wi < capacity(); m_wi++) { pData[m_wi] = value; m_len++; } } template size_t Buffer::len() { return m_len; } template size_t Buffer::capacity() { return m_capacity; } template void Buffer::clear() { m_len = 0; m_wi = 0; m_ri = 0; } template T* Buffer::data_w() { return &bufferActive()[m_wi]; } template T* Buffer::data_r() { return &bufferActive()[m_ri]; } template size_t Buffer::write(const T *pData, size_t len) { len = std::min(m_capacity - m_len, len); size_t numWritten = 0; while(len) { size_t num_remain = m_capacity - m_wi; size_t actual_len = std::min(num_remain, len); memcpy(data_w(), pData, actual_len*sizeof(T)); produce(actual_len); len -= actual_len; pData += actual_len; numWritten += actual_len; } return numWritten; } template size_t Buffer::read(T* pData, size_t len) { len = std::min(m_len, len); size_t numRead = 0; while(len) { size_t num_remain = m_capacity - m_ri; size_t actual_len = std::min(num_remain, len); memcpy(pData, data_r(), actual_len*sizeof(T)); len -= actual_len; pData += actual_len; consume(actual_len); } return numRead; } template typename Buffer::Result Buffer::readAt(size_t offset, T &x) { if (m_len == 0) { RETURN_OR_EXCEPT(Result::Err_InvalidSize); } size_t n = (m_ri+offset) % m_capacity; x = data_r()[n]; if (offset) { consume(1); } return Result::Ok; } template typename Buffer::Result Buffer::consume(size_t len) { if (len > m_len) { RETURN_OR_EXCEPT(Result::Err_InvalidSize); } m_len -= len; m_ri += len; if (m_ri >= m_capacity) { m_ri -= m_capacity; } return Result::Ok; } template typename Buffer::Result Buffer::produce(size_t len) { if (len > (m_capacity - m_len)) { RETURN_OR_EXCEPT(Result::Err_InvalidSize); } m_len += len; m_wi += len; if (m_wi >= m_capacity) { m_wi -= m_capacity; } return Result::Ok; } template void Buffer::print(const char *prefix) { make_contigious(); T *data = data_r(); printf("%s", prefix); for (size_t i=0; i < m_len; i++) { printf("%f ", data[i]); } printf("\n"); }