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

1 篇文章 0 订阅

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

为了项目中编写上位机软件,刚开始学习C++,把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();
}
  • 12
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值