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

📄 circularbuf.h

📁 MTK平台COM口通讯的源代码。很底层的。可以学习一下。
💻 H
字号:
/*****************************************************************************
*  Copyright Statement:
*  --------------------
*  This software is protected by Copyright and the information contained
*  herein is confidential. The software may not be copied and the information
*  contained herein may not be used or disclosed except with the written
*  permission of MediaTek Inc. (C) 2005
*
*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/

/*******************************************************************************
* Filename:
* ---------
*  CircularBuf.h
*
* Project:
* --------
*   Catcher
*
* Description:
* ------------
*   Template definition of circular buffer.
*
* Author:
* -------
*  Angus Chen (mtk00306)
*
*==============================================================================
*           HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
* $Revision:   1.0  $
* $Modtime:   May 29 2003 14:48:32  $
* $Log:   //mtkvs01/vmdata/PhoneSuiteApp/archives/comm/CircularBuf.h-arc  $
 * 
 *    Rev 1.0   Feb 27 2004 18:28:10   admin
 * Initial revision.
 * 
 *    Rev 1.0   Feb 27 2004 16:42:06   admin
 * Initial revision.
 * 
 *    Rev 1.0   Aug 14 2003 21:27:04   admin
 * Initial revision.
 * 
 *    Rev 1.0   Nov 19 2002 13:51:40   MTK00303
 * Initial revision.
*
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*==============================================================================
*******************************************************************************/
#ifndef ANGUS_CIRCULARBUFFER_DEF_H
#define ANGUS_CIRCULARBUFFER_DEF_H

#include "Lock.h"

#ifndef AFX_INLINE
#define AFX_INLINE inline
#endif

template<class Type>
class ACircularBuf
{
public:
	ACircularBuf();
	~ACircularBuf();
	bool StartBuffer(int size);
	void StopBuffer();
	void Clear();
	bool IsFull();
	bool IsEmpty();
	bool CheckIn(Type &);
	bool CheckOut(Type &);
	bool GetWatch(Type &);
	void AlignIn();
	void AlignWatch();
	bool ProceedWatch(int steps);
	bool StepbackWatch(int steps);
protected:
	bool				started;
	Type				*m_Buffer;
	int					m_size;
	int					m_pIn;
	int					m_pOut;
	int					m_pWatch;
	ACriticalSection	m_CritSec;
	HANDLE				m_evIN[2];
	HANDLE				m_evOUT[2];
	HANDLE				m_evEXIT;

	bool betweenInOut(int pwatch);
};

template<class Type>
AFX_INLINE ACircularBuf<Type>::ACircularBuf()
{
	m_Buffer = NULL;
	m_pIn = -1;
	m_pOut = -1;
	m_pWatch = -1;
	m_size = 0;

	m_evEXIT = NULL;
	m_evIN[1] = NULL;
	m_evOUT[1] = NULL;

	started = false;
}

template<class Type>
AFX_INLINE ACircularBuf<Type>::~ACircularBuf()
{
	Clear();
}

template<class Type>
AFX_INLINE void ACircularBuf<Type>::Clear()
{
	// Clear buffer
	if( m_Buffer!=NULL ) {
		delete [] m_Buffer;
		m_Buffer = NULL;
	}

	m_pIn = -1;
	m_pOut = -1;
	m_pWatch = -1;
	m_size = 0;

	// Close exit event
	if( m_evEXIT!=NULL ) {
		CloseHandle(m_evEXIT);
		m_evEXIT = NULL;
	}
	// Close wait for space event
	if( m_evIN[1]!=NULL ) {
		CloseHandle(m_evIN[1]);
		m_evIN[1] = NULL;
	}
	// Close wait for item event
	if( m_evOUT[1]!=NULL) {
		CloseHandle(m_evOUT[1]);
		m_evOUT[1] = NULL;
	}

}

template<class Type>
AFX_INLINE bool ACircularBuf<Type>::StartBuffer(int size)
{
	Clear();

	m_size = size;
	m_Buffer = new Type[size];
	if( m_Buffer==NULL )
		goto SetSizeFailed;

	// Create exit event
	m_evEXIT = ::CreateEvent(NULL, TRUE, FALSE, NULL);
	if( m_evEXIT==NULL )
		goto SetSizeFailed;
	m_evIN[0] = m_evEXIT;
	m_evOUT[0] = m_evEXIT;

	// Create wait for space event
	m_evIN[1] = ::CreateEvent(NULL, TRUE, TRUE, NULL);
	if( m_evIN[1]==NULL )
		goto SetSizeFailed;

	// Create wait for item event
	m_evOUT[1] = ::CreateEvent(NULL, TRUE, TRUE, NULL);
	if( m_evOUT[1]==NULL )
		goto SetSizeFailed;

	// Initilize the three pointer
	m_pIn = m_pOut = m_pWatch = 0;

	started = true;

	return true;

SetSizeFailed:
	Clear();
	return false;
}

template<class Type>
AFX_INLINE void ACircularBuf<Type>::StopBuffer()
{
	if( started==false )
		return;

	HANDLE ev[2];

	::SetEvent(m_evEXIT);

	ev[0] = m_evIN[1];
	ev[1] = m_evOUT[1];
	::WaitForMultipleObjects(2, ev, TRUE, INFINITE);

	Clear();

	started = false;
}

template<class Type>
AFX_INLINE bool ACircularBuf<Type>::IsFull()
{
	ALock lock(&m_CritSec);

	// DON'T delete this line
	// This line is inteded to prevend the problem
	// when we stop the consumer and producer of this buffer
	if( m_pIn==-1 ) return true;

	if( m_pOut==(m_pIn+1)%m_size )
		return true;
	else
		return false;
}

