📄 circularbuffer.cpp
字号:
//---------------------------------------------------------------------------
// Pixelworks Inc. Company Confidential Strictly Private
//
// $Archive: $
// $Revision: 1.1.1.1 $
// $Author: KevinM $
// $Date: 2003/09/29 18:19:04 $
//
// --------------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------------
// Copyright 1997-2003 (c) Pixelworks Inc.
//
// Pixelworks owns the sole copyright to this software. Under international
// copyright laws you (1) may not make a copy of this software except for
// the purposes of maintaining a single archive copy, (2) may not derive
// works herefrom, (3) may not distribute this work to others. These rights
// are provided for information clarification, other restrictions of rights
// may apply as well.
//
// This is an unpublished work.
// --------------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>>>>> WARRANTEE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// --------------------------------------------------------------------------
// Pixelworks Inc. MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THE USE OF
// THIS SOFTWARE, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
// PURPOSE.
// --------------------------------------------------------------------------
//
// CircularBuffer.cpp: implementation of the CCircularBuffer class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CircularBuffer.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCircularBuffer::CCircularBuffer()
{
InitMembers(0);
}
CCircularBuffer::CCircularBuffer(int nBufSize)
{
InitMembers(nBufSize);
}
void CCircularBuffer::InitMembers(int nBufSize)
{
if (nBufSize > 0)
{
m_nBufferSize = nBufSize;
m_pBuffer = new BYTE[m_nBufferSize];
}
else
{
m_nBufferSize = 0;
m_pBuffer = NULL;
}
m_nWriteIndex = 0;
m_nReadIndex = 0;
m_pReadEv = new CEvent;
m_pWriteEv = new CEvent;
m_bShutdown = FALSE;
m_pBuffer = NULL;
}
CCircularBuffer::~CCircularBuffer()
{
delete[m_nBufferSize] m_pBuffer;
delete m_pReadEv;
delete m_pWriteEv;
}
bool CCircularBuffer::SetSize(int nBufSize)
{
if (m_pBuffer != NULL)
{
delete[m_nBufferSize] m_pBuffer;
m_pBuffer = NULL;
m_nBufferSize = 0;
}
m_nReadIndex = 0;
m_nWriteIndex = 0;
m_nBufferSize = nBufSize;
m_pBuffer = new BYTE[m_nBufferSize];
return TRUE;
}
// Add new bytes to the circular buffer. Returns TRUE if bytes were added
// sucessfully.
bool CCircularBuffer::AddBytes(BYTE* pBytes, int nCount, int nTimeout)
{
VERIFY(m_pBuffer != NULL);
// Number of byte we can write
int nRemain = GetAvailSpace();
while (nRemain < nCount && !m_bShutdown)
{
// Not enough room to add the requested bytes. Wait
// until more room becomes available...
CSingleLock WaitForData(m_pWriteEv);
if (!WaitForData.Lock(nTimeout))
{
return 0;
}
m_pWriteEv->ResetEvent();
nRemain = GetAvailSpace();
}
// Ensure that we have thread safe
// access to the buffer and it's indexes.
CSingleLock SLock(&m_Mutex);
SLock.Lock(INFINITE);
int nStart = m_nWriteIndex;
// First, move all newly arrived data into the circular buffer...
int nBytes = nCount;
int i=0;
while (nBytes--)
{
m_pBuffer[m_nWriteIndex++] = pBytes[i++];
if (m_nWriteIndex == m_nBufferSize)
{
m_nWriteIndex = 0;
}
}
// Pulse the reader event to let any other thread know
// that new data has arrived.
//TRACE("SET TID: 0x%08X, EV: 0x%08X\n", GetCurrentThreadId(), m_pReadEv);
m_pReadEv->SetEvent();
return TRUE;
}
// Read nCount bytes from the circular buffer, waiting if neccesary for the
// proper number of byte to become available.
int CCircularBuffer::ReadBytes(BYTE* pBytes, int nCount, int nTimeout, char cMarker)
{
VERIFY(m_pBuffer != NULL);
// Number of byte we can write
int nAvail = GetAvailBytes();
while (nAvail < nCount && !m_bShutdown)
{
// Not enough bytes available. Wait
// until more bytes becomes available...
CSingleLock WaitForData(m_pReadEv);
//TRACE("WAT TID: 0x%08X, EV: 0x%08X\n", GetCurrentThreadId(), m_pReadEv);
if (!WaitForData.Lock(nTimeout))
{
return FALSE;
}
m_pReadEv->ResetEvent();
nAvail = GetAvailBytes();
}
// Ensure that we have thread safe
// access to the buffer and it's indexes.
CSingleLock SLock(&m_Mutex);
SLock.Lock(INFINITE);
int nStart = m_nReadIndex;
int nBytes = nCount;
int i=0;
while (nBytes--)
{
BYTE cTmp = pBytes[i++] = m_pBuffer[m_nReadIndex++];
if (m_nReadIndex == m_nBufferSize)
{
m_nReadIndex = 0;
}
if ((cMarker != 0x00) && (cTmp == cMarker))
// We hit our marker, break out of here.
break;
}
// Pulse the write event to let any other thread know
// that new data has arrived.
m_pWriteEv->SetEvent();
return (i);
}
// Returns the number of byte available for reading.
int CCircularBuffer::GetAvailBytes()
{
VERIFY(m_pBuffer != NULL);
// Ensure that we have thread safe
// access to the buffer and it's indexes.
CSingleLock SLock(&m_Mutex);
SLock.Lock(INFINITE);
// Number of byte we can read
int nRemain = (m_nWriteIndex - m_nReadIndex);
// Handle wrap condition
if (nRemain < 0)
nRemain += m_nBufferSize;
return nRemain;
}
int CCircularBuffer::GetAvailSpace()
{
VERIFY(m_pBuffer != NULL);
// Ensure that we have thread safe
// access to the buffer and it's indexes.
CSingleLock SLock(&m_Mutex);
SLock.Lock(INFINITE);
// Number of byte we can write
int nRemain = (m_nReadIndex - m_nWriteIndex);
// Handle wrap condition
if (nRemain <= 0)
nRemain += m_nBufferSize;
return nRemain;
}
int CCircularBuffer::WaitForBytes(int nCount, int nTimeout)
{
VERIFY(m_pBuffer != NULL);
// Number of valid bytes in the cirular buffer
int nAvail = GetAvailBytes();
while (nAvail < nCount && !m_bShutdown)
{
// Not enough bytes available. Wait
// until more bytes becomes available...
CSingleLock WaitForData(m_pReadEv);
if (!WaitForData.Lock(nTimeout))
{
return nAvail;
}
m_pReadEv->ResetEvent();
nAvail = GetAvailBytes();
}
return GetAvailBytes();
}
void CCircularBuffer::Flush()
{
// Throw away any data...
VERIFY(m_pBuffer != NULL);
// Ensure that we have thread safe
// access to the buffer and it's indexes.
CSingleLock SLock(&m_Mutex);
SLock.Lock(INFINITE);
m_nReadIndex = 0;
m_nWriteIndex = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -