⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ringbuffer.c

📁 ts流的解复用
💻 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 + -