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

📄 mybuffer.h

📁 内存缓冲区类
💻 H
字号:
//---------------------------------------------------------------------------
/**	@file	MyBuffer.h
* @brief	缓冲区类,按关键字宽度读取、存入。
*  @author	刘双笑
*  @copyright	版权所有,擅用将承担法律责任。如有需要请联系telllsx@21cn.com
*  		学习时请保留作者名称和版权信息。
*  @date	完  成:2007.5
*  @date	修  改:
*/
//----------------------------------------------------------------------------
#pragma once

// 缓冲区类,按关键字宽度读取、存入。
// 可以指定缓冲区大小,自动申请释放内存,也可以使用类外部已申请的内存
class CBuffer
{	
public:
	typedef int (__cdecl *SortFunc)( const char *, const char *);

	char			*pszBuf;		
protected:
	bool			m_bAllocated;		
	char			*m_pEnd;		
	DWORD			m_dwBufSize;		
	unsigned short	m_usKeyWidth;

	void buffer_resize(DWORD s) 
	{	
		ASSERT( m_usKeyWidth > 0);

		m_dwBufSize = s / m_usKeyWidth * m_usKeyWidth; 
	}

public:
	CBuffer() : pszBuf(NULL),m_pEnd(NULL),m_dwBufSize(0),m_bAllocated(true)
	{
	}
	
	~CBuffer()
	{
		release_buffer();
	}

	// 自动申请释放内存?
	bool is_auto_allocate()	const	{	return m_bAllocated;	}

	// 设置是否自动申请释放内存,慎用!使用不当可能导致内存泄漏
	void auto_allocate(bool bAuto)	{	m_bAllocated = bAuto;	}

	// 释放缓冲区内存,缓冲区指针、缓冲区长度清0
	void release_buffer()
	{
		if(m_bAllocated) // 自动释放
		{
			if(pszBuf != NULL)
			{
				delete [] pszBuf;
			}
		}

		pszBuf		 = NULL;
		m_dwBufSize	 = 0;
	}

	// 绑定新的缓冲区内存块,释放老的缓冲区内存块
	void attach_buffer(char *buf ,DWORD bufSize)
	{
		release_buffer();

		pszBuf		 = buf;
		m_pEnd		 = pszBuf;
		
		buffer_resize(bufSize); 
	}

	// 初始化,绑定外部申请的缓冲区内存块,不自动释放
	// width		- 关键字宽度
	// buf			- 外部缓冲区指针
	// bufSize		- 缓冲区长度
	void init(unsigned short width,char *buf ,DWORD bufSize)
	{
		ASSERT( width > 0);
		ASSERT( bufSize > 0);

		m_usKeyWidth	 = width;	

		attach_buffer(buf,bufSize);

		m_bAllocated = false;		

	}

	// 初始化,自动申请、释放内存,并初始化缓冲区
	// width - 关键字宽度
	// num - 缓冲区关键字容量
	// cFill - 缓冲区填充字符
	void init(unsigned short width,DWORD num,unsigned char cFill )
	{
		init(width,num );

		memset( pszBuf, m_dwBufSize, cFill);
	}

	// 初始化,自动申请、释放内存
	// width - 关键字宽度
	// num - 缓冲区关键字容量
	bool init(unsigned short width,DWORD num )
	{
		ASSERT( num > 0);
		ASSERT( width > 0);

		try{
			if(  m_usKeyWidth == width && m_dwBufSize == num * width)
				return true;

			release_buffer();

			m_bAllocated = true;	

			m_usKeyWidth	 = width;	

			m_dwBufSize = num * m_usKeyWidth; 

			pszBuf		 = new char[m_dwBufSize];
			if(pszBuf == NULL)
				throw 1;

			m_pEnd		 = pszBuf;
		}
		catch(...)
		{
			pszBuf = NULL;
			m_pEnd = NULL;
			m_dwBufSize = 0;
			m_bAllocated = true;
			return false;
		}

		return true;
	}

	// 缓冲区为空?
	bool is_nul()	const {		return  pszBuf == NULL;	}

