//===============================================================
///@file RingBuffer.cpp
///@brief 环形缓冲区
///@detail 可以实现FIFO队列,FILO堆栈
///@version V1.0.0
///@author afei
///@data 2020.09.26
///@note 右向旋转的环形缓冲区要比左向旋转的环形缓冲区效率高
//===============================================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "RingBuffer.h"
//===============================================================
///@fn ST_RING_BUFFER *RINGBUF_Handle2Point(int hRing)
///@brief 将一个环形缓冲区句柄转换成指针
///@param [in] hRing 环形缓冲区句柄
///@param [out] 无
///@return 返回环形缓冲区指针
//===============================================================
ST_RING_BUFFER *RINGBUF_Handle2Point(int hRing)
{
return (ST_RING_BUFFER *)hRing;
}
//===============================================================================
///@fn int RINGBUF_Init(ST_RING_BUFFER *pRing, char *pBuf,
/// unsigned int itemSize, unsigned int itemCount)
///@brief 创建一个环形缓冲区
///@param [in] pRing 指向环形缓冲区
///@param [in] pBuf 指向缓冲区
///@param [in] itemSize 一个元素大小
///@param [in] itemCount 环形缓冲区包含元素的总个数
///@param [out] 无
///@return 返回环形缓冲区句柄,0代表初始化失败
///@note 环形缓冲区满时,存储的元素个数为itemCount-1
///@ref RINGBUF_Create使用动态内存创建环形缓冲区,可以使用RINGBUF_Desdroy销毁;
///RINGBUF_Init由外面定义环形缓冲区然后初始化, 禁止使用RINGBUF_Desdroy销毁
//===============================================================================
int RINGBUF_Init(ST_RING_BUFFER *pRing, char *pBuf,
unsigned int itemSize, unsigned int itemCount)
{
if(NULL == pRing || NULL == pBuf || 0 == itemSize || 0 == itemCount)
{
return 0;
}
pRing->itemCount = itemCount;
pRing->itemSize = itemSize;
pRing->pBuffer = pBuf;
pRing->left = 0;
pRing->right = 0;
return (int)pRing;
}
//===============================================================================
///@fn int RINGBUF_Create(unsigned int itemSize,
/// unsigned int itemCount)
///@brief 创建一个环形缓冲区
///@param [in] itemSize 一个元素大小
///@param [in] itemCount 环形缓冲区包含元素的总个数
///@param [out] 无
///@return 返回环形缓冲区句柄,0代表创建失败
///@note 环形缓冲区满时,存储的元素个数为itemCount-1
///@ref RINGBUF_Init由外面定义环形缓冲区然后初始化, 禁止使用RINGBUF_Desdroy销毁;
///RINGBUF_Create使用动态内存创建环形缓冲区,可以使用RINGBUF_Desdroy销毁。
//===============================================================================
int RINGBUF_Create(unsigned int itemSize, unsigned int itemCount)
{
ST_RING_BUFFER *p = NULL;
if(0 == itemSize || 0 == itemCount)
{
return 0;
}
p = (ST_RING_BUFFER *)malloc(sizeof(ST_RING_BUFFER));
if(NULL == p)
{
return 0;
}
p->pBuffer = (char *)malloc(itemSize*itemCount);
if(NULL == p->pBuffer)
{
free(p);
return 0;
}
p->itemSize = itemSize;
p->itemCount = itemCount;
p->left = 0;
p->right = 0;
return (int)p;
}
//===============================================================================
///@fn void RINGBUF_Desdroy(int *phRing)
///@brief 销毁一个环形缓冲区
///@param [in] phRing 指向环形缓冲区句柄
///@param [out] phRing 销毁后句柄会变为无效
///@return 无
//===============================================================================
void RINGBUF_Desdroy(int *phRing)
{
ST_RING_BUFFER *p = (ST_RING_BUFFER *)(*phRing);
if(NULL != p)
{
if(NULL != p->pBuffer)
{
free(p->pBuffer);
}
free(p);
}
*phRing = 0;
}
//===============================================================================
///@fn unsigned int RINGBUF_GetItemSize(int hRing)
///@brief 获取环形缓冲区一个元素占用的字节数
///@param [in] hRing 环形缓冲区句柄
///@param [out] 无
///@return 环形缓冲区元一个元素占用的字节数
//===============================================================================
unsigned int RINGBUF_GetItemSize(int hRing)
{
ST_RING_BUFFER *p = (ST_RING_BUFFER *)hRing;
assert(NULL != p);
return p->itemSize;
}
//===============================================================================
///@fn unsigned int RINGBUF_GetCount(int hRing)
///@brief 获取环形缓冲区容量的元素个数
///@param [in] hRing 环形缓冲区句柄
///@param [out] 无
///@return 环形缓冲区元容量的素个数
//===============================================================================
unsigned int RINGBUF_GetCount(int hRing)
{
ST_RING_BUFFER *p = (ST_RING_BUFFER *)hRing;
assert(NULL != p);
return p->itemCount;
}
//===============================================================================
///@fn int RINGBUF_IsEmpty(int hRing)
///@brief 判断环形缓冲区是否为空
///@param [in] hRing 环形缓冲区句柄
///@param [out] 无
///@return 1-为空,0-不为空
//===============================================================================
int RINGBUF_IsEmpty(int hRing)
{
ST_RING_BUFFER *p = (ST_RING_BUFFER *)hRing;
assert(NULL != p);
return (p->right == p->left);
}
//===============================================================================
///@fn int RINGBUF_IsFull(int hRing)
///@brief 判断环形缓冲区是否为满
///@param [in] hRing 环形缓冲区句柄
///@param [out] 无
///@return 1-为满,0-不为满
//===============================================================================
int RINGBUF_IsFull(int hRing)
{
ST_RING_BUFFER *p = (ST_RING_BUFFER *)hRing;
assert(NULL != p);
return (p->left == ((p->right + 1)%p->itemCount));
}
//===============================================================================
///@fn unsigned int RINGBUF_GetUsed(int hRing)
///@brief 获取环形缓冲区已使用元素个数
///@param [in] hRing 环形缓冲区句柄
///@param [out] 无
///@return 已使用元素个数
//===============================================================================
unsigned int RINGBUF_GetUsed(int hRing)
{
ST_RING_BUFFER *p = (ST_RING_BUFFER *)hRing;
assert(NULL != p);
return ((p->right - p->left + p->itemCount)%p->itemCount);
}
//===============================================================================
///@fn unsigned int RINGBUF_GetFree(int hRing)
///@brief 获取环形缓冲区未使用元素个数
///@param [in] hRing 环形缓冲区句柄
///@param [out] 无
///@return 未使用元素个数
//===============================================================================
unsigned int RINGBUF_GetFree(int hRing)
{
ST_RING_BUFFER *p = (ST_RING_BUFFER *)hRing;
assert(NULL != p);
return (p->left - p->right + p->itemCount - 1)%p->itemCount;
}
//===============================================================================
///@fn int RINGBUF_PushRight(int hRing, void *pItem)
///@brief 向环形缓冲区的右侧存一个元素
///@param [in] hRing 环形缓冲区句柄
///@param [in] pItem 指向插入的元素
///@param [out] 无
///@return 1-成功,0-失败
//===============================================================================
int RINGBUF_PushRight(int hRing, void *pItem)
{
ST_RING_BUFFER *p = (ST_RING_BU