xref: /haiku/src/add-ons/media/plugins/ape_reader/MAClib/CircleBuffer.cpp (revision 68ea01249e1e2088933cb12f9c28d4e5c5d1c9ef)
1 #include "All.h"
2 #include "CircleBuffer.h"
3 
4 CCircleBuffer::CCircleBuffer()
5 {
6     m_pBuffer = NULL;
7     m_nTotal = 0;
8     m_nHead = 0;
9     m_nTail = 0;
10     m_nEndCap = 0;
11     m_nMaxDirectWriteBytes = 0;
12 }
13 
14 CCircleBuffer::~CCircleBuffer()
15 {
16     SAFE_ARRAY_DELETE(m_pBuffer)
17 }
18 
19 void CCircleBuffer::CreateBuffer(int nBytes, int nMaxDirectWriteBytes)
20 {
21     SAFE_ARRAY_DELETE(m_pBuffer)
22 
23     m_nMaxDirectWriteBytes = nMaxDirectWriteBytes;
24     m_nTotal = nBytes + 1 + nMaxDirectWriteBytes;
25     m_pBuffer = new unsigned char [m_nTotal];
26     m_nHead = 0;
27     m_nTail = 0;
28     m_nEndCap = m_nTotal;
29 }
30 
31 int CCircleBuffer::MaxAdd()
32 {
33     int nMaxAdd = (m_nTail >= m_nHead) ? (m_nTotal - 1 - m_nMaxDirectWriteBytes) - (m_nTail - m_nHead) : m_nHead - m_nTail - 1;
34     return nMaxAdd;
35 }
36 
37 int CCircleBuffer::MaxGet()
38 {
39     return (m_nTail >= m_nHead) ? m_nTail - m_nHead : (m_nEndCap - m_nHead) + m_nTail;
40 }
41 
42 int CCircleBuffer::Get(unsigned char * pBuffer, int nBytes)
43 {
44     int nTotalGetBytes = 0;
45 
46     if (pBuffer != NULL && nBytes > 0)
47     {
48         int nHeadBytes = min(m_nEndCap - m_nHead, nBytes);
49         int nFrontBytes = nBytes - nHeadBytes;
50 
51         memcpy(&pBuffer[0], &m_pBuffer[m_nHead], nHeadBytes);
52         nTotalGetBytes = nHeadBytes;
53 
54         if (nFrontBytes > 0)
55         {
56             memcpy(&pBuffer[nHeadBytes], &m_pBuffer[0], nFrontBytes);
57             nTotalGetBytes += nFrontBytes;
58         }
59 
60         RemoveHead(nBytes);
61     }
62 
63     return nTotalGetBytes;
64 }
65 
66 void CCircleBuffer::Empty()
67 {
68     m_nHead = 0;
69     m_nTail = 0;
70     m_nEndCap = m_nTotal;
71 }
72 
73 int CCircleBuffer::RemoveHead(int nBytes)
74 {
75     nBytes = min(MaxGet(), nBytes);
76     m_nHead += nBytes;
77     if (m_nHead >= m_nEndCap)
78         m_nHead -= m_nEndCap;
79     return nBytes;
80 }
81 
82 int CCircleBuffer::RemoveTail(int nBytes)
83 {
84     nBytes = min(MaxGet(), nBytes);
85     m_nTail -= nBytes;
86     if (m_nTail < 0)
87         m_nTail += m_nEndCap;
88     return nBytes;
89 }
90