zoukankan      html  css  js  c++  java
  • C++版的循环缓冲区类(实际测试可用!)

    /*
     * CCycleBuffer.h
     *
     *  Created on: 2013-5-27
     *      Author: shiguang
     */
    
    #ifndef __test__CCycleBuffer__
    #define __test__CCycleBuffer__
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    class CCycleBuffer
    {
    public:
    	bool isFull();
    	bool isEmpty();
    	void Empty();
    	int GetLength();
    	CCycleBuffer(int size);
    	virtual ~CCycleBuffer();
    	int Write(char* buf, int count);
    	int Read(char* buf, int count);
    private:
    	bool m_bEmpty, m_bFull;
    	char * m_pBuf;
    	int m_nBufSize;
    	int m_nReadPos;
    	int m_nWritePos;
    
    public:
    	int GetReadPos()
    	{
    		return m_nReadPos;
    	}
    	int GetWritePos()
    	{
    		return m_nWritePos;
    	}
    };
    #endif /* defined(__test__CCycleBuffer__) */
    


    /*
     * CCycleBuffer.cpp
     *
     *  Created on: 2013-5-27
     *      Author: shiguang
     */
    
    #include "CCycleBuffer.h"
    // 定义
    CCycleBuffer::CCycleBuffer(int size)
    {
    	m_nBufSize = size;
    	m_nReadPos = 0;
    	m_nWritePos = 0;
    	m_pBuf = new char[m_nBufSize];
    	m_bEmpty = true;
    	m_bFull = false;
    }
    
    CCycleBuffer::~CCycleBuffer()
    {
    	delete[] m_pBuf;
    }
    
    /************************************************************************/
    /* 向缓冲区写入数据,返回实际写入的字节数                               */
    /************************************************************************/
    int CCycleBuffer::Write(char* buf, int count)
    {
    	if (count <= 0)
    		return 0;
    	m_bEmpty = false;
    	// 缓冲区已满,不能继续写入
    	if (m_bFull)
    	{
    		return 0;
    	}
    	else if (m_nReadPos == m_nWritePos) // 缓冲区为空时
    	{
    		/*                          == 内存模型 ==
    		 (empty)             m_nReadPos                (empty)
    		 |----------------------------------|-----------------------------------------|
    		 m_nWritePos        m_nBufSize
    		 */
    		int leftcount = m_nBufSize - m_nWritePos;
    		if (leftcount > count)
    		{
    			memcpy(m_pBuf + m_nWritePos, buf, count);
    			m_nWritePos += count;
    			m_bFull = (m_nWritePos == m_nReadPos);
    			return count;
    		}
    		else
    		{
    			memcpy(m_pBuf + m_nWritePos, buf, leftcount);
    			m_nWritePos =
    					(m_nReadPos > count - leftcount) ?
    							count - leftcount : m_nReadPos; // 计算未写入数据大小
    			memcpy(m_pBuf, buf + leftcount, m_nWritePos);
    			m_bFull = (m_nWritePos == m_nReadPos);
    			return leftcount + m_nWritePos;
    		}
    	}
    	else if (m_nReadPos < m_nWritePos) // 有剩余空间可写入
    	{
    		/*                           == 内存模型 ==
    		 (empty)                 (data)                     (empty)
    		 |-------------------|----------------------------|---------------------------|
    		 m_nReadPos                m_nWritePos       (leftcount)
    		 */
    		// 剩余缓冲区大小(从写入位置到缓冲区尾)
    		int leftcount = m_nBufSize - m_nWritePos;
    		if (leftcount > count)   // 有足够的剩余空间存放
    		{
    			memcpy(m_pBuf + m_nWritePos, buf, count);
    			m_nWritePos += count;
    			m_bFull = (m_nReadPos == m_nWritePos);
    			assert(m_nReadPos <= m_nBufSize);
    			assert(m_nWritePos <= m_nBufSize);
    			return count;
    		}
    		else       // 剩余空间不足
    		{
    			// 先填充满剩余空间,再回头找空间存放
    			memcpy(m_pBuf + m_nWritePos, buf, leftcount);
    			m_nWritePos =
    					(m_nReadPos >= count - leftcount) ?
    							count - leftcount : m_nReadPos;
    			memcpy(m_pBuf, buf + leftcount, m_nWritePos);
    			m_bFull = (m_nReadPos == m_nWritePos);
    			assert(m_nReadPos <= m_nBufSize);
    			assert(m_nWritePos <= m_nBufSize);
    			return leftcount + m_nWritePos;
    		}
    	}
    	else
    	{
    		/*                          == 内存模型 ==
    		 (unread)                 (read)                     (unread)
    		 |-------------------|----------------------------|---------------------------|
    		 m_nWritePos    (leftcount)    m_nReadPos
    		 */
    		int leftcount = m_nReadPos - m_nWritePos;
    		if (leftcount > count)
    		{
    			// 有足够的剩余空间存放
    			memcpy(m_pBuf + m_nWritePos, buf, count);
    			m_nWritePos += count;
    			m_bFull = (m_nReadPos == m_nWritePos);
    			assert(m_nReadPos <= m_nBufSize);
    			assert(m_nWritePos <= m_nBufSize);
    			return count;
    		}
    		else
    		{
    			// 剩余空间不足时要丢弃后面的数据
    			memcpy(m_pBuf + m_nWritePos, buf, leftcount);
    			m_nWritePos += leftcount;
    			m_bFull = (m_nReadPos == m_nWritePos);
    			assert(m_bFull);
    			assert(m_nReadPos <= m_nBufSize);
    			assert(m_nWritePos <= m_nBufSize);
    			return leftcount;
    		}
    	}
    }
    
    /************************************************************************/
    /* 从缓冲区读数据,返回实际读取的字节数                                 */
    /************************************************************************/
    int CCycleBuffer::Read(char* buf, int count)
    {
    	if (count <= 0)
    		return 0;
    	m_bFull = false;
    	if (m_bEmpty)       // 缓冲区空,不能继续读取数据
    	{
    		return 0;
    	}
    	else if (m_nReadPos == m_nWritePos)   // 缓冲区满时
    	{
    		/*                          == 内存模型 ==
    		 (data)          m_nReadPos                (data)
    		 |--------------------------------|--------------------------------------------|
    		 m_nWritePos         m_nBufSize
    		 */
    		int leftcount = m_nBufSize - m_nReadPos;
    		if (leftcount > count)
    		{
    			memcpy(buf, m_pBuf + m_nReadPos, count);
    			m_nReadPos += count;
    			m_bEmpty = (m_nReadPos == m_nWritePos);
    			return count;
    		}
    		else
    		{
    			memcpy(buf, m_pBuf + m_nReadPos, leftcount);
    			m_nReadPos =
    					(m_nWritePos > count - leftcount) ?
    							count - leftcount : m_nWritePos;
    			memcpy(buf + leftcount, m_pBuf, m_nReadPos);
    			m_bEmpty = (m_nReadPos == m_nWritePos);
    			return leftcount + m_nReadPos;
    		}
    	}
    	else if (m_nReadPos < m_nWritePos)   // 写指针在前(未读数据是连接的)
    	{
    		/*                          == 内存模型 ==
    		 (read)                 (unread)                      (read)
    		 |-------------------|----------------------------|---------------------------|
    		 m_nReadPos                m_nWritePos                     m_nBufSize
    		 */
    		int leftcount = m_nWritePos - m_nReadPos;
    		int c = (leftcount > count) ? count : leftcount;
    		memcpy(buf, m_pBuf + m_nReadPos, c);
    		m_nReadPos += c;
    		m_bEmpty = (m_nReadPos == m_nWritePos);
    		assert(m_nReadPos <= m_nBufSize);
    		assert(m_nWritePos <= m_nBufSize);
    		return c;
    	}
    	else          // 读指针在前(未读数据可能是不连接的)
    	{
    		/*                          == 内存模型 ==
    		 (unread)                (read)                      (unread)
    		 |-------------------|----------------------------|---------------------------|
    		 m_nWritePos                  m_nReadPos                  m_nBufSize
    
    		 */
    		int leftcount = m_nBufSize - m_nReadPos;
    		if (leftcount > count)   // 未读缓冲区够大,直接读取数据
    		{
    			memcpy(buf, m_pBuf + m_nReadPos, count);
    			m_nReadPos += count;
    			m_bEmpty = (m_nReadPos == m_nWritePos);
    			assert(m_nReadPos <= m_nBufSize);
    			assert(m_nWritePos <= m_nBufSize);
    			return count;
    		}
    		else       // 未读缓冲区不足,需回到缓冲区头开始读
    		{
    			memcpy(buf, m_pBuf + m_nReadPos, leftcount);
    			m_nReadPos =
    					(m_nWritePos >= count - leftcount) ?
    							count - leftcount : m_nWritePos;  // 计算剩余未读数据大小
    			memcpy(buf + leftcount, m_pBuf, m_nReadPos); // 注意目的指针位置
    			m_bEmpty = (m_nReadPos == m_nWritePos);
    			assert(m_nReadPos <= m_nBufSize);
    			assert(m_nWritePos <= m_nBufSize);
    			return leftcount + m_nReadPos;
    		}
    	}
    }
    
    /************************************************************************/
    /* 获取缓冲区有效数据长度                                               */
    /************************************************************************/
    int CCycleBuffer::GetLength()
    {
    	if (m_bEmpty)
    	{
    		return 0;
    	}
    	else if (m_bFull)
    	{
    		return m_nBufSize;
    	}
    	else if (m_nReadPos < m_nWritePos)
    	{
    		return m_nWritePos - m_nReadPos;
    	}
    	else
    	{
    		return m_nBufSize - m_nReadPos + m_nWritePos;
    	}
    }
    
    void CCycleBuffer::Empty()
    {
    	m_nReadPos = 0;
    	m_nWritePos = 0;
    	m_bEmpty = true;
    	m_bFull = false;
    }
    
    bool CCycleBuffer::isEmpty()
    {
    	return m_bEmpty;
    }
    
    bool CCycleBuffer::isFull()
    {
    	return m_bFull;
    }
    


    /*
     * main.cpp
     *
     *  Created on: 2013-5-27
     *      Author: shiguang
     */
    
    #include "CCycleBuffer.h"
    
    int main()
    {
    	CCycleBuffer buffer(100);
    	char* datachar = new char[40];
    	char* reschar = new char[100];
    
    	int res = 0;
    
    	for (int i = 0; i < 40; ++i)
    	{
    		datachar[i] = i + 1;
    	}
    	res = buffer.Write(datachar, 40);
    	printf("写入数据个数:%d\n", res);
    	res = buffer.Write(datachar, 40);
    	printf("写入数据个数:%d\n", res);
    	res = buffer.Write(datachar, 40);
    	printf("写入数据个数:%d\n", res);
    	res = buffer.Write(datachar, 40);
    	printf("写入数据个数:%d\n", res);
    
    	res = buffer.Read(reschar, 100);
    	printf("读取数据个数:%d\n", res);
    	for (int i = 0; i < 100; ++i)
    	{
    		if (i % 10 == 0)
    		{
    			printf("\n");
    		}
    		printf("%2d   ", reschar[i]);
    	}
    
    	return 0;
    }
    


    输出结果:

    写入数据个数:40
    写入数据个数:40
    写入数据个数:20
    写入数据个数:0
    读取数据个数:100
    
     1    2    3    4    5    6    7    8    9   10   
    11   12   13   14   15   16   17   18   19   20   
    21   22   23   24   25   26   27   28   29   30   
    31   32   33   34   35   36   37   38   39   40   
     1    2    3    4    5    6    7    8    9   10   
    11   12   13   14   15   16   17   18   19   20   
    21   22   23   24   25   26   27   28   29   30   
    31   32   33   34   35   36   37   38   39   40   
     1    2    3    4    5    6    7    8    9   10   
    11   12   13   14   15   16   17   18   19   20   


    源程序来自网络资料!

  • 相关阅读:
    如何使用SAP Intelligent Robotic Process Automation自动操作Excel
    OpenSAML 使用引导 IV: 安全特性
    Spring Cloud Zuul 网关使用与 OAuth2.0 认证授权服务
    微服务架构集大成者—Spring Cloud (转载)
    Spring Cloud Eureka 服务注册列表显示 IP 配置问题
    使用 Notification API 开启浏览器桌面提醒
    SignalR 中使用 MessagePack 序列化提高 WebSocket 通信性能
    配置 Nginx 的目录浏览功能
    关于 Nginx 配置 WebSocket 400 问题
    Migrate from ASP.NET Core 2.0 to 2.1
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3106618.html
Copyright © 2011-2022 走看看