Mixxx

/home/maxime/Projets/Mixxx/1.10/mixxx/src/circularbuffer.h

Go to the documentation of this file.
00001 #ifndef CIRCULARBUFFER_H
00002 #define CIRCULARBUFFER_H
00003 
00004 #include <stdlib.h>
00005 
00006 // CircularBuffer is a basic implementation of a constant-length circular
00007 // buffer.
00008 //
00009 // WARNING: CircularBuffer IS NOT THREAD SAFE! It is "sort of" thread safe on
00010 // platforms with atomic writes and aligned memory locations, but it is most
00011 // definitely not safe on x86 without memory barriers that could re-order reads
00012 // and writes.
00013 template <typename T>
00014 class CircularBuffer {
00015   public:
00016     CircularBuffer(unsigned int iLength)
00017             : m_iLength(iLength),
00018               m_pBuffer(new T[m_iLength]),
00019               m_iWritePos(0),
00020               m_iReadPos(0) {
00021         // No need to clear the buffer because we consider it to be empty right
00022         // now.
00023     }
00024 
00025     virtual ~CircularBuffer() {
00026         delete [] m_pBuffer;
00027         m_pBuffer = NULL;
00028     }
00029 
00030     // Returns true if the buffer is full
00031     inline bool isFull() const {
00032         return (m_iWritePos + 1) % m_iLength == m_iReadPos;
00033     }
00034 
00035     // Returns true if the buffer is empty.
00036     inline bool isEmpty() const {
00037         return m_iReadPos == m_iWritePos;
00038     }
00039 
00040     inline void clear() {
00041         m_iReadPos = 0;
00042         m_iWritePos = 0;
00043     }
00044 
00045     // Returns the total capacity of the CircularBuffer in units of T
00046     inline unsigned int length() const {
00047         return m_iLength;
00048     }
00049 
00050     // Write numItems into the CircularBuffer. Returns the total number of
00051     // items written, which could be less than numItems if the buffer becomes
00052     // full.
00053     unsigned int write(const T* pBuffer, const unsigned int numItems) {
00054         if (m_pBuffer == NULL)
00055             return 0;
00056 
00057         unsigned int itemsWritten = 0;
00058         while (!isFull() && itemsWritten < numItems) {
00059             m_pBuffer[m_iWritePos++] = pBuffer[itemsWritten++];
00060             m_iWritePos %= m_iLength;
00061         }
00062         return itemsWritten;
00063     }
00064 
00065     // Read itemsToRead into pBuffer. Returns the total number of items read,
00066     // which may be less than itemsToRead if the buffer becomes empty.
00067     unsigned int read(T* pBuffer, const unsigned int itemsToRead) {
00068         if (m_pBuffer == NULL)
00069             return 0;
00070 
00071         unsigned int itemsRead = 0;
00072         while (!isEmpty() && itemsRead < itemsToRead) {
00073             pBuffer[itemsRead++] = m_pBuffer[m_iReadPos++];
00074             m_iReadPos %= m_iLength;
00075         }
00076         return itemsRead;
00077     }
00078 
00079     unsigned int skip(const unsigned int itemsToRead) {
00080         if (m_pBuffer == NULL)
00081             return 0;
00082         unsigned int itemsRead = 0;
00083         while (!isEmpty() && itemsRead < itemsToRead) {
00084             m_iReadPos = (m_iReadPos + 1) % m_iLength;
00085             itemsRead++;
00086         }
00087         return itemsRead;
00088     }
00089 
00090   private:
00091     const unsigned int m_iLength;
00092     T* m_pBuffer;
00093     unsigned int m_iWritePos;
00094     unsigned int m_iReadPos;
00095 };
00096 
00097 #endif /* CIRCULARBUFFER_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines