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

#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;

};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值