summaryrefslogtreecommitdiffstats
path: root/src/fileringbuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/fileringbuffer.cpp')
-rw-r--r--src/fileringbuffer.cpp252
1 files changed, 252 insertions, 0 deletions
diff --git a/src/fileringbuffer.cpp b/src/fileringbuffer.cpp
new file mode 100644
index 0000000..5cca0c7
--- /dev/null
+++ b/src/fileringbuffer.cpp
@@ -0,0 +1,252 @@
+/***************************************************************************
+ 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/fileringbuffer.h"
+
+#include <tqstring.h>
+#include <unistd.h>
+#include <tdelocale.h>
+
+FileRingBuffer::FileRingBuffer(const TQString &filename, TQ_UINT64 max_size)
+{
+ m_BaseFileName = filename;
+ m_FileIdx = 0;
+ m_FileName = m_BaseFileName + "_" + TQString::number(++m_FileIdx);
+ m_File = fopen(m_FileName.ascii(), "w+");
+ m_MaxSize = max_size;
+ m_RealSize = 0;
+ m_FillSize = 0;
+ m_Start = 0;
+ m_error = m_File == NULL;
+ m_errorString = m_File ? TQString() : i18n("cannot open buffer file %1").arg(filename);
+}
+
+
+FileRingBuffer::~FileRingBuffer()
+{
+ if (m_File) {
+ fclose (m_File);
+ unlink (m_FileName.ascii());
+ }
+ m_File = NULL;
+ m_FileName = TQString();
+ m_MaxSize = 0;
+ m_RealSize = 0;
+ m_FillSize = 0;
+ m_Start = 0;
+ m_error = false;
+ m_errorString = TQString();
+}
+
+
+bool FileRingBuffer::resize(const TQString &filename, TQ_UINT64 new_max_size)
+{
+ if (filename != m_BaseFileName) {
+ clear();
+ if (m_File) {
+ fclose (m_File);
+ unlink (m_FileName.ascii());
+ }
+ m_BaseFileName = filename;
+ m_FileName = m_BaseFileName + "_" + TQString::number(++m_FileIdx);
+ m_File = fopen(m_FileName.ascii(), "w+");
+ m_error = m_File == NULL;
+ m_errorString = m_File ? TQString() : i18n("cannot open buffer file %1").arg(filename);
+ }
+
+ if (new_max_size >= m_RealSize) {
+ m_MaxSize = new_max_size;
+ }
+ else if (m_Start + m_FillSize < m_RealSize && new_max_size > m_Start + m_FillSize) {
+ ftruncate(fileno(m_File), new_max_size);
+ m_MaxSize = new_max_size;
+ }
+ else if (new_max_size >= m_FillSize) {
+ const size_t buffer_size = 65536;
+ char buffer[buffer_size];
+
+ TQString tmp_file_name = m_BaseFileName + "_" + TQString::number(++m_FileIdx);
+ FILE *tmp_file = fopen (tmp_file_name.ascii(), "w+");
+ TQ_UINT64 newFill = 0;
+ if (tmp_file) {
+ while (!m_error && m_FillSize > 0) {
+ int tmp_size = takeData(buffer, buffer_size);
+ if (tmp_size > 0) {
+ if (fwrite (buffer, tmp_size, 1, tmp_file) > 0) {
+ newFill += tmp_size;
+ } else {
+ m_error = true;
+ m_errorString += i18n("FileRingbuffer::resize: Writing to tmpfile %1 failed. ").arg(tmp_file_name);
+ }
+ }
+ }
+ } else {
+ m_error = true;
+ m_errorString += i18n("FileRingbuffer::resize: Opening tmpfile %1 failed. ").arg(tmp_file_name);
+ }
+
+ if (!m_error) {
+ fclose (m_File);
+ m_FileName = tmp_file_name;
+ m_File = tmp_file;
+ m_FillSize = newFill;
+ m_Start = 0;
+ m_MaxSize = new_max_size;
+ m_RealSize = newFill;
+ }
+ return true;
+ }
+ return false;
+}
+
+
+size_t FileRingBuffer::addData (const char *src, size_t size)
+{
+ size_t written = 0;
+ if (m_Start + m_FillSize <= m_RealSize) {
+ TQ_UINT64 rest = m_MaxSize - (m_Start + m_FillSize);
+ if (rest > size)
+ rest = size;
+ fseek(m_File, m_Start + m_FillSize, SEEK_SET);
+ if (rest > 0 && fwrite(src, rest, 1, m_File) <= 0) {
+ m_error = true;
+ m_errorString += i18n("FileRingBuffer::addData: failed writing data to file %1.").arg(m_FileName);
+ } else {
+ m_FillSize += rest;
+ if (m_Start + m_FillSize > m_RealSize)
+ m_RealSize = m_Start + m_FillSize;
+ written += rest;
+ size -= rest;
+ src += rest;
+ }
+ }
+ if (!m_error && size > 0 && m_FillSize < m_RealSize) {
+ size_t rest = size;
+ if (rest > m_RealSize - m_FillSize)
+ rest = m_RealSize - m_FillSize;
+
+ fseek(m_File, m_Start + m_FillSize - m_RealSize, SEEK_SET);
+ if (fwrite(src, rest, 1, m_File) <= 0) {
+ m_error = true;
+ m_errorString += i18n("FileRingBuffer::addData: failed writing data to file %1.").arg(m_FileName);
+ } else {
+ m_FillSize += rest;
+ written += rest;
+ //fflush(m_File); // debug only
+ }
+ }
+ return written;
+}
+
+
+size_t FileRingBuffer::takeData(char *dst, size_t size)
+{
+ size_t read = 0;
+ while (!m_error && m_FillSize > 0 && size > 0) {
+ size_t n = size;
+ if (n > m_FillSize)
+ n = m_FillSize;
+ if (n > m_RealSize - m_Start)
+ n = m_RealSize - m_Start;
+ fseek(m_File, m_Start, SEEK_SET);
+ if (fread(dst+read, n, 1, m_File) <= 0) {
+ m_error = true;
+ m_errorString += i18n("FileRingBuffer::takeData: failed reading data to file %1.").arg(m_FileName);
+ } else {
+ m_FillSize -= n;
+ m_Start += n;
+ read += n;
+ size -= n;
+ if (m_Start >= m_RealSize)
+ m_Start -= m_RealSize;
+ }
+
+ }
+ return read;
+}
+
+
+TQ_UINT64 FileRingBuffer::getFreeSpace(TQ_UINT64 &size)
+{
+ if (m_FillSize == m_RealSize) {
+ size = 0;
+ return 0;
+ }
+
+ if (m_Start + m_FillSize >= m_RealSize) {
+ size = m_RealSize - m_FillSize;
+ return m_Start + m_FillSize - m_RealSize;
+ } else {
+ size = m_MaxSize - m_Start - m_FillSize;
+ return m_Start + m_FillSize;
+ }
+}
+
+
+TQ_UINT64 FileRingBuffer::removeFreeSpace(TQ_UINT64 size)
+{
+ if (m_FillSize == m_RealSize)
+ return 0;
+
+ if (m_Start + m_FillSize >= m_RealSize) {
+ if (size > m_RealSize - m_FillSize)
+ size = m_RealSize - m_FillSize;
+ m_FillSize += size;
+ return size;
+ } else {
+ if (m_Start + m_FillSize + size >= m_MaxSize)
+ size = m_MaxSize - m_Start - m_FillSize;
+ m_FillSize += size;
+ return size;
+ }
+}
+
+
+TQ_UINT64 FileRingBuffer::getData(TQ_UINT64 &size)
+{
+ if (m_Start + m_FillSize >= m_RealSize) {
+ size = m_RealSize - m_Start;
+ } else {
+ size = m_FillSize;
+ }
+ return m_Start;
+}
+
+
+TQ_UINT64 FileRingBuffer::removeData(TQ_UINT64 size)
+{
+ if (size > m_FillSize)
+ size = m_FillSize;
+ if (m_Start + size >= m_RealSize) {
+ m_Start = m_Start + size - m_RealSize;
+ } else {
+ m_Start += size;
+ }
+ m_FillSize -= size;
+ return size;
+}
+
+
+void FileRingBuffer::clear()
+{
+ if (!m_error) {
+ ftruncate(fileno(m_File), 0);
+ m_Start = 0;
+ m_FillSize = 0;
+ m_RealSize = 0;
+ }
+}