RingBuffer

ringbuffer.h

#ifndef __RINGBUFFER_H__
#define __RINGBUFFER_H__

#if defined(__cplusplus)
extern "C" {
#endif

#define BUFFER_OVERFLOW (-1)

typedef struct {
    unsigned char *buffer;
    unsigned int size;
    unsigned int fill;
    unsigned char *read;
    unsigned char *write;
} RINGBUFFER_T;

int ringbuffer_empty(RINGBUFFER_T *rb);

int ringbuffer_full(RINGBUFFER_T *rb);

int ringbuffer_read(RINGBUFFER_T *rb, unsigned char* buf, unsigned int len);
int ringbuffer_write(RINGBUFFER_T *rb, unsigned char* buf, unsigned int len);

void ringbuffer_release(RINGBUFFER_T *rb);
int ringbuffer_init(RINGBUFFER_T **rb, unsigned ringbuffer_size);
unsigned int ringbuffer_get_fillsize(RINGBUFFER_T *rb);

#if defined(__cplusplus)
}
#endif

#endif

 

ringbuffer.c

/* Ring buffer implementation */
#include "ringbuffer.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>

int ringbuffer_empty(RINGBUFFER_T *rb)
{
	/* It's empty when the read and write pointers are the same. */
	if (0 == rb->fill) {
		return 1;
	}else {
		return 0;
	}
}

int ringbuffer_full(RINGBUFFER_T *rb)
{
	/* It's full when the write ponter is 1 element before the read pointer*/
	if (rb->size == rb->fill) {
		return 1;
	}else {
		return 0;
	}
}

int ringbuffer_read(RINGBUFFER_T *rb, unsigned char* buf, unsigned int len)
{
	assert(len>0);
	if (rb->fill >= len) {
		// in one direction, there is enough data for retrieving
		if (rb->write > rb->read) {
			memcpy(buf, rb->read, len);
			rb->read += len;
		}else if (rb->write < rb->read) {
			int len1 = rb->buffer + rb->size - 1 - rb->read + 1;
			if (len1 >= len) {
				memcpy(buf, rb->read, len);
				rb->read += len;
			} else {
				int len2 = len - len1;
				memcpy(buf, rb->read, len1);
				memcpy(buf + len1, rb->buffer, len2);
				rb->read = rb->buffer + len2; // Wrap around
			}
		}
		rb-> fill -= len;
		return len;
	} else	{
		return 0;
	}
}

int ringbuffer_write(RINGBUFFER_T *rb, unsigned char* buf, unsigned int len)
{
	assert(len > 0);
	if (rb->size - rb->fill < len) {
		return 0;
	}
	else {
		if (rb->write >= rb->read) {
			int len1 = rb->buffer + rb->size - rb->write;
			if (len1 >= len) {
				memcpy(rb->write, buf, len);
				rb->write += len;
			} else {
				int len2 = len - len1;
				memcpy(rb->write, buf, len1);
				memcpy(rb->buffer, buf+len1, len2);
				rb->write = rb->buffer + len2; // Wrap around
			}
		} else {
			memcpy(rb->write, buf, len);
			rb->write += len;
		}
		rb->fill += len;
		return len;
	}
}

unsigned int ringbuffer_get_fillsize(RINGBUFFER_T *rb)
{
    return rb->fill;
}

void ringbuffer_release(RINGBUFFER_T *rb)
{
    if ( NULL != rb )
    {
        if ( NULL != rb->buffer )
        {
            free(rb->buffer);
        }
        free(rb);
    }
}

int ringbuffer_init(RINGBUFFER_T **rb, unsigned ringbuffer_size)
{
		*rb = (RINGBUFFER_T *)malloc(sizeof(RINGBUFFER_T));
        if ( NULL == *rb )
        {
            return -1;
        }
        memset(*rb, 0, sizeof(RINGBUFFER_T));
        (*rb)->buffer = (unsigned char *)malloc(ringbuffer_size);
        if ( NULL == (*rb)->buffer )
        {
            free(*rb);
            return -1;
        }
        memset((*rb)->buffer, 0, ringbuffer_size);
        (*rb)->size = ringbuffer_size;
        (*rb)->fill = 0;
        (*rb)->read = (*rb)->buffer;
        (*rb)->write = (*rb)->buffer;
        return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值