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::free() { return m_capacity-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 typename Buffer::Result Buffer::write(const T *pData, size_t len) { if (len > free()) { printf("len : %u\n", (unsigned)len); printf("free : %u\n", (unsigned)free()); printf("capa : %u\n", (unsigned)capacity()); RETURN_OR_EXCEPT(Result::Err_InvalidSize); } 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)); len -= actual_len; pData += actual_len; produce(actual_len); } return Result::Ok; } template typename Buffer::Result Buffer::read(T* pData, size_t len) { if (len > m_len) { RETURN_OR_EXCEPT(Result::Err_InvalidSize); } 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 Result::Ok; } template T Buffer::readAt(size_t offset) { if (m_len < (1+offset)) { EXC_EXCEPT(Result::Err_InvalidSize); } size_t i = (m_ri + offset) % m_capacity; T result = bufferActive()[i]; consume(1+offset); return result; } template typename Buffer::Result Buffer::consume(size_t len) { if (len > m_len) { RETURN_OR_EXCEPT(Result::Err_InvalidSize); } m_len -= len; m_ri = (m_ri + len) % m_capacity; return Result::Ok; } template typename Buffer::Result Buffer::produce(size_t len) { if (len > free()) { RETURN_OR_EXCEPT(Result::Err_InvalidSize); } m_len += len; m_wi = (m_wi + len) % 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"); }