📄 ringbuffer.c
字号:
#include "ringbuffer.h"#define PKT_READY 0#define PKT_DISPOSED 1void rb_init(struct ringbuffer_s *rbuf, void *data, int len){ rbuf->data = data; rbuf->size = len; rbuf->ptr_r = rbuf->ptr_w = 0; rbuf->error = 0; rbuf->pre_r = rbuf->ptr_r;}//填充初始化,将一个缓冲初始化为一个循环缓冲void rb_fill_init(struct ringbuffer_s *rbuf, void *data, int len){ rbuf->data = data; rbuf->size = len; rbuf->ptr_r = 0; rbuf->ptr_w = len-1; rbuf->error = 0; rbuf->pre_r = rbuf->ptr_r;}int rb_empty(struct ringbuffer_s *rbuf){ return (rbuf->ptr_r == rbuf->ptr_w);}int rb_free(struct ringbuffer_s *rbuf){ int free; free = rbuf->ptr_r - rbuf->ptr_w; if(free <= 0) free += rbuf->size; return free - 1;}int rb_avail(struct ringbuffer_s *rbuf){ int avail; avail = rbuf->ptr_w - rbuf->ptr_r; if(avail < 0) avail += rbuf->size; return avail;}void rb_flush(struct ringbuffer_s *rbuf){ rbuf->ptr_r = rbuf->ptr_w; rbuf->pre_r = rbuf->ptr_r; rbuf->error = 0;}int rb_read(struct ringbuffer_s *rbuf, u8 *buf, int len){ int todo = len; int split; //记录前一次读指针 rbuf->pre_r = rbuf->ptr_r; split = (rbuf->ptr_r + len > rbuf->size) ? rbuf->size - rbuf->ptr_r : 0; if(split > 0) { memcpy(buf, rbuf->data+rbuf->ptr_r, split); buf += split; todo -= split; rbuf->ptr_r = 0; } memcpy(buf, rbuf->data+rbuf->ptr_r, todo); rbuf->ptr_r = (rbuf->ptr_r + todo) % rbuf->size; return len;}int rb_write(struct ringbuffer_s *rbuf, const u8 *buf, int len){ int todo = len; int split; split = (rbuf->ptr_w + len > rbuf->size) ? rbuf->size - rbuf->ptr_w : 0; if (split > 0) { memcpy(rbuf->data+rbuf->ptr_w, buf, split); buf += split; todo -= split; rbuf->ptr_w = 0; } memcpy(rbuf->data+rbuf->ptr_w, buf, todo); rbuf->ptr_w = (rbuf->ptr_w + todo) % rbuf->size; return len;}//从文件读数据填充到rb里int rb_fill(struct ringbuffer_s *rbuf, FILE *fp, int len){ int todo = len; int split; int size; split = (rbuf->ptr_w + len > rbuf->size) ? rbuf->size - rbuf->ptr_w : 0; if (split > 0) { size = fread(rbuf->data+rbuf->ptr_w, split, 1, fp); if(size <= 0) return 0; todo -= split; rbuf->ptr_w = 0; } size = fread(rbuf->data+rbuf->ptr_w, todo, 1, fp); if(size <= 0) return 0; rbuf->ptr_w = (rbuf->ptr_w + todo) % rbuf->size; return len;}//读指针回退void rb_backspace(struct ringbuffer_s *s, int offset){ s->ptr_r = s->pre_r;}int rb_pkt_write(struct ringbuffer_s *rbuf, u8* buf, int len){ int status; int oldptr_w = rbuf->ptr_w; RB_WRITE_BYTE(rbuf, len >> 8); RB_WRITE_BYTE(rbuf, len & 0xff); RB_WRITE_BYTE(rbuf, PKT_READY); status = rb_write(rbuf, buf, len); if (status < 0) rbuf->ptr_w = oldptr_w; return status;}int rb_pkt_read(struct ringbuffer_s *rbuf, int idx, int offset, u8* buf, int len){ int todo; int split; int pktlen; pktlen = rbuf->data[idx] << 8; pktlen |= rbuf->data[(idx + 1) % rbuf->size]; if (offset > pktlen) return -1; if ((offset + len) > pktlen) len = pktlen - offset; idx = (idx + RB_PKTHDRSIZE + offset) % rbuf->size; todo = len; split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; if (split > 0) { memcpy(buf, rbuf->data+idx, split); buf += split; todo -= split; idx = 0; } memcpy(buf, rbuf->data+idx, todo); return len;}void rb_pkt_dispose(struct ringbuffer_s *rbuf, int idx){ int pktlen; rbuf->data[(idx + 2) % rbuf->size] = PKT_DISPOSED; // clean up disposed packets while(rb_avail(rbuf) > RB_PKTHDRSIZE) { if (RB_PEEK(rbuf, 2) == PKT_DISPOSED) { pktlen = RB_PEEK(rbuf, 0) << 8; pktlen |= RB_PEEK(rbuf, 1); RB_SKIP(rbuf, pktlen + RB_PKTHDRSIZE); } else { // first packet is not disposed, so we stop cleaning now break; } }}int rb_pkt_next(struct ringbuffer_s *rbuf, int idx, int* pktlen){ int consumed; int curpktlen; int curpktstatus; if (idx == -1) { idx = rbuf->ptr_r; } else { curpktlen = rbuf->data[idx] << 8; curpktlen |= rbuf->data[(idx + 1) % rbuf->size]; idx = (idx + curpktlen + RB_PKTHDRSIZE) % rbuf->size; } consumed = (idx - rbuf->ptr_r) % rbuf->size; while((rb_avail(rbuf) - consumed) > RB_PKTHDRSIZE) { curpktlen = rbuf->data[idx] << 8; curpktlen |= rbuf->data[(idx + 1) % rbuf->size]; curpktstatus = rbuf->data[(idx + 2) % rbuf->size]; if (curpktstatus == PKT_READY) { *pktlen = curpktlen; return idx; } consumed += curpktlen + RB_PKTHDRSIZE; idx = (idx + curpktlen + RB_PKTHDRSIZE) % rbuf->size; } // no packets available return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -