summaryrefslogtreecommitdiffstats
path: root/src/ringbuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ringbuffer.cpp')
-rw-r--r--src/ringbuffer.cpp173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/ringbuffer.cpp b/src/ringbuffer.cpp
new file mode 100644
index 0000000..7609768
--- /dev/null
+++ b/src/ringbuffer.cpp
@@ -0,0 +1,173 @@
+/***************************************************************************
+ ringbuffer.cpp - description
+ -------------------
+ begin : Sun March 21 2004
+ copyright : (C) 2004 by Martin Witte
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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;
+}