环形缓冲区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 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 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等通信缓冲区。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |