summaryrefslogtreecommitdiffstats
path: root/lib/libUPnP/Neptune/Source/Core/NptRingBuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libUPnP/Neptune/Source/Core/NptRingBuffer.cpp')
-rw-r--r--lib/libUPnP/Neptune/Source/Core/NptRingBuffer.cpp269
1 files changed, 269 insertions, 0 deletions
diff --git a/lib/libUPnP/Neptune/Source/Core/NptRingBuffer.cpp b/lib/libUPnP/Neptune/Source/Core/NptRingBuffer.cpp
new file mode 100644
index 0000000..798176d
--- /dev/null
+++ b/lib/libUPnP/Neptune/Source/Core/NptRingBuffer.cpp
@@ -0,0 +1,269 @@
+/*****************************************************************
+|
+| Neptune - Ring Buffer
+|
+| Copyright (c) 2002-2008, Axiomatic Systems, LLC.
+| All rights reserved.
+|
+| Redistribution and use in source and binary forms, with or without
+| modification, are permitted provided that the following conditions are met:
+| * Redistributions of source code must retain the above copyright
+| notice, this list of conditions and the following disclaimer.
+| * Redistributions in binary form must reproduce the above copyright
+| notice, this list of conditions and the following disclaimer in the
+| documentation and/or other materials provided with the distribution.
+| * Neither the name of Axiomatic Systems nor the
+| names of its contributors may be used to endorse or promote products
+| derived from this software without specific prior written permission.
+|
+| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY
+| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY
+| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+|
+ ****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include "NptRingBuffer.h"
+#include "NptResults.h"
+#include "NptUtils.h"
+#include "NptStreams.h"
+
+/*----------------------------------------------------------------------
+| NPT_RingBuffer::NPT_RingBuffer
++---------------------------------------------------------------------*/
+NPT_RingBuffer::NPT_RingBuffer(NPT_Size size) :
+ m_BufferIsLocal(true),
+ m_Closed(false)
+{
+ m_Data.start = new unsigned char[size];
+ m_Data.end = m_Data.start + size;
+
+ m_In = m_Out = m_Data.start;
+}
+
+/*----------------------------------------------------------------------
+| NPT_RingBuffer::NPT_RingBuffer
++---------------------------------------------------------------------*/
+NPT_RingBuffer::NPT_RingBuffer(void* buffer, NPT_Size size) :
+ m_BufferIsLocal(false),
+ m_Closed(false)
+{
+ m_Data.start = (unsigned char*)buffer;
+ m_Data.end = m_Data.start + size;
+
+ m_In = m_Out = m_Data.start;
+}
+
+/*----------------------------------------------------------------------
+| NPT_RingBuffer::~NPT_RingBuffer
++---------------------------------------------------------------------*/
+NPT_RingBuffer::~NPT_RingBuffer()
+{
+ if (m_BufferIsLocal) delete[] m_Data.start;
+}
+
+/*----------------------------------------------------------------------
+| NPT_RingBuffer::GetContiguousSpace
++---------------------------------------------------------------------*/
+NPT_Size
+NPT_RingBuffer::GetContiguousSpace() const
+{
+ return
+ (m_In < m_Out) ?
+ (NPT_Size)(m_Out - m_In - 1) :
+ ((m_Out == m_Data.start) ?
+ (NPT_Size)(m_Data.end - m_In - 1) :
+ (NPT_Size)(m_Data.end - m_In));
+}
+
+/*----------------------------------------------------------------------
+| NPT_RingBuffer::GetSpace
++---------------------------------------------------------------------*/
+NPT_Size
+NPT_RingBuffer::GetSpace() const
+{
+ return
+ (m_In < m_Out) ?
+ (NPT_Size)(m_Out - m_In - 1) :
+ (NPT_Size)(m_Data.end - m_In + m_Out - m_Data.start - 1);
+}
+
+/*----------------------------------------------------------------------+
+| NPT_RingBuffer::Write
++----------------------------------------------------------------------*/
+NPT_Result
+NPT_RingBuffer::Write(const void* buffer, NPT_Size byte_count)
+{
+ if (m_Closed) return NPT_ERROR_WRITE_FAILED;
+
+ if (byte_count == 0) return NPT_SUCCESS;
+ if (m_In < m_Out) {
+ if (buffer) NPT_CopyMemory(m_In, buffer, byte_count);
+ m_In += byte_count;
+ if (m_In == m_Data.end) m_In = m_Data.start;
+ } else {
+ unsigned int chunk = (unsigned int)(m_Data.end - m_In);
+ if (chunk >= byte_count) chunk = byte_count;
+
+ if (buffer) NPT_CopyMemory(m_In, buffer, chunk);
+ m_In += chunk;
+ if (m_In == m_Data.end) m_In = m_Data.start;
+ if (chunk != byte_count) {
+ if (buffer) {
+ NPT_CopyMemory(m_In,
+ ((const char*)buffer)+chunk,
+ byte_count-chunk);
+ }
+ m_In += byte_count-chunk;
+ if (m_In == m_Data.end) m_In = m_Data.start;
+ }
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------
+| NPT_RingBuffer::GetContiguousAvailable
++---------------------------------------------------------------------*/
+NPT_Size
+NPT_RingBuffer::GetContiguousAvailable() const
+{
+ return
+ (m_Out <= m_In) ?
+ (NPT_Size)(m_In-m_Out) :
+ (NPT_Size)(m_Data.end - m_Out);
+}
+
+/*----------------------------------------------------------------------
+| NPT_RingBuffer::GetAvailable
++---------------------------------------------------------------------*/
+NPT_Size
+NPT_RingBuffer::GetAvailable() const
+{
+ return
+ (m_Out <= m_In) ?
+ (NPT_Size)(m_In-m_Out) :
+ (NPT_Size)(m_Data.end - m_Out + m_In - m_Data.start);
+}
+
+/*----------------------------------------------------------------------+
+| NPT_RingBuffer::Read
++----------------------------------------------------------------------*/
+NPT_Result
+NPT_RingBuffer::Read(void* buffer, NPT_Size byte_count)
+{
+ if (m_Closed) return NPT_ERROR_READ_FAILED;
+
+ if (byte_count == 0) return NPT_SUCCESS;
+ if (m_In > m_Out) {
+ if (buffer) NPT_CopyMemory(buffer, m_Out, byte_count);
+ m_Out += byte_count;
+ if (m_Out == m_Data.end) m_Out = m_Data.start;
+ } else {
+ unsigned int chunk = (unsigned int)(m_Data.end - m_Out);
+ if (chunk >= byte_count) chunk = byte_count;
+
+ if (buffer) NPT_CopyMemory(buffer, m_Out, chunk);
+ m_Out += chunk;
+ if (m_Out == m_Data.end) m_Out = m_Data.start;
+ if (chunk != byte_count) {
+ if (buffer) {
+ NPT_CopyMemory(((char*)buffer)+chunk, m_Out, byte_count-chunk);
+ }
+ m_Out += byte_count-chunk;
+ if (m_Out == m_Data.end) m_Out = m_Data.start;
+ }
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------+
+| NPT_RingBuffer::ReadByte
++----------------------------------------------------------------------*/
+unsigned char
+NPT_RingBuffer::ReadByte()
+{
+ unsigned char result = *m_Out++;
+ if (m_Out == m_Data.end) m_Out = m_Data.start;
+ return result;
+}
+
+/*----------------------------------------------------------------------+
+| NPT_RingBuffer::PeekByte
++----------------------------------------------------------------------*/
+unsigned char
+NPT_RingBuffer::PeekByte(NPT_Position offset)
+{
+ unsigned char *where;
+
+ where = m_Out+offset;
+ if (where >= m_Data.end) where -= (m_Data.end - m_Data.start);
+
+ return *where;
+}
+
+/*----------------------------------------------------------------------+
+| NPT_RingBuffer::MoveIn
++----------------------------------------------------------------------*/
+NPT_Result
+NPT_RingBuffer::MoveIn(NPT_Position offset)
+{
+ int fold;
+
+ m_In += offset;
+ fold = (int)(m_In - m_Data.end);
+ if (fold >= 0) {
+ m_In = m_Data.start + fold;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------+
+| NPT_RingBuffer::MoveOut
++----------------------------------------------------------------------*/
+NPT_Result
+NPT_RingBuffer::MoveOut(NPT_Position offset)
+{
+ int fold;
+
+ m_Out += offset;
+ fold = (int)(m_Out - m_Data.end);
+ if (fold >= 0) {
+ m_Out = m_Data.start + fold;
+ }
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------+
+| NPT_RingBuffer::Flush
++----------------------------------------------------------------------*/
+NPT_Result
+NPT_RingBuffer::Flush()
+{
+ m_In = m_Out = m_Data.start;
+
+ return NPT_SUCCESS;
+}
+
+/*----------------------------------------------------------------------+
+| NPT_RingBuffer::Close
++----------------------------------------------------------------------*/
+NPT_Result
+NPT_RingBuffer::Close()
+{
+ m_Closed = true;
+ return NPT_SUCCESS;
+}
+