	// 关键字满?
	bool full() const 	{		return is_nul() ? true : ( m_pEnd >= (pszBuf + m_dwBufSize) ) ;	}

	// 没有关键字?
	bool empty() const 	{		return m_pEnd == pszBuf;	}

	// 缓冲区关键字内容字节数
	DWORD valid_bytes() const {	return DWORD( m_pEnd - pszBuf );	 }

	// 获取缓冲区大小
	DWORD buffer_size() const	{	return m_dwBufSize; }

	// 获取关键字个数
	DWORD size() const	{		return DWORD( m_pEnd - pszBuf ) / m_usKeyWidth; }

	// 获取关键字宽度
	unsigned short	key_width()	const {	return m_usKeyWidth;	}

	// 获取缓冲区容量(关键字个数)
	DWORD capacity() const	{	return ( m_dwBufSize / m_usKeyWidth ); }

	// 重设关键字个数
	// dwCount - 关键字个数
	void resize(DWORD dwCount)		
	{
		ASSERT( dwCount * m_usKeyWidth <= m_dwBufSize );
	
		m_pEnd = pszBuf + dwCount * m_usKeyWidth;	
	}

	// 重设关键字个数,并初始化新增的关键字
	// dwCount	 - 关键字个数
	// cFill	 - 初始化填充物
	void resize(DWORD dwCount,char cFill)		
	{
		ASSERT( dwCount * m_usKeyWidth <= m_dwBufSize );
	
		char* pNewEnd = pszBuf + dwCount * m_usKeyWidth ;

		if( pNewEnd > m_pEnd )
			memset( m_pEnd,cFill, pNewEnd - m_pEnd );

		m_pEnd = pNewEnd;	
	}

	// 清空缓冲区关键字
	void clear()		{		m_pEnd = pszBuf;	}

	// 尾部插入关键字
	// key	 - 关键字个数
	// 返回值: false - 缓冲区满, true - 操作成功	
	bool push_back(const char* key)
	{
		ASSERT( m_pEnd != NULL );

		if( full() ) 
			return false;
		
		memcpy(m_pEnd ,key,m_usKeyWidth);
		
		m_pEnd += m_usKeyWidth;

		return true;
	}

	// 尾部插入关键字
	// key	 - 关键字个数
	// width	 - 关键字宽度
	// 返回值: false - 缓冲区满, true - 操作成功	
	bool push_back(const char* key,size_t width)
	{
		ASSERT( m_pEnd != NULL );

		if( full() ) // 已满
			return false;
		
		memset(m_pEnd ,0,m_usKeyWidth );

		memcpy(m_pEnd ,key,min(width,m_usKeyWidth) );
		
		m_pEnd += m_usKeyWidth;

		return true;
	}

	// 删除首个关键字
	// false - 缓冲区中没有关键字, true - 操作成功
	bool pop_head()
	{
		ASSERT( pszBuf != NULL );

		ASSERT( !m_bAllocated) ;

		if( empty() ) 
			return false;
		
		pszBuf += m_usKeyWidth;

		m_dwBufSize-= m_usKeyWidth;

		return true;
	}

	// 删除尾个关键字
	// false - 缓冲区中没有关键字, true - 操作成功
	bool pop_back()
	{
		ASSERT( pszBuf != NULL );

		if( empty() ) // 关键字空
			return false;
		
		m_pEnd -= m_usKeyWidth;

		return true;
	}

	// 按序号访问关键字,序号超出范围返回NULL
	char* operator[](DWORD no) 
	{
		ASSERT( m_usKeyWidth > 0 );

		if( no * m_usKeyWidth >= m_dwBufSize || pszBuf == NULL )
			return NULL;

		return pszBuf + no * m_usKeyWidth;	
	}

	// 对缓冲区中的关键字排序
	void sort(SortFunc pred)
	{
		if( ! empty () )
		{
			::qsort(pszBuf,size(),m_usKeyWidth,(int (__cdecl *)(const void *, const void *))pred);		
		}
	}	
};

⌨️ 快捷键说明

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