You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
2.3 KiB
C

#include <stdint.h>
#include <string.h>
#define cb_item_t uint8_t // item type
#define CB_ITEM_N 1024 // item number实际可存入数据少一个留一个空位表示满以区别于空
typedef struct
{
cb_item_t buf[CB_ITEM_N];
int wrptr; // 写指针
int rdptr; // 读指针
} CircleBuffer_t;
/* Element Count in buffer */
static int CirBuf_Count(CircleBuffer_t *cirbuf)
{
return (cirbuf->wrptr - cirbuf->rdptr) & (CB_ITEM_N - 1);
}
/* Space available in buffer */
static int CirBuf_Space(CircleBuffer_t *cirbuf)
{
return (cirbuf->rdptr - cirbuf->wrptr - 1) & (CB_ITEM_N - 1);
}
static int CirBuf_Empty(CircleBuffer_t *cirbuf)
{
return CirBuf_Count(cirbuf) == 0;
}
static int CirBuf_Full(CircleBuffer_t *cirbuf)
{
return CirBuf_Space(cirbuf) == 0;
}
static void CirBuf_Clear(CircleBuffer_t *cirbuf)
{
cirbuf->rdptr = cirbuf->wrptr;
}
static int CirBuf_Write(CircleBuffer_t *cirbuf, cb_item_t *buf, int num)
{
int n;
if(cirbuf->wrptr >= cirbuf->rdptr)
{
n = CB_ITEM_N - cirbuf->wrptr;
if(cirbuf->rdptr == 0)
n -= 1;
n = (n >= num) ? num : n;
memcpy(&cirbuf->buf[cirbuf->wrptr], buf, n * sizeof(cb_item_t));
cirbuf->wrptr = (cirbuf->wrptr + n) % CB_ITEM_N;
if((n == num) || CirBuf_Full(cirbuf))
return n;
else
return n + CirBuf_Write(cirbuf, &buf[n], num - n);
}
else
{
n = CirBuf_Space(cirbuf);
n = (n >= num) ? num : n;
memcpy(&cirbuf->buf[cirbuf->wrptr], buf, n * sizeof(cb_item_t));
cirbuf->wrptr += n;
return n;
}
}
static int CirBuf_Read(CircleBuffer_t *cirbuf, cb_item_t *buf, int num)
{
int n;
if(cirbuf->wrptr >= cirbuf->rdptr)
{
n = CirBuf_Count(cirbuf);
n = (n >= num) ? num : n;
memcpy(buf, &cirbuf->buf[cirbuf->rdptr], n * sizeof(cb_item_t));
cirbuf->rdptr += n;
return n;
}
else
{
n = CB_ITEM_N - cirbuf->rdptr;
n = (n >= num) ? num : n;
memcpy(buf, &cirbuf->buf[cirbuf->rdptr], n * sizeof(cb_item_t));
cirbuf->rdptr = (cirbuf->rdptr + n) % CB_ITEM_N;
if((n == num) || CirBuf_Empty(cirbuf))
return n;
else
return n + CirBuf_Read(cirbuf, &buf[n], num - n);
}
}