#include    "gen_queue.h"
#include    "string.h"
#include "platform.h"
/*
* 通用环形队列函数:init;in;out;
* 1, 为了确保队列的通用性，将存储的数据抽象出来为 void *;
* 2, 由于抽象出来的数据的不确定性，导致gen_queue_in,gen_queue_out函数中查找数据都只能根据data_len计算得出，无法用数组形式开始查找。
* 3,由于定义环形队列时就已经初始化了，所以无需开放初始化函数;
* 4, data_len可以理解为一维数组的空间大小;同理也可以是一个用户结构体的空间;
* 5，使用实例： GEN_CIRCLE_QUEUE_DEF(transtopc,10,64); 
    a,意思是用户定义了一个深度10宽度64的环形队列transtopc;(即64字节的数组最多可以存储10组)
    b,定义了transtopc_buf[10][64]的数组;（类似malloc功能）
    c,定义了一个环形队列transtopc，同时初始化数据指针指向transtopc_buf和其他参数;
    d,封装了队列读写函数: transtopc__in(void **data); transtopc__out(void** data); (用户调用方便)
		e,使用名字拼接函数CONCAT_2可生成每个队列对应的函数名称;
GEN_CIRCLE_QUEUE_DEF(transtopc,10,64); 

void gen_circle_queue_test(void)
{
    unsigned char test_data[64];
    if(transtopc__in(test_data) >= 0 ){
        //存储成功
    }
    if( transtopc__out(test_data) >= 0){
        //读取成功
    }
}	
*/
//#include "platform_extern.h"

 /*
 队列初始化*/
 void gen_queue_init(GenCircleQueue *queue,GEN_QUEUE_DATA_TYPE **data)	
 {	
 	queue->pdata = data;
 	queue->front = queue->rear;
 	queue->count =0;
 }

/*
* 将数据存储到队列尾部
* return:
    -1: 队列已满，存储失败;
    否则返回操作后队列中元素的个数;
*/
signed short gen_queue_in(GenCircleQueue * const queue,const GEN_QUEUE_DATA_TYPE* data)	
{
	signed short retval;
    PLATFORM_DISABLE_IRQ();
    
	if( (queue->front ==queue->rear)&&(queue->count >= queue->node_size ) )
		retval = -1;
	else{
		//memcpy(queue->pdata[queue->rear] ,data, queue->data_len);
     memcpy((GEN_QUEUE_DATA_TYPE*)(queue->pdata) + queue->rear*queue->data_len,data, queue->data_len);
		queue->rear = (queue->rear +1)% queue->node_size;
		queue->count += 1;
		retval = queue->count;
	}
	PLATFORM_ENABLE_IRQ();
	return retval;
}


/*
* 从队列头读取数据，并且删除
* return:
    -1: 队列已满，存储失败;
    否则返回操作后队列中元素的个数;
*/
signed short gen_queue_out(GenCircleQueue *const queue,GEN_QUEUE_DATA_TYPE* data)	
{	
	signed short retval;
	PLATFORM_DISABLE_IRQ();
	if( (queue->front ==queue->rear)&&(queue->count == 0) )
		retval= -1;
	else{
		//memcpy(data,queue->pdata[queue->front],queue->data_len);
		memcpy(data, (GEN_QUEUE_DATA_TYPE*)(queue->pdata) + queue->front*queue->data_len,queue->data_len);
		queue->front = (queue->front +1)% queue->node_size;
		queue->count -= 1;
		retval= queue->count;
	}	
	PLATFORM_ENABLE_IRQ();
	return retval;
}

//
unsigned short gen_queue_get_len(GenCircleQueue *const queue)	
{
	return queue->count;
}

unsigned char* gen_queue_get_ele(GenCircleQueue *const queue,unsigned short i)
{
	unsigned short offset = (queue->front +i)% queue->node_size;
	return (GEN_QUEUE_DATA_TYPE*)(queue->pdata) + offset*queue->data_len ;
	//memcpy(data, ,queue->data_len);
}

//---------------------------------------------------------------------------------------


//GEN_CIRCLE_QUEUE_DEF(test_fifo,100,64);


