my_ringbuff.c 4.5 KB
#include "my_ringbuff.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"


/*环形缓冲区初始化函数*/
/*不使用全局变量,将环形缓冲区结构体返回*/
ringBuf_t *ringBufInit(ringBuf_t* ringBuffer,int size)
{
	ringBuffer = (ringBuf_t*)malloc(sizeof(ringBuf_t));
	if(NULL == ringBuffer)
	{
		printf("ringBuffer malloc error!\n");
		return NULL;
	}
	memset(ringBuffer,0,sizeof(ringBuf_t));
	
	ringBuffer->buffer = (char*)malloc(size);
	memset(ringBuffer->buffer,0,size);
	
	ringBuffer->size   = size;
	ringBuffer->pRead  = 0;
	ringBuffer->pWrite = 0;

	return ringBuffer;
}


/*从环形缓冲区读数据*/
int ringBufRead(ringBuf_t *ringBuffer,char *readBuf,int readLength)
{
//	int pre  = 0;	//记录read指针到缓冲区尾端数据长度
//	int last = 0;	//记录剩余数据长度,也就是缓冲区头部的部分数据
	int dataLen = 0;
	
	if(NULL == ringBuffer)
	{
//		printf("ringBuffer is NULL,ringBuffer init error!\n");
		return(-1);
	}
	if(NULL == readBuf)
	{
//		printf("readBuf is NULL,readBuf init error!\n");
		return(-1);
	}

	/*readLength超出缓冲区大小*/
	/*可设置只读有效数据或直接报错*/
	/*后续设计有效数据记录变量,防止读重复,同时也解决了readLength超缓冲区的问题*/
	if(readLength > ringBuffer->size)
	{
//		printf("readLength is too long! readlen = %d  lenth = %d\n",readLength,ringBuffer->size);
		return(-1);
	}
//
	//获取缓存区中的有效数据大小
	dataLen = ringBufDataLen(ringBuffer);
	
	//当缓存区为空时,退出
	if(dataLen==0)
		return -1;
	
	//当要读取值超过有效数据值,更新读取值
	if(dataLen<readLength)
	{
//		printf("valid data is short than readlen\r\n");
		readLength = dataLen;
	}
//	
	
	if(readLength+ringBuffer->pRead <= ringBuffer->size)
	{
		/*readLength + pRead < size,要读的数据没有到达尾部*/
		memcpy(readBuf,ringBuffer->buffer+ringBuffer->pRead,readLength);
	}else
	{
		/*readLength + pRead > size,一部分数据在尾端,一部分在头端*/
		int pre  = ringBuffer->size - ringBuffer->pRead;
		int last = readLength - pre;
		memcpy(readBuf,ringBuffer->buffer+ringBuffer->pRead,pre);
		memcpy(readBuf+pre,ringBuffer->buffer,last); 
	}

	/*移动pRead指针*/
	ringBuffer->pRead = (ringBuffer->pRead + readLength) % (ringBuffer->size);
		
	return readLength;	//后续要返回读有效数据长度
}

static uint8_t writeFlag = 0;


/*往环形缓冲区写数据*/
int ringBufWrite(ringBuf_t *ringBuffer,char *writeBuf,int writeLength)
{
//    int pre  = 0;   //记录write指针到缓冲区尾端长度
//    int last = 0;   //记录剩余所需空间,也就是要往缓冲区头部写的部分空间
	
    if(NULL == ringBuffer)
    {
//        printf("ringBuffer is NULL,ringBuffer init error!\n");
        return(-1);
    }
    if(NULL == writeBuf)
    {
//        printf("writeBuf is NULL,writeBuf init error!\n");
        return (-1);
    }

    /*writeLength超出缓冲区大小*/
    /*可设置只写有效空间或直接报错*/
	/*后续设计有效数据记录变量,防止写覆盖,同时也解决了writeLength超缓冲区的问题*/
    if(writeLength > ringBuffer->size)
    {
//        printf("writeLength is too long!\n");
        return(-1);
    }

    if(writeLength+ringBuffer->pWrite <= ringBuffer->size)
    {
        /*writeLength + pWrite < size	写空间足够,不用回到头部*/
        memcpy(ringBuffer->buffer+ringBuffer->pWrite,writeBuf,writeLength);
    }else
    {
        /*writeLength + pRead > size	一部分数据写在尾部,一部分数据写在头部*/
        int pre  = ringBuffer->size - ringBuffer->pWrite;
        int last = writeLength - pre;
        memcpy(ringBuffer->buffer+ringBuffer->pWrite,writeBuf,pre);
        memcpy(ringBuffer->buffer,writeBuf+pre,last);
    }
	
    /*移动pWrite指针*/
    ringBuffer->pWrite = (ringBuffer->pWrite + writeLength) % (ringBuffer->size);
		
    return writeLength;	//后续要返回写有效数据长度
}



/*计算环形缓冲区数据长度*/
/*write指针可能在read指针前,也可能在read指针后*/

int ringBufDataLen(ringBuf_t *ringBuffer)
{
	int dataLen = 0;

	if(NULL == ringBuffer)
	{
//		printf("ringBuffer is NULL!\n");
		return NULL;
	}

	//
	if(ringBuffer->pWrite >= ringBuffer->pRead)
	{
		return (ringBuffer->pWrite - ringBuffer->pRead);
	}else
	{
		return (ringBuffer->size - ringBuffer->pRead + ringBuffer->pWrite);
	}
}


/*释放环形缓冲区*/
void ringBufFree(ringBuf_t *ringBuffer)
{
	if(NULL == ringBuffer)
	{
//		printf("ringBuffer is NULL!\n");
		
	}
	if(ringBuffer->buffer != NULL)
	{
		free(ringBuffer->buffer);
		ringBuffer->buffer =NULL;
	}
	free(ringBuffer);
	ringBuffer = NULL;
}



/*环形缓存区复位*/
void ringBufReset(ringBuf_t *ringBuffer,uint16_t size)
{
	if(NULL == ringBuffer)
	{
		
	}
	if(ringBuffer->buffer!=NULL)
	{
		memset(ringBuffer->buffer,0,size);
	
		ringBuffer->size   = size;
		ringBuffer->pRead  = 0;
		ringBuffer->pWrite = 0;
	}
}