EVOLUTION-MANAGER
Edit File: ringbuffer.cpp
/* * simple ring buffer * * Copyright (C) 2005-2008 Joern Seger * * 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. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <string.h> #include "ringbuffer.h" ringbuffer::ringbuffer(unsigned int buffersize) : size(buffersize), used(0), begin(0), end(0) { lock(); fifo = new unsigned char[buffersize]; unlock(); } ringbuffer::ringbuffer(unsigned char* data, unsigned int len) : size(len), used(len), begin(0), end(0) { // gonna make a copy for savety: lock(); fifo = new unsigned char[len]; memcpy(fifo, data, len); unlock(); } ringbuffer::~ringbuffer() { delete[] fifo; } unsigned int ringbuffer::addData(const unsigned char* data, unsigned int len) { lock(); if ((!len) || (!data)) { unlock(); return(0); } if (begin+len < size) { memcpy(fifo+begin,data,len); } else { // split int part1 = (size - begin); int part2 = len - part1; memcpy(fifo+begin,data,part1); memcpy(fifo,data+part1,part2); } begin += len; begin %= size; if (len > (size-used)) { // overwriting end += (len - size + used); end %= size; used = size; } else { used += len; } unlock(); /* if (drop) std::cerr<<"d"; */ return (len); } unsigned int ringbuffer::getData(unsigned char* data, unsigned int len) { lock(); if (used < len) len = used; if (size < (end + len)) { // split int part1 = size - end; int part2 = len - part1; memcpy(data, fifo+end, part1); memcpy(data+part1, fifo, part2); } else memcpy(data, fifo+end, len); end += len; end %= size; used -= len; /* for(unsigned int i=0; i<len; ++i) { data[i] = fifo[end++]; end %= size; } */ unlock(); return (len); } unsigned int ringbuffer::getAvailable() { unsigned int retValue; lock(); retValue = size-used; unlock(); return(retValue); } unsigned int ringbuffer::getUsed() { unsigned int retValue; lock(); retValue = used; unlock(); return(retValue); } void ringbuffer::clean() { lock(); begin = end = used = 0; unlock(); } unsigned int ringbuffer::luenkerback(unsigned char* data, unsigned int len) { lock(); if (len>used) len = used; int tmpEnd = begin-1; for (int i=len-1; i>=0; --i) { if (tmpEnd < 0) tmpEnd = size-1; data[i] = fifo[tmpEnd--]; } unlock(); return (len); } unsigned int ringbuffer::luenkerfront(unsigned char* data, unsigned int len) { lock(); if (used < len) len = used; unsigned int tmpEnd = end; for (unsigned int i=0; i<len; ++i) { data[i] = fifo[tmpEnd++]; tmpEnd %= size; } unlock(); return (len); } unsigned int ringbuffer::inc(unsigned int len) { lock(); if (used < len) len = used; end += len; end %= size; used -= len; unlock(); return (len); }