循环队列(数组)

1、模型
循环队列(数组)_第1张图片
2、代码实现

typedef struct {
	uint32_t         bufsize;             	/* round buffer size */
	uint32_t         used;             	/* round buffer used */
	uint8_t          *bptr;               	/* begin position */
	uint8_t          *eptr;               	/* end position */
	uint8_t          *wptr;               	/* write position */
	uint8_t          *rptr;               	/* read position */
} RoundBuf_t;

static void roundbuf_update_used(RoundBuf_t *round);
/*******************************************************************
** 函数名:     roundbuf_init
** 函数描述:   初始化循环缓冲区
** 参数:       [in]  round:           循环缓冲区
**             [in]  mem:             循环缓冲区所管理的内存地址
**             [in]  memsize:         循环缓冲区所管理的内存字节数
**             [in]  rule:            循环缓冲区数据读取是的解码规则
** 返回:       实际可用长度为数组长度-1,防止写入指针追上读取指针
********************************************************************/
void roundbuf_init(RoundBuf_t *round, uint8_t *mem, uint32_t memsize)
{
	round->bufsize = memsize-1;
	round->used    = 0;
	round->bptr    = mem;
	round->eptr    = mem + round->bufsize;
	round->wptr = round->rptr = round->bptr;
}

/*******************************************************************
** 函数名:     roundbuf_reset
** 函数描述:   复位循环缓冲区, 即将循环缓冲区的已使用字节数清0
** 参数:       [in]  round:           循环缓冲区
** 返回:       无
********************************************************************/
void roundbuf_reset(RoundBuf_t *round)
{
	round->used = 0;
	round->rptr = round->wptr = round->bptr;
}

/*******************************************************************
** 函数名:     roundbuf_get_start_pos
** 函数描述:   获取循环缓冲区所管理内存的起始指针
** 参数:       [in]  round:           循环缓冲区
** 返回:       所管理内存的起始指针
********************************************************************/
uint8_t *roundbuf_get_start_pos(RoundBuf_t *round)
{
	return round->bptr;
}

/*******************************************************************
** 函数名:     roundbuf_write_byte
** 函数描述:   往循环缓冲区中写入一个字节的数据
** 参数:       [in]  round:           循环缓冲区
**             [in]  data:              待写入的数据
** 返回:       如写之前循环缓冲区中的使用字节数达到所管理内存的字节数, 
**             则返回失败; 否则, 返回成功
********************************************************************/
bool roundbuf_write_byte(RoundBuf_t *round, uint8_t data)
{
	if( NULL == round ) 
		return false;
	if( round->used >= round->bufsize ) 
		return false;
	*round->wptr = data;
	if( round->wptr >= round->eptr )
	{
		round->wptr = round->bptr;
	}
	else
	{
		round->wptr++;
	}
	//更新缓存区已经使用的数量
	roundbuf_update_used(round);
	return true;
}

/*******************************************************************
** 函数名:     roundbuf_read_byte
** 函数描述:   从循环缓冲区中读取一个字节的数据
** 参数:       [in]  round:           循环缓冲区
** 返回:       如读之前循环缓冲区中的使用字节数为0, 则返回-1;
**             否则, 返回读取到的字节
********************************************************************/
int32_t roundbuf_read_byte(RoundBuf_t *round)
{
	int32_t ret;
	//获取当前数组使用情况
	if (round->used == 0)
		return -1;
	ret = *round->rptr;
	if (round->rptr >= round->eptr)
	{
		round->rptr = round->bptr;
	}
	else
	{
		round->rptr++;
	}
	//更新缓存区已经使用的数量
	roundbuf_update_used(round);
	return ret;
}

/*******************************************************************
** 函数名:     roundbuf_read_data
** 函数描述:   读循环缓冲区指定长度
** 参数:       [in]  round:           循环缓冲区
**             [out] pdata:           要读数据块的指针
**             [in]  datalen:         要读数据块的字节数
** 返回:       实际读出数据长度
********************************************************************/
int32_t roundbuf_read_data(RoundBuf_t *round, uint8_t *pdata, uint32_t datalen)
{
	uint32_t i, readlen;
	uint32_t used = round->used;
	if( used <= datalen )
	{
		readlen = used;
	}
	else
	{
		readlen = datalen;
	}

	for ( i = 0; i < readlen; i++ )
	{
		pdata[i] = *round->rptr;
		if (round->rptr >= round->eptr)
		{
			round->rptr = round->bptr;
		}
		else
		{
			round->rptr++;
		}
	}
	//更新缓存区已经使用的数量
	roundbuf_update_used(round);
	
	return readlen;
}

/*******************************************************************
** 函数名:     roundbuf_read_byte_no_move_ptr
** 函数描述:   再不移动缓冲区指针的情况下,从循环缓冲区中读取一个字节的数据
** 参数:       [in]  round:           循环缓冲区
** 返回:       剩余的可用字节数
********************************************************************/
int32_t roundbuf_read_byte_no_move_ptr(RoundBuf_t *round)
{
	if (round->used == 0)
		return -1;
	else 
		return *round->rptr; 
}

/*******************************************************************
** 函数名:     roundbuf_get_left
** 函数描述:   获取循环缓冲区中剩余的可用字节数
** 参数:       [in]  round:           循环缓冲区
** 返回:       剩余的可用字节数
********************************************************************/
uint32_t roundbuf_get_left(RoundBuf_t *round)
{
	return (round->bufsize - round->used);
}
/*******************************************************************
** 函数名:     roundbuf_update_used
** 函数描述:   更新循环缓冲区中已使用字节数
** 参数:       [in]  round:           循环缓冲区
** 返回: 	   无
********************************************************************/
static void roundbuf_update_used(RoundBuf_t *round)
{
	if( (round->wptr) == (round->rptr) )
		round->used = 0;
	else if( (round->wptr) > (round->rptr) )
		round->used = (round->wptr) - (round->rptr);
	else //if( (round->wptr) < (round->rptr) )
		round->used = ( (round->eptr) - (round->rptr) ) + ( (round->wptr) - (round->bptr) ) + 1 ;
}
/*******************************************************************
** 函数名:     roundbuf_get_used
** 函数描述:   获取循环缓冲区中已使用字节数
** 参数:       [in]  round:           循环缓冲区
** 返回:       已使用的字节数
********************************************************************/
uint32_t roundbuf_get_used(RoundBuf_t *round)
{
	return round->used;
}

/*******************************************************************
** 函数名:     roundbuf_write_block
** 函数描述:   往循环缓冲区中写入一块数据单元
** 参数:       [in]  round:           循环缓冲区
**             [in]  bptr:            待写入数据块的指针
**             [in]  blksize:         待写入数据块的字节数
** 返回:       成功写入循环缓冲区的字节数
********************************************************************/
bool roundbuf_write_block(RoundBuf_t *round, uint8_t *bptr, uint32_t blksize)
{
	if(blksize > roundbuf_get_left(round))
		return false;
	for(; blksize > 0; blksize--)
	{ 
		*round->wptr = *bptr++;
		if( round->wptr >= round->eptr )
		{
			round->wptr = round->bptr;
		}
		else
		{
			round->wptr++;
		}
	}    
	//更新缓存区已经使用的数量
	roundbuf_update_used(round);
	return true;
}


你可能感兴趣的:(编程相关)