2 * Copyright (C) 2010-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "RingBuffer.h"
22 #include "threads/SingleLock.h"
29 CRingBuffer::CRingBuffer()
39 CRingBuffer::~CRingBuffer()
44 /* Create a ring buffer with the specified 'size' */
45 bool CRingBuffer::Create(unsigned int size)
47 CSingleLock lock(m_critSection);
48 m_buffer = (char*)malloc(size);
57 /* Free the ring buffer and set all values to NULL or 0 */
58 void CRingBuffer::Destroy()
60 CSingleLock lock(m_critSection);
72 /* Clear the ring buffer */
73 void CRingBuffer::Clear()
75 CSingleLock lock(m_critSection);
81 /* Read in data from the ring buffer to the supplied buffer 'buf'. The amount
82 * read in is specified by 'size'.
84 bool CRingBuffer::ReadData(char *buf, unsigned int size)
86 CSingleLock lock(m_critSection);
87 if (size > m_fillCount)
91 if (size + m_readPtr > m_size)
93 unsigned int chunk = m_size - m_readPtr;
94 memcpy(buf, m_buffer + m_readPtr, chunk);
95 memcpy(buf + chunk, m_buffer, size - chunk);
96 m_readPtr = size - chunk;
100 memcpy(buf, m_buffer + m_readPtr, size);
103 if (m_readPtr == m_size)
109 /* Read in data from the ring buffer to another ring buffer object specified by
112 bool CRingBuffer::ReadData(CRingBuffer &rBuf, unsigned int size)
114 CSingleLock lock(m_critSection);
115 if (rBuf.getBuffer() == NULL)
118 bool bOk = size <= rBuf.getMaxWriteSize() && size <= getMaxReadSize();
121 unsigned int chunksize = std::min(size, m_size - m_readPtr);
122 bOk = rBuf.WriteData(&getBuffer()[m_readPtr], chunksize);
123 if (bOk && chunksize < size)
124 bOk = rBuf.WriteData(&getBuffer()[0], size - chunksize);
132 /* Write data to ring buffer from buffer specified in 'buf'. Amount read in is
133 * specified by 'size'.
135 bool CRingBuffer::WriteData(const char *buf, unsigned int size)
137 CSingleLock lock(m_critSection);
138 if (size > m_size - m_fillCount)
142 if (size + m_writePtr > m_size)
144 unsigned int chunk = m_size - m_writePtr;
145 memcpy(m_buffer + m_writePtr, buf, chunk);
146 memcpy(m_buffer, buf + chunk, size - chunk);
147 m_writePtr = size - chunk;
151 memcpy(m_buffer + m_writePtr, buf, size);
154 if (m_writePtr == m_size)
160 /* Write data to ring buffer from another ring buffer object specified by
163 bool CRingBuffer::WriteData(CRingBuffer &rBuf, unsigned int size)
165 CSingleLock lock(m_critSection);
166 if (m_buffer == NULL)
169 bool bOk = size <= rBuf.getMaxReadSize() && size <= getMaxWriteSize();
172 unsigned int readpos = rBuf.getReadPtr();
173 unsigned int chunksize = std::min(size, rBuf.getSize() - readpos);
174 bOk = WriteData(&rBuf.getBuffer()[readpos], chunksize);
175 if (bOk && chunksize < size)
176 bOk = WriteData(&rBuf.getBuffer()[0], size - chunksize);
182 /* Skip bytes in buffer to be read */
183 bool CRingBuffer::SkipBytes(int skipSize)
185 CSingleLock lock(m_critSection);
188 return false; // skipping backwards is not supported
191 unsigned int size = skipSize;
192 if (size > m_fillCount)
196 if (size + m_readPtr > m_size)
198 unsigned int chunk = m_size - m_readPtr;
199 m_readPtr = size - chunk;
205 if (m_readPtr == m_size)
211 /* Append all content from ring buffer 'rBuf' to this ring buffer */
212 bool CRingBuffer::Append(CRingBuffer &rBuf)
214 return WriteData(rBuf, rBuf.getMaxReadSize());
217 /* Copy all content from ring buffer 'rBuf' to this ring buffer overwriting any existing data */
218 bool CRingBuffer::Copy(CRingBuffer &rBuf)
224 /* Our various 'get' methods */
225 char *CRingBuffer::getBuffer()
230 unsigned int CRingBuffer::getSize()
232 CSingleLock lock(m_critSection);
236 unsigned int CRingBuffer::getReadPtr()
241 unsigned int CRingBuffer::getWritePtr()
243 CSingleLock lock(m_critSection);
247 unsigned int CRingBuffer::getMaxReadSize()
249 CSingleLock lock(m_critSection);
253 unsigned int CRingBuffer::getMaxWriteSize()
255 CSingleLock lock(m_critSection);
256 return m_size - m_fillCount;