C# · 12月 20, 2021

环形缓冲区ringbuffer c++类模版实现

@ringbuffer

环形缓冲区ringbuffer c++类模版实现

使用方法:

1、将ringBuffer.h文件拷贝到开发工程中,添加相应的头文件

2、需要g++编译器(开发的项目工程需要支持),编译此类模版

3、支持int、char、bool等类型

#pragma once

#include “stdlib.h”

#include

#define MAX_ASK_FOR_CAP (1 << 16) // 64K

struct BufferInfo{

BufferInfo(unsigned int r = 0,unsigned int w = 0,unsigned int c = 0)

: read(r)

,write(w)

,capacity(c)

,mask(c – 1)

{

}

unsigned int read; // read index in buffer

unsigned int write; // write index in buffer

unsigned int capacity; // capacity of the buffer

unsigned int mask; // mask of the capacity

};

template

class RingBuffer

{

public:

RingBuffer(unsigned int bufCap = 0)

: buffer(NULL)

{

create(bufCap);

}

~RingBuffer()

{

destroy();

}

/**

* @brief create create one buffer

* @param bufCap buffer capacity

* @return return true if successful

*/

bool create(unsigned int bufCap)

{

if (bufCap == 0)

{

return false;

}

if (buffer != NULL)

{

delete buffer;

buffer = NULL;

}

unsigned int length = bufCap;

unsigned int n = 1;

while (length > n)

{

n *= 2;

if (n > MAX_ASK_FOR_CAP)

{

return false;

}

}

length = n;

buffer = new T[length];

bufferInfo.read = 0;

bufferInfo.write = 0;

bufferInfo.capacity = length;

bufferInfo.mask = bufferInfo.capacity – 1;

return true;

}

/**

* @brief push write one data of T type into the buffer

* @param data one data of T type

* @return return true if successful

*/

bool push(T data)

{

if (isFull() == true)

{

return false;

}

int num = memcpy((buffer + bufferInfo.write),reinterpret_cast(&data),sizeof(T));

if (num == sizeof(T))

{

bufferInfo.write += num;

return true;

}

return false;

}

/**

* @brief push write serival data of T type into the buffer

* @param data serival data of T type

* @param len length of data

* @return num of writing to buffer successfully

*/

unsigned int push(T *data,unsigned int len)

{

if (isFull() == true)

{

return 0;

}

unsigned int space = availableToWrite();

if (len > space)

{

len = space;

}

int num = memcpy((buffer + bufferInfo.write),reinterpret_cast(data),len * sizeof(T));

bufferInfo.write += len;

return num;

}

/**

* @brief pop remove oldest data of the buffer

* @param num num of the removed data

* @return num of the successful removed data

*/

unsigned int pop(unsigned int num)

{

if (isEmpty() == true)

{

return 0;

}

unsigned int count = availableToRead();

if (num < count)

{

bufferInfo.read += num;

return num;

}

bufferInfo.read = bufferInfo.write = 0;

return count;

}

/**

* @brief takeTail get oldest data of the buffer and remove it

* @return the data of T type

*/

T takeTail()

{

if (isEmpty() == true)

{

return;

}

T data = buffer[bufferInfo.read];

pop(1);

return data;

}

/**

* @brief read read some oldest data of the buffer and remove them

* @param buf read the data to this buf.

* @param len read length

* @return read legth successfully

*/

unsigned int read(T &buf,unsigned int len)

{

if (sizeof(buf) < len)

{

len = sizeof(buf);

}

unsigned int count = 0;

while (isEmpty() == false)

{

buf[count++] = this->buffer[bufferInfo.read];

pop(1);

if (count >= len)

{

break;

}

}

return count;

}

private:

/**

* @brief destroy destroy the buffer created

*/

void destroy()

{

if (buffer == NULL)

{

return;

}

delete buffer;

buffer = NULL;

}

/**

* @brief isFull if be full of the buffer

* @return return true if successful

*/

inline bool isFull() const

{

if (0 == availableToWrite())

{

return true;

}

return false;

}

/**

* @brief isEmpty if be empty of the buffer

* @return return true if successful

*/

inline bool isEmpty() const

{

if (0 == availableToRead())

{

return true;

}

return false;

}

/**

* @brief availableToRead available buffer to read

* @return num of available buffer to read

*/

inline unsigned int availableToRead() const

{

return (bufferInfo.write & bufferInfo.mask) – (bufferInfo.read & bufferInfo.mask);

}

/**

* @brief availableToWrite available buffer to write

* @return num of available buffer to write

*/

inline unsigned int availableToWrite() const

{

return bufferInfo.mask – bufferInfo.mask & bufferInfo.write;

}

T *buffer;

BufferInfo bufferInfo;

};

适用于小型数据量的通信缓冲区建立,例如嵌入式中usart、spi、iic、can等通信缓冲区。