|
一直想实现一个可以支持任意数据类型的队列,好更好的优化现有的只支持的unsigned char *类型的队列,恨死的它的限制了。
今天终于实现了。哇咔咔,和大家分享一下。借鉴了一下rt_thread的dq。大家共同学习。基础功能实现了,检错之类的还没完善,
想用的朋友可以自己完善一下,也希望有朋友有更宝贵的意见,可以更一步的优化这个队列。
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#define RT_EOK 0 /**< There is no error */
#define RT_ERROR 1 /**< A generic error happens */
#define RT_ETIMEOUT 2 /**< Timed out */
#define RT_EFULL 3 /**< The resource is full */
#define RT_EEMPTY 4 /**< The resource is empty */
#define RT_ENOMEM 5 /**< No memory */
#define RT_ENOSYS 6 /**< No system */
#define RT_EBUSY 7 /**< Busy */
#define RT_EIO 8 /**< IO error */
#define RT_NULL (0)
struct rt_data_item
{
unsigned char *data_ptr;
unsigned int data_size;
};
#define DATAQUEUE_EVENT_UNKNOWN 0x00
#define DATAQUEUE_EVENT_POP 0x01
#define DATAQUEUE_EVENT_PUSH 0x02
#define DATAQUEUE_EVENT_LWM 0x03
/* data queue implementation */
struct data_queue
{
unsigned int size;
unsigned int get_index;
unsigned int put_index;
struct rt_data_item queue;
/* event notify */
void (*evt_notify)(struct data_queue *queue, unsigned int event);
};
void evt_notify(struct data_queue *queue, unsigned int event)
{
printf("Event = %d\r\n",event);
}
unsigned int data_queue_init(struct data_queue *queue,
unsigned int size,
unsigned int type_size,
void (*evt_notify)(struct data_queue *queue, unsigned int event))
{
queue->evt_notify = evt_notify;
queue->size = size;
queue->get_index = 0;
queue->put_index = 0;
queue->queue.data_size = type_size;
queue->queue.data_ptr = (unsigned char *)malloc(sizeof(unsigned char ) * size * type_size);
if (queue->queue.data_ptr == RT_NULL)
{
return -RT_ENOMEM;
}
return RT_EOK;
}
bool data_queue_full(struct data_queue *queue)
{
if(queue->get_index == (queue->put_index + 1)%queue->size) //判断循环链表是否满,留一个预留空间不用
return true;
else
return false;
}
bool data_queue_empty(struct data_queue *queue)
{
if(queue->put_index == queue->get_index) //判断是否为空
return true;
else
return false;
}
unsigned int rt_data_queue_push(struct data_queue *queue,
void *data_ptr)
{
unsigned int mask;
unsigned int result;
result = RT_EOK;
if(data_queue_full(queue))
{
printf("full\r\n");
return false;
}
else
{
memcpy((queue->queue.data_ptr+queue->put_index*queue->queue.data_size),(unsigned char *)data_ptr,queue->queue.data_size);
queue->put_index = (queue->put_index + 1)%queue->size;
if (queue->evt_notify != RT_NULL)
{
queue->evt_notify(queue, DATAQUEUE_EVENT_PUSH);
}
return true;
}
return result;
}
unsigned int rt_data_queue_pop(struct data_queue *queue,
void* data_ptr)
{
unsigned int result;
unsigned int mask;
result = RT_EOK;
if(data_queue_empty(queue))
{
printf("empty\r\n");
return false;
}
else
{
memcpy(data_ptr,queue->queue.data_ptr+queue->get_index*queue->queue.data_size,queue->queue.data_size);
queue->get_index = (queue->get_index + 1)%queue->size;
if (queue->evt_notify != RT_NULL)
{
queue->evt_notify(queue, DATAQUEUE_EVENT_POP);
}
return true;
}
return result;
}
void rt_data_queue_reset(struct data_queue *queue)
{
}
struct Student{
char name[10];
unsigned char age;
};
int main(int argc, char* argv[])
{
unsigned int size;
#if 1
{
data_queue intque;
int value = 7777;
int valueTemp;
data_queue_init(&intque,3,sizeof(int),evt_notify);
rt_data_queue_push(&intque,&value);
rt_data_queue_pop(&intque,&valueTemp);
printf("valueTemp = %d\r\n",valueTemp);
}
#endif
#if 1
{
data_queue stuque;
Student stu;
Student stubak;
strcpy(stu.name,"bill");
stu.age = 10;
data_queue_init(&stuque,3,sizeof(Student),evt_notify);
rt_data_queue_push(&stuque,&stu);
memset(&stubak,0x00,sizeof(stubak));
rt_data_queue_pop(&stuque,&stubak);
printf("stubak name = %s, age = %d\r\n",stubak.name,stubak.age);
#endif
}
return 0;
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
如果天空是黑暗的,那就摸黑生存;
如果发出声音是危险的,那就保持沉默;
如果自觉无力发光,那就蜷伏于牆角。
但是,不要习惯了黑暗就为黑暗辩护;
也不要为自己的苟且而得意;
不要嘲讽那些比自己更勇敢的人。
我们可以卑微如尘土,但不可扭曲如蛆虫。
|