1 /*****************************************************************
3 | Neptune - Ring Buffer
5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC.
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.
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.
30 ****************************************************************/
32 /*----------------------------------------------------------------------
34 +---------------------------------------------------------------------*/
35 #include "NptRingBuffer.h"
36 #include "NptResults.h"
38 #include "NptStreams.h"
40 /*----------------------------------------------------------------------
41 | NPT_RingBuffer::NPT_RingBuffer
42 +---------------------------------------------------------------------*/
43 NPT_RingBuffer::NPT_RingBuffer(NPT_Size size
) :
44 m_BufferIsLocal(true),
47 m_Data
.start
= new unsigned char[size
];
48 m_Data
.end
= m_Data
.start
+ size
;
50 m_In
= m_Out
= m_Data
.start
;
53 /*----------------------------------------------------------------------
54 | NPT_RingBuffer::NPT_RingBuffer
55 +---------------------------------------------------------------------*/
56 NPT_RingBuffer::NPT_RingBuffer(void* buffer
, NPT_Size size
) :
57 m_BufferIsLocal(false),
60 m_Data
.start
= (unsigned char*)buffer
;
61 m_Data
.end
= m_Data
.start
+ size
;
63 m_In
= m_Out
= m_Data
.start
;
66 /*----------------------------------------------------------------------
67 | NPT_RingBuffer::~NPT_RingBuffer
68 +---------------------------------------------------------------------*/
69 NPT_RingBuffer::~NPT_RingBuffer()
71 if (m_BufferIsLocal
) delete[] m_Data
.start
;
74 /*----------------------------------------------------------------------
75 | NPT_RingBuffer::GetContiguousSpace
76 +---------------------------------------------------------------------*/
78 NPT_RingBuffer::GetContiguousSpace() const
82 (NPT_Size
)(m_Out
- m_In
- 1) :
83 ((m_Out
== m_Data
.start
) ?
84 (NPT_Size
)(m_Data
.end
- m_In
- 1) :
85 (NPT_Size
)(m_Data
.end
- m_In
));
88 /*----------------------------------------------------------------------
89 | NPT_RingBuffer::GetSpace
90 +---------------------------------------------------------------------*/
92 NPT_RingBuffer::GetSpace() const
96 (NPT_Size
)(m_Out
- m_In
- 1) :
97 (NPT_Size
)(m_Data
.end
- m_In
+ m_Out
- m_Data
.start
- 1);
100 /*----------------------------------------------------------------------+
101 | NPT_RingBuffer::Write
102 +----------------------------------------------------------------------*/
104 NPT_RingBuffer::Write(const void* buffer
, NPT_Size byte_count
)
106 if (m_Closed
) return NPT_ERROR_WRITE_FAILED
;
108 if (byte_count
== 0) return NPT_SUCCESS
;
110 if (buffer
) NPT_CopyMemory(m_In
, buffer
, byte_count
);
112 if (m_In
== m_Data
.end
) m_In
= m_Data
.start
;
114 unsigned int chunk
= (unsigned int)(m_Data
.end
- m_In
);
115 if (chunk
>= byte_count
) chunk
= byte_count
;
117 if (buffer
) NPT_CopyMemory(m_In
, buffer
, chunk
);
119 if (m_In
== m_Data
.end
) m_In
= m_Data
.start
;
120 if (chunk
!= byte_count
) {
123 ((const char*)buffer
)+chunk
,
126 m_In
+= byte_count
-chunk
;
127 if (m_In
== m_Data
.end
) m_In
= m_Data
.start
;
134 /*----------------------------------------------------------------------
135 | NPT_RingBuffer::GetContiguousAvailable
136 +---------------------------------------------------------------------*/
138 NPT_RingBuffer::GetContiguousAvailable() const
142 (NPT_Size
)(m_In
-m_Out
) :
143 (NPT_Size
)(m_Data
.end
- m_Out
);
146 /*----------------------------------------------------------------------
147 | NPT_RingBuffer::GetAvailable
148 +---------------------------------------------------------------------*/
150 NPT_RingBuffer::GetAvailable() const
154 (NPT_Size
)(m_In
-m_Out
) :
155 (NPT_Size
)(m_Data
.end
- m_Out
+ m_In
- m_Data
.start
);
158 /*----------------------------------------------------------------------+
159 | NPT_RingBuffer::Read
160 +----------------------------------------------------------------------*/
162 NPT_RingBuffer::Read(void* buffer
, NPT_Size byte_count
)
164 if (m_Closed
) return NPT_ERROR_READ_FAILED
;
166 if (byte_count
== 0) return NPT_SUCCESS
;
168 if (buffer
) NPT_CopyMemory(buffer
, m_Out
, byte_count
);
170 if (m_Out
== m_Data
.end
) m_Out
= m_Data
.start
;
172 unsigned int chunk
= (unsigned int)(m_Data
.end
- m_Out
);
173 if (chunk
>= byte_count
) chunk
= byte_count
;
175 if (buffer
) NPT_CopyMemory(buffer
, m_Out
, chunk
);
177 if (m_Out
== m_Data
.end
) m_Out
= m_Data
.start
;
178 if (chunk
!= byte_count
) {
180 NPT_CopyMemory(((char*)buffer
)+chunk
, m_Out
, byte_count
-chunk
);
182 m_Out
+= byte_count
-chunk
;
183 if (m_Out
== m_Data
.end
) m_Out
= m_Data
.start
;
190 /*----------------------------------------------------------------------+
191 | NPT_RingBuffer::ReadByte
192 +----------------------------------------------------------------------*/
194 NPT_RingBuffer::ReadByte()
196 unsigned char result
= *m_Out
++;
197 if (m_Out
== m_Data
.end
) m_Out
= m_Data
.start
;
201 /*----------------------------------------------------------------------+
202 | NPT_RingBuffer::PeekByte
203 +----------------------------------------------------------------------*/
205 NPT_RingBuffer::PeekByte(NPT_Position offset
)
207 unsigned char *where
;
209 where
= m_Out
+offset
;
210 if (where
>= m_Data
.end
) where
-= (m_Data
.end
- m_Data
.start
);
215 /*----------------------------------------------------------------------+
216 | NPT_RingBuffer::MoveIn
217 +----------------------------------------------------------------------*/
219 NPT_RingBuffer::MoveIn(NPT_Position offset
)
224 fold
= (int)(m_In
- m_Data
.end
);
226 m_In
= m_Data
.start
+ fold
;
232 /*----------------------------------------------------------------------+
233 | NPT_RingBuffer::MoveOut
234 +----------------------------------------------------------------------*/
236 NPT_RingBuffer::MoveOut(NPT_Position offset
)
241 fold
= (int)(m_Out
- m_Data
.end
);
243 m_Out
= m_Data
.start
+ fold
;
249 /*----------------------------------------------------------------------+
250 | NPT_RingBuffer::Flush
251 +----------------------------------------------------------------------*/
253 NPT_RingBuffer::Flush()
255 m_In
= m_Out
= m_Data
.start
;
260 /*----------------------------------------------------------------------+
261 | NPT_RingBuffer::Close
262 +----------------------------------------------------------------------*/
264 NPT_RingBuffer::Close()