⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 circularbuffer.cpp

📁 PW芯片方案Flash ROM烧写程序
💻 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 + -