comparison deps/Platinum/ThirdParty/Neptune/Source/Core/NptRingBuffer.cpp @ 0:3425707ddbf6

Initial import (hopefully this mercurial stuff works...)
author fraserofthenight
date Mon, 06 Jul 2009 08:06:28 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3425707ddbf6
1 /*****************************************************************
2 |
3 | Neptune - Ring Buffer
4 |
5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC.
6 | All rights reserved.
7 |
8 | Redistribution and use in source and binary forms, with or without
9 | modification, are permitted provided that the following conditions are met:
10 | * Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 | * Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 | * Neither the name of Axiomatic Systems nor the
16 | names of its contributors may be used to endorse or promote products
17 | derived from this software without specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY
20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY
23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 |
30 ****************************************************************/
31
32 /*----------------------------------------------------------------------
33 | includes
34 +---------------------------------------------------------------------*/
35 #include "NptRingBuffer.h"
36 #include "NptResults.h"
37 #include "NptUtils.h"
38 #include "NptStreams.h"
39
40 /*----------------------------------------------------------------------
41 | NPT_RingBuffer::NPT_RingBuffer
42 +---------------------------------------------------------------------*/
43 NPT_RingBuffer::NPT_RingBuffer(NPT_Size size) :
44 m_Size(size),
45 m_BufferIsLocal(true),
46 m_Closed(false)
47 {
48 m_Data.start = new unsigned char[size];
49 m_Data.end = m_Data.start + size;
50
51 m_In = m_Out = m_Data.start;
52 }
53
54 /*----------------------------------------------------------------------
55 | NPT_RingBuffer::NPT_RingBuffer
56 +---------------------------------------------------------------------*/
57 NPT_RingBuffer::NPT_RingBuffer(void* buffer, NPT_Size size) :
58 m_Size(size),
59 m_BufferIsLocal(false)
60 {
61 m_Data.start = (unsigned char*)buffer;
62 m_Data.end = m_Data.start + size;
63
64 m_In = m_Out = m_Data.start;
65 }
66
67 /*----------------------------------------------------------------------
68 | NPT_RingBuffer::~NPT_RingBuffer
69 +---------------------------------------------------------------------*/
70 NPT_RingBuffer::~NPT_RingBuffer()
71 {
72 if (m_BufferIsLocal) delete[] m_Data.start;
73 }
74
75 /*----------------------------------------------------------------------
76 | NPT_RingBuffer::GetContiguousSpace
77 +---------------------------------------------------------------------*/
78 NPT_Size
79 NPT_RingBuffer::GetContiguousSpace() const
80 {
81 return
82 (m_In < m_Out) ?
83 (NPT_Size)(m_Out - m_In - 1) :
84 ((m_Out == m_Data.start) ?
85 (NPT_Size)(m_Data.end - m_In - 1) :
86 (NPT_Size)(m_Data.end - m_In));
87 }
88
89 /*----------------------------------------------------------------------
90 | NPT_RingBuffer::GetSpace
91 +---------------------------------------------------------------------*/
92 NPT_Size
93 NPT_RingBuffer::GetSpace() const
94 {
95 return
96 (m_In < m_Out) ?
97 (NPT_Size)(m_Out - m_In - 1) :
98 (NPT_Size)(m_Data.end - m_In + m_Out - m_Data.start - 1);
99 }
100
101 /*----------------------------------------------------------------------+
102 | NPT_RingBuffer::Write
103 +----------------------------------------------------------------------*/
104 NPT_Result
105 NPT_RingBuffer::Write(const void* buffer, NPT_Size byte_count)
106 {
107 if (m_Closed) return NPT_ERROR_WRITE_FAILED;
108
109 if (byte_count == 0) return NPT_SUCCESS;
110 if (m_In < m_Out) {
111 if (buffer) NPT_CopyMemory(m_In, buffer, byte_count);
112 m_In += byte_count;
113 if (m_In == m_Data.end) m_In = m_Data.start;
114 } else {
115 unsigned int chunk = (unsigned int)(m_Data.end - m_In);
116 if (chunk >= byte_count) chunk = byte_count;
117
118 if (buffer) NPT_CopyMemory(m_In, buffer, chunk);
119 m_In += chunk;
120 if (m_In == m_Data.end) m_In = m_Data.start;
121 if (chunk != byte_count) {
122 if (buffer) {
123 NPT_CopyMemory(m_In,
124 ((const char*)buffer)+chunk,
125 byte_count-chunk);
126 }
127 m_In += byte_count-chunk;
128 if (m_In == m_Data.end) m_In = m_Data.start;
129 }
130 }
131
132 return NPT_SUCCESS;
133 }
134
135 /*----------------------------------------------------------------------
136 | NPT_RingBuffer::GetContiguousAvailable
137 +---------------------------------------------------------------------*/
138 NPT_Size
139 NPT_RingBuffer::GetContiguousAvailable() const
140 {
141 return
142 (m_Out <= m_In) ?
143 (NPT_Size)(m_In-m_Out) :
144 (NPT_Size)(m_Data.end - m_Out);
145 }
146
147 /*----------------------------------------------------------------------
148 | NPT_RingBuffer::GetAvailable
149 +---------------------------------------------------------------------*/
150 NPT_Size
151 NPT_RingBuffer::GetAvailable() const
152 {
153 return
154 (m_Out <= m_In) ?
155 (NPT_Size)(m_In-m_Out) :
156 (NPT_Size)(m_Data.end - m_Out + m_In - m_Data.start);
157 }
158
159 /*----------------------------------------------------------------------+
160 | NPT_RingBuffer::Read
161 +----------------------------------------------------------------------*/
162 NPT_Result
163 NPT_RingBuffer::Read(void* buffer, NPT_Size byte_count)
164 {
165 if (m_Closed) return NPT_ERROR_READ_FAILED;
166
167 if (byte_count == 0) return NPT_SUCCESS;
168 if (m_In > m_Out) {
169 if (buffer) NPT_CopyMemory(buffer, m_Out, byte_count);
170 m_Out += byte_count;
171 if (m_Out == m_Data.end) m_Out = m_Data.start;
172 } else {
173 unsigned int chunk = (unsigned int)(m_Data.end - m_Out);
174 if (chunk >= byte_count) chunk = byte_count;
175
176 if (buffer) NPT_CopyMemory(buffer, m_Out, chunk);
177 m_Out += chunk;
178 if (m_Out == m_Data.end) m_Out = m_Data.start;
179 if (chunk != byte_count) {
180 if (buffer) {
181 NPT_CopyMemory(((char*)buffer)+chunk, m_Out, byte_count-chunk);
182 }
183 m_Out += byte_count-chunk;
184 if (m_Out == m_Data.end) m_Out = m_Data.start;
185 }
186 }
187
188 return NPT_SUCCESS;
189 }
190
191 /*----------------------------------------------------------------------+
192 | NPT_RingBuffer::ReadByte
193 +----------------------------------------------------------------------*/
194 unsigned char
195 NPT_RingBuffer::ReadByte()
196 {
197 unsigned char result = *m_Out++;
198 if (m_Out == m_Data.end) m_Out = m_Data.start;
199 return result;
200 }
201
202 /*----------------------------------------------------------------------+
203 | NPT_RingBuffer::PeekByte
204 +----------------------------------------------------------------------*/
205 unsigned char
206 NPT_RingBuffer::PeekByte(NPT_Position offset)
207 {
208 unsigned char *where;
209
210 where = m_Out+offset;
211 if (where >= m_Data.end) where -= (m_Data.end - m_Data.start);
212
213 return *where;
214 }
215
216 /*----------------------------------------------------------------------+
217 | NPT_RingBuffer::MoveIn
218 +----------------------------------------------------------------------*/
219 NPT_Result
220 NPT_RingBuffer::MoveIn(NPT_Position offset)
221 {
222 int fold;
223
224 m_In += offset;
225 fold = (int)(m_In - m_Data.end);
226 if (fold >= 0) {
227 m_In = m_Data.start + fold;
228 }
229
230 return NPT_SUCCESS;
231 }
232
233 /*----------------------------------------------------------------------+
234 | NPT_RingBuffer::MoveOut
235 +----------------------------------------------------------------------*/
236 NPT_Result
237 NPT_RingBuffer::MoveOut(NPT_Position offset)
238 {
239 int fold;
240
241 m_Out += offset;
242 fold = (int)(m_Out - m_Data.end);
243 if (fold >= 0) {
244 m_Out = m_Data.start + fold;
245 }
246
247 return NPT_SUCCESS;
248 }
249
250 /*----------------------------------------------------------------------+
251 | NPT_RingBuffer::Flush
252 +----------------------------------------------------------------------*/
253 NPT_Result
254 NPT_RingBuffer::Flush()
255 {
256 m_In = m_Out = m_Data.start;
257
258 return NPT_SUCCESS;
259 }
260
261 /*----------------------------------------------------------------------+
262 | NPT_RingBuffer::Close
263 +----------------------------------------------------------------------*/
264 NPT_Result
265 NPT_RingBuffer::Close()
266 {
267 m_Closed = true;
268 return NPT_SUCCESS;
269 }
270