首页 > 编程 > C++ > 正文

C++ 环形缓冲区RingBuffer 简单实现

2019-11-08 02:59:09
字体:
来源:转载
供稿:网友

C++环形缓冲区RingBuffer的简单实现

为了项目中编写上位机软件,最近开始学习C++ 刚刚入门,C++中很多知识都还不会,在练习中学习吧。由于需要进行串口通信,打算引入一个环形缓冲区,可能C++标准库中有某类容器可以很简单的实现缓冲区的功能,但我不会啊~233333,除了简单的写成了类,其他都是C语言写出来的。

为什么需要缓冲区,参考生产者 消费者模式

ringbuffer.h

#ifndef QRINGBUFFER_H#define QRINGBUFFER_H#include <cstring>#ifndef RB_MAX_LEN#define RB_MAX_LEN 2048#endif#define min(a, b) (a)<(b)?(a):(b) //求最小class QRingBuffer{public: QRingBuffer(int size = RB_MAX_LEN); ~QRingBuffer(); int canRead(); //how much can read int canWrite(); //how much can write int read(void *data, int count); //read data frome ringbuffer int write(const void *data, int count); int size();PRivate: int bufferSize; //buffer size unsigned char *rbBuf = new unsigned char [bufferSize]; /*环形缓冲区变量*/ int rbCapacity; //容量 unsigned char *rbHead; unsigned char *rbTail; unsigned char *rbBuff;};#endif // QRINGBUFFER_H

ringbuffer.cpp

#include "qringbuffer.h"/** * @brief QRingBuffer::QRingBuffer * @param buffersize Byte */QRingBuffer::QRingBuffer(int size){ bufferSize = size; rbCapacity = size; rbBuff = rbBuf; rbHead = rbBuff; rbTail = rbBuff;}QRingBuffer::~QRingBuffer(){ rbBuff = nullptr; rbHead = nullptr; rbTail = nullptr; rbCapacity = 0; delete []rbBuf; //释放缓冲区}/** * @brief QRingBuffer::rbCanRead * @return 缓冲区可读字节数 */int QRingBuffer::canRead(){ //ring buufer is null, return -1 if((nullptr == rbBuff)||(nullptr == rbHead)||(nullptr == rbTail)) { return -1; } if (rbHead == rbTail) { return 0; } if (rbHead < rbTail) { return rbTail - rbHead; } return rbCapacity - (rbHead - rbTail);}/** * @brief QRingBuffer::rbCanWrite 缓冲区剩余可写字节数 * @return 可写字节数 */int QRingBuffer::canWrite(){ if((nullptr == rbBuff)||(nullptr == rbHead)||(nullptr == rbTail)) { return -1; } return rbCapacity - canRead();}/** * @brief QRingBuffer::read 从缓冲区读数据 * @param 目标数组地址 * @param 读的字节数 * @return */int QRingBuffer::read(void *data, int count){ int copySz = 0; if((nullptr == rbBuff)||(nullptr == rbHead)||(nullptr == rbTail)) { return -1; } if(nullptr == data) { return -1; } if (rbHead < rbTail) { copySz = min(count, canRead()); memcpy(data, rbHead, copySz); rbHead += copySz; return copySz; } else { if (count < rbCapacity-(rbHead - rbBuff)) { copySz = count; memcpy(data, rbHead, copySz); rbHead += copySz; return copySz; } else { copySz = rbCapacity - (rbHead - rbBuff); memcpy(data, rbHead, copySz); rbHead = rbBuff; copySz += read((unsigned char *)data+copySz, count-copySz); return copySz; } }}/** * @brief QRingBuffer::write * @param 数据地址 * @param 要写的字节数 * @return 写入的字节数 */int QRingBuffer::write(const void *data, int count){ int tailAvailSz = 0; if((nullptr == rbBuff)||(nullptr == rbHead)||(nullptr == rbTail)) { return -1; } if(nullptr == data) { return -1; } if (count >= canWrite()) { return -1; } if (rbHead <= rbTail) { tailAvailSz = rbCapacity - (rbTail - rbBuff); if (count <= tailAvailSz) { memcpy(rbTail, data, count); rbTail += count; if (rbTail == rbBuff+rbCapacity) { rbTail = rbBuff; } return count; } else { memcpy(rbTail, data, tailAvailSz); rbTail = rbBuff; return tailAvailSz + write((char*)data+tailAvailSz, count-tailAvailSz); } } else { memcpy(rbTail, data, count); rbTail += count; return count; }}/** * @brief QRingBuffer::size * @return 缓冲区大小 */int QRingBuffer::size(){ return bufferSize;}

简单测试一下:

main.cpp

#include <QCoreapplication>#include <iostream>#include "qringbuffer.h"using namespace std;int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); QRingBuffer buffer; cout<<"buffer size:"<<buffer.size()<<endl; char data1[48] = {0x55}; char data2[8] = {0}; cout<<"buffer can read:"<<buffer.canRead()<<endl; cout<<"buffer can write:"<<buffer.canWrite()<<endl; cout<<"buffer writing..."<<endl; buffer.write(data1,sizeof(data1)); cout<<"buffer can read:"<<buffer.canRead()<<endl; cout<<"buffer can write:"<<buffer.canWrite()<<endl; cout<<"buffer reading..."<<endl; buffer.read(data2,8); cout<<"buffer can read:"<<buffer.canRead()<<endl; cout<<"buffer can write:"<<buffer.canWrite()<<endl; cout<<"HelloWorld!"<<endl; return a.exec();}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选