git-svn-id: http://moon:8086/svn/software/trunk/libsrc/cpp@1044 b431acfa-c32f-4a4a-93f1-934dc6c82436
192 lines
3.0 KiB
C++
192 lines
3.0 KiB
C++
|
|
template<typename T>
|
|
Buffer<T>::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<typename T>
|
|
Buffer<T>::~Buffer()
|
|
{
|
|
resize(0);
|
|
}
|
|
|
|
template<typename T>
|
|
void Buffer<T>::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<typename T>
|
|
void Buffer<T>::fill(T value)
|
|
{
|
|
T *pData = data_w();
|
|
|
|
for (m_wi=0; m_wi < capacity(); m_wi++)
|
|
{
|
|
pData[m_wi] = value;
|
|
m_len++;
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
size_t Buffer<T>::len()
|
|
{
|
|
return m_len;
|
|
}
|
|
|
|
template<typename T>
|
|
size_t Buffer<T>::free()
|
|
{
|
|
return m_capacity-m_len;
|
|
}
|
|
|
|
template<typename T>
|
|
size_t Buffer<T>::capacity()
|
|
{
|
|
return m_capacity;
|
|
}
|
|
|
|
template<typename T>
|
|
void Buffer<T>::clear()
|
|
{
|
|
m_len = 0;
|
|
m_wi = 0;
|
|
m_ri = 0;
|
|
}
|
|
|
|
template<typename T>
|
|
T* Buffer<T>::data_w()
|
|
{
|
|
return &bufferActive()[m_wi];
|
|
}
|
|
|
|
template<typename T>
|
|
T* Buffer<T>::data_r()
|
|
{
|
|
return &bufferActive()[m_ri];
|
|
}
|
|
|
|
template<typename T>
|
|
typename Buffer<T>::Result Buffer<T>::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 T>
|
|
typename Buffer<T>::Result Buffer<T>::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<typename T>
|
|
T Buffer<T>::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 T>
|
|
typename Buffer<T>::Result Buffer<T>::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 T>
|
|
typename Buffer<T>::Result Buffer<T>::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<typename T>
|
|
void Buffer<T>::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");
|
|
}
|