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

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

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

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

ringbuffer.h

#ifndef QRINGBUFFER_H
#define QRINGBUFFER_H

#include 

#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 
#include 
#include "qringbuffer.h"
using namespace std;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QRingBuffer buffer;

    cout<<"buffer size:"<char data1[48] = {0x55};
    char data2[8] = {0};
    cout<<"buffer can read:"<cout<<"buffer can write:"<cout<<"buffer writing..."<sizeof(data1));
    cout<<"buffer can read:"<cout<<"buffer can write:"<cout<<"buffer reading..."<8);
    cout<<"buffer can read:"<cout<<"buffer can write:"<cout<<"HelloWorld!"<return a.exec();
}

你可能感兴趣的:(C++,Qt)