You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tderadio/src/ringbuffer.cpp

174 lines
4.3 KiB

/***************************************************************************
ringbuffer.cpp - description
-------------------
begin : Sun March 21 2004
copyright : (C) 2004 by Martin Witte
email : witte@kawo1.rwth-aachen.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "include/ringbuffer.h"
#include <string.h>
RingBuffer::RingBuffer(size_t size)
{
m_Buffer = new char [size];
m_Size = size;
m_FillSize = 0;
m_Start = 0;
}
RingBuffer::~RingBuffer()
{
delete[] m_Buffer;
m_Buffer = NULL;
m_Size = 0;
}
bool RingBuffer::resize(size_t new_size)
{
if (new_size >= m_FillSize && new_size > 0) {
char *newBuffer = new char[new_size];
size_t newFill = 0;
while (m_FillSize > 0)
newFill += takeData(newBuffer + newFill, m_FillSize);
delete[] m_Buffer;
m_FillSize = newFill;
m_Start = 0;
m_Buffer = newBuffer;
m_Size = new_size;
return true;
}
return false;
}
size_t RingBuffer::addData (const char *src, size_t size)
{
size_t written = 0;
if (m_Start + m_FillSize < m_Size) {
size_t rest = m_Size - m_Start - m_FillSize;
if (rest > size)
rest = size;
memmove (m_Buffer + m_Start + m_FillSize, src, rest);
m_FillSize += rest;
written += rest;
size -= rest;
src += rest;
}
if (size > 0 && m_FillSize < m_Size) {
size_t rest = size;
if (rest > m_Size - m_FillSize)
rest = m_Size - m_FillSize;
memmove(m_Buffer + m_Start + m_FillSize - m_Size, src, rest);
m_FillSize += rest;
written += rest;
}
return written;
}
size_t RingBuffer::takeData(char *dst, size_t size)
{
size_t read = 0;
while (m_FillSize > 0 && size > 0) {
size_t n = size;
if (n > m_FillSize)
n = m_FillSize;
if (n > m_Size - m_Start)
n = m_Size - m_Start;
memmove (dst, m_Buffer + m_Start, n);
m_FillSize -= n;
m_Start += n;
read += n;
size -= n;
if (m_Start >= m_Size)
m_Start -= m_Size;
}
return read;
}
char *RingBuffer::getFreeSpace(size_t &size)
{
if (m_FillSize == m_Size) {
size = 0;
return NULL;
}
if (m_Start + m_FillSize >= m_Size) {
size = m_Size - m_FillSize;
return m_Buffer + m_Start + m_FillSize - m_Size;
} else {
size = m_Size - m_Start - m_FillSize;
return m_Buffer + m_Start + m_FillSize;
}
}
size_t RingBuffer::removeFreeSpace(size_t size)
{
if (m_FillSize == m_Size)
return 0;
if (m_Start + m_FillSize >= m_Size) {
if (size > m_Size - m_FillSize)
size = m_Size - m_FillSize;
m_FillSize += size;
return size;
} else {
if (m_Start + m_FillSize + size >= m_Size)
size = m_Size - m_Start - m_FillSize;
m_FillSize += size;
return size;
}
}
char *RingBuffer::getData(size_t &size)
{
if (m_Start + m_FillSize >= m_Size) {
size = m_Size - m_Start;
} else {
size = m_FillSize;
}
return m_Buffer + m_Start;
}
size_t RingBuffer::removeData(size_t size)
{
size_t n = 0;
if (size > m_FillSize)
size = m_FillSize;
if (m_Start + size >= m_Size) {
n = m_Size - m_Start;
m_Start = 0;
} else {
m_Start += size;
n = size;
}
m_FillSize -= n;
return n;
}
void RingBuffer::clear()
{
m_Start = 0;
m_FillSize = 0;
}