http://blog.csdn.net/firehood_/article/details/6716357
版权声明:本文为博主原创文章,未经博主允许不得转载。
在WINCE开发中很多时候需要用到循环队列来缓存数据,比如在串口通信中,可以将接收到的数据流先缓存到循环队列中,然后再从循环队列中取出数据做下一步的处理。这样可以有效的避免解析数据帧时繁琐的拼接处理。
为了方便使用,封装了一个循环队列类,具体代码如下:
头文件:
- /********************************************************************
- filename: CircularQueue.h
- created: 2011-08-23
- author: firehood
- purpose: 实现循环队列
- 队列可以缓存的数据大小 = 队列长度 -1
- 插入数据时在队列满的情况下会自动覆盖队列头部数据
- *********************************************************************/
- #pragma once
- #define DEFAULT_QUEUE_MAX_SIZE 512
- class CCircularQueue
- {
- public:
- // 无参构造函数,默认创建队列的大小为512字节
- CCircularQueue(void);
- // 带参构造函数,创建指定大小的队列
- CCircularQueue(int nQueueSize);
- ~CCircularQueue(void);
- public:
- // 向队列尾部插入一个字节,队列满时会自动覆盖队列头部数据
- bool PushBack(unsigned char data);
- // 从队列头部取出一个字节
- bool PopFront(unsigned char &data);
- // 向队列尾部插入指定长度数据,队列满时会自动覆盖队列头部数据
- bool PushBack(unsigned char *pData, int size);
- // 从队列头部取出指定长度数据
- // 返回值:>0 返回实际取出的数据长度; <=0 失败
- int PopFront(unsigned char *pData, int size);
- // 重新调整队列大小
- bool Resize(int nQueueSize);
- // 当前队列缓存的数据大小
- int Size();
- // 队列当前剩余空间大小
- int RemainSize();
- // 队列是否为空
- bool IsEmpty();
- // 队列是否满
- bool IsFull();
- // 打印数据(测试使用)
- void PrintData();
- private:
- unsigned char *m_pQueueBase; // 队列基址
- int m_QueueSize; // 队列大小
- int m_Head, m_Tail; // 队列头尾指针
- CRITICAL_SECTION m_csRW; // 读写锁
- };
源文件:
- /********************************************************************
- filename: CircularQueue.cpp
- created: 2011-08-23
- author: firehood
- purpose: 实现循环队列
- 队列可以缓存的数据大小 = 队列长度 -1
- 插入数据时在队列满的情况下会自动覆盖队列头部数据
- *********************************************************************/
- #include "stdafx.h"
- #include "CircularQueue.h"
- CCircularQueue::CCircularQueue(void):
- m_pQueueBase(NULL),
- m_Head(0),
- m_Tail(0),
- m_QueueSize(DEFAULT_QUEUE_MAX_SIZE)
- {
- m_pQueueBase = new unsigned char[m_QueueSize];
- ASSERT(m_pQueueBase);
- memset(m_pQueueBase, 0, m_QueueSize);
- InitializeCriticalSection(&m_csRW);
- }
- CCircularQueue::CCircularQueue(int nQueueSize):
- m_pQueueBase(NULL),
- m_Head(0),
- m_Tail(0),
- m_QueueSize(nQueueSize)
- {
- m_pQueueBase = new unsigned char[m_QueueSize];
- ASSERT(m_pQueueBase);
- memset(m_pQueueBase, 0, m_QueueSize);
- InitializeCriticalSection(&m_csRW);
- }
- CCircularQueue::~CCircularQueue(void)
- {
- if(m_pQueueBase)
- {
- delete[] m_pQueueBase;
- m_pQueueBase = NULL;
- }
- DeleteCriticalSection (&m_csRW);
- }
- // 向队列尾部插入一个字节,队列满时会自动覆盖队列头部数据
- bool CCircularQueue::PushBack(unsigned char data)
- {
- if(m_pQueueBase == NULL)
- {
- return false;
- }
- EnterCriticalSection(&m_csRW);
- m_pQueueBase[m_Tail]= data;
- m_Tail =(m_Tail+1) % m_QueueSize;
- if(m_Tail == m_Head)
- {
- m_Head = m_Tail+1;
- printf("Warning:lost data, Queue is full..\n");
- }
- LeaveCriticalSection(&m_csRW);
- return true;
- }
- // 从队列头部取出一个字节
- bool CCircularQueue::PopFront(unsigned char &data)
- {
- if(m_pQueueBase == NULL)
- {
- return false;
- }
- if(IsEmpty())
- {
- return false;
- }
- EnterCriticalSection(&m_csRW);
- data = m_pQueueBase[m_Head];
- m_Head=(m_Head+1) % m_QueueSize;
- LeaveCriticalSection(&m_csRW);
- return true;
- }
- // 向队列尾部插入指定长度数据,队列满时会自动覆盖队列头部数据
- bool CCircularQueue::PushBack(unsigned char *pData, int size)
- {
- if(m_pQueueBase == NULL || pData == NULL)
- {
- return false;
- }
- if(size >= m_QueueSize)
- {
- printf("PushBack failed: DataSize[%d] > MAX_QUEUE_SIZE[%d]\n" , size, (m_QueueSize-1));
- return false;
- }
- EnterCriticalSection(&m_csRW);
- int nRemianSize = RemainSize();
- int nTailToEndSize = m_QueueSize - m_Tail;
- if(size <= nTailToEndSize)
- {
- memcpy(m_pQueueBase+m_Tail, pData, size);
- }
- else
- {
- memcpy(m_pQueueBase+m_Tail, pData, nTailToEndSize);
- memcpy(m_pQueueBase,pData+nTailToEndSize, size-nTailToEndSize);
- }
- m_Tail = (m_Tail+size) % m_QueueSize;
- if(size >= nRemianSize)
- {
- printf("Warning:lost data, Queue is full..\n");
- m_Head = m_Tail+1;
- }
- LeaveCriticalSection(&m_csRW);
- return true;
- }
- // 从队列头部取出指定长度数据
- // 返回值:>0 返回实际取出的数据长度; <=0 失败
- int CCircularQueue::PopFront(unsigned char *pData, int size)
- {
- if(pData == NULL || m_pQueueBase == NULL)
- return -1;
- EnterCriticalSection(&m_csRW);
- int nReadSize = (this->Size()>size) ? size : this->Size();
- int nHeadToEndSize = m_QueueSize - m_Head;
- if(nReadSize <= nHeadToEndSize)
- {
- memcpy(pData, m_pQueueBase+m_Head, nReadSize);
- }
- else
- {
- memcpy(pData,m_pQueueBase+m_Head, nHeadToEndSize);
- memcpy(pData+nHeadToEndSize,m_pQueueBase,nReadSize-nHeadToEndSize);
- }
- m_Head=(m_Head+nReadSize) % m_QueueSize;
- LeaveCriticalSection(&m_csRW);
- return nReadSize;
- }
- // 当前队列缓存的数据大小
- int CCircularQueue::Size()
- {
- return (m_Tail-m_Head+m_QueueSize) % m_QueueSize;
- }
- // 队列是否为空
- bool CCircularQueue::IsEmpty()
- {
- return (m_Head == m_Tail) ? true : false;
- }
- // 队列是否满
- bool CCircularQueue::IsFull()
- {
- return (((m_Tail+1) % m_QueueSize) == m_Head) ? true : false;
- }
- // 队列当前剩余空间大小
- int CCircularQueue::RemainSize()
- {
- return ((m_QueueSize-1)-Size());
- }
- // 打印数据
- void CCircularQueue::PrintData()
- {
- int tempHead, tempTail;
- tempHead = m_Head;
- tempTail = m_Tail;
- printf("************************************************\n");
- printf("CirualarQueue Data:");
- while(tempHead != tempTail)
- {
- printf("0x%02x ", m_pQueueBase[tempHead]);
- tempHead=(tempHead+1) % m_QueueSize;
- }
- printf("\n");
- printf("************************************************\n");
- }
- // 重新调整队列大小
- bool CCircularQueue::Resize(int nQueueSize)
- {
- unsigned char *pNewQueue = NULL;
- // 申请新的队列空间
- pNewQueue = new unsigned char[nQueueSize];
- if(pNewQueue == NULL) // 申请内存失败
- return false;
- // 将队列原有数据拷贝到新队列中
- int len = PopFront(pNewQueue,nQueueSize);
- // 释放原来队列空间
- if(m_pQueueBase)
- {
- delete[] m_pQueueBase;
- m_pQueueBase = NULL;
- }
- // 使用新的队列空间
- m_pQueueBase = pNewQueue;
- m_QueueSize = nQueueSize;
- m_Head = 0;
- m_Tail = len;
- return true;
- }
-
顶
- 0
-
踩
- 0