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

来源:互联网 发布:二叉树的结点算法 编辑:程序博客网 时间:2024/05/17 03:46

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();}
0 0
原创粉丝点击