template<class Type>
AFX_INLINE bool ACircularBuf<Type>::IsEmpty()
{
	ALock lock(&m_CritSec);

	// DON'T delete this line
	// This line is inteded to prevend the problem
	// when we stop the consumer and producer of this buffer
	if( m_pOut==-1 ) return true;

	if( m_pIn==m_pOut )
		return true;
	else
		return false;
}

template<class Type>
AFX_INLINE bool ACircularBuf<Type>::CheckIn(Type &data)
{
	bool ToWait = false;

	{
		ALock lock(&m_CritSec);
		if( IsFull() ) {
			::ResetEvent(m_evIN[1]);
			ToWait = true;
		}
	}

	if( ToWait==true ) {
		DWORD rets = ::WaitForMultipleObjects(2, m_evIN, FALSE, INFINITE);
		if( rets==WAIT_OBJECT_0 ) {
			// exit event is signalled
			// signale wait for space event to resume the blocked StopBuffer function.
			::SetEvent(m_evIN[1]);
			return false;
		}
	}

	{
		ALock lock(&m_CritSec);

		// DON'T delete this line
		// This line is inteded to prevend the problem
		// when we stop the consumer and producer of this buffer
		if( m_Buffer==NULL )
			return false;

		m_Buffer[m_pIn] = data;

		m_pIn = (m_pIn+1)%m_size;
		
		SetEvent(m_evOUT[1]);

		return true;
	}
}

template<class Type>
AFX_INLINE bool ACircularBuf<Type>::CheckOut(Type &data)
{
	bool ToWait = false;
	{
		ALock lock(&m_CritSec);

		if( IsEmpty() ) {
			::ResetEvent(m_evOUT[1]);
			ToWait = true;
		}
	}
	
	if( ToWait==true ) {
		DWORD rets = ::WaitForMultipleObjects(2, m_evOUT, FALSE, INFINITE);
		if( rets==WAIT_OBJECT_0 ) {
			// exit event is signalled
			// signale wait for item event to resume the blocked StopBuffer function.
			::SetEvent(m_evOUT[1]);
			return false;
		}
	}

	{
		ALock lock(&m_CritSec);
	
		// DON'T delete this line
		// This line is inteded to prevend the problem
		// when we stop the consumer and producer of this buffer
		if( m_Buffer==NULL )
			return false;

		data = m_Buffer[m_pOut];
		if( m_pOut==m_pWatch ) {
			m_pOut = (m_pOut+1)%m_size;
			m_pWatch = m_pOut;
		} else {
			m_pOut = (m_pOut+1)%m_size;
		}

		SetEvent(m_evIN[1]);

		return true;
	}
}

template<class Type>
AFX_INLINE bool ACircularBuf<Type>::GetWatch(Type &data)
{
	bool ToWait = false;
	{
		ALock lock(&m_CritSec);

		if( m_pWatch==m_pIn ) {
			::ResetEvent(m_evOUT[1]);
			ToWait = true;
		}
	}
	
	if( ToWait==true ) {
		DWORD rets = ::WaitForMultipleObjects(2, m_evOUT, FALSE, INFINITE);
		if( rets==WAIT_OBJECT_0 ) {
			// exit event is signalled
			// signale wait for item event to resume the blocked StopBuffer function.
			::SetEvent(m_evOUT[1]);
			return false;
		}
	}

	{
		ALock lock(&m_CritSec);

		// DON'T delete this line
		// This line is inteded to prevend the problem
		// when we stop the consumer and producer of this buffer
		if( m_Buffer==NULL )
			return false;

		data = m_Buffer[m_pWatch];

		m_pWatch = (m_pWatch+1)%m_size;
	}

	return true;
}

template<class Type>
AFX_INLINE void ACircularBuf<Type>::AlignIn()
{
	ALock lock(&m_CritSec);
	
	if( m_pOut==m_pWatch )
		return;

	m_pOut = m_pWatch;

	SetEvent(m_evIN[1]);
}

template<class Type>
AFX_INLINE bool ACircularBuf<Type>::ProceedWatch(int steps)
{
	ALock lock(&m_CritSec);

	// DON'T delete this line
	// This line is inteded to prevend the problem
	// when we stop the consumer and producer of this buffer
	if( m_pWatch==-1 ) return false;

	int newp = (m_pWatch + steps)%m_size;

	if( betweenInOut(newp) ) {
		m_pWatch = newp;
		return true;
	} else {
		return false;
	}
}

template<class Type>
AFX_INLINE bool ACircularBuf<Type>::StepbackWatch(int steps)
{
	ALock lock(&m_CritSec);

	// DON'T delete this line
	// This line is inteded to prevend the problem
	// when we stop the consumer and producer of this buffer
	if( m_pWatch==-1)
		return false;

	int newp = (m_pWatch - steps)%m_size;

	if( betweenInOut(newp) ) {
		m_pWatch = newp;
		return true;
	} else {
		return false;
	}
}

template<class Type>
AFX_INLINE void ACircularBuf<Type>::AlignWatch()
{
	ALock lock(&m_CritSec);

	m_pWatch = m_pOut;
}

template<class Type>
AFX_INLINE bool ACircularBuf<Type>::betweenInOut(int pwatch)
{
	ALock lock(&m_CritSec);

	// empty
	if( m_pIn==m_pOut )
		return false;

	if( m_pOut>m_pIn) {
		if( pwatch>=m_pIn && pwatch<m_pOut)
			return false;
		else
			return true;
	} else {
		if( pwatch>=m_pOut && pwatch<m_pIn)
			return true;
		else
			return false;
	}
}

//template class ACircularBuf<int>;
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -