搜索
bottom↓
回复: 8

支持任意数据类型的队列

[复制链接]

出0入0汤圆

发表于 2015-7-26 23:23:07 | 显示全部楼层 |阅读模式
        一直想实现一个可以支持任意数据类型的队列,好更好的优化现有的只支持的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周年了!感谢大家的支持与爱护!!

如果想吃一顿饺子,就得从冰箱里取出肉,剁馅儿,倒面粉、揉面、醒面,擀成皮儿,下锅……
一整个繁琐流程,就是为了出锅时那一嘴滚烫流油的热饺子。

如果这个过程,禁不住饿,零食下肚了,饺子出锅时也就不香了……《非诚勿扰3》

出0入42汤圆

发表于 2015-7-26 23:26:11 | 显示全部楼层
这个用(void *)指针不就可以了吗?

出0入0汤圆

发表于 2015-7-26 23:40:48 | 显示全部楼层
一直不敢用malloc,听说用多几次后会产生碎片,然后程序就挂了,不知道是不是真的

出0入0汤圆

发表于 2015-7-27 08:45:09 | 显示全部楼层
浮点呢?

出0入0汤圆

 楼主| 发表于 2015-7-27 09:07:14 | 显示全部楼层
bbglx 发表于 2015-7-26 23:40
一直不敢用malloc,听说用多几次后会产生碎片,然后程序就挂了,不知道是不是真的 ...

        如不敢用动态申请的话,可以改写data_queue_init,把传数组地址也是可以实现的。

出0入0汤圆

 楼主| 发表于 2015-7-27 09:08:53 | 显示全部楼层

        能够支持的。

出0入0汤圆

发表于 2015-7-27 10:04:55 | 显示全部楼层

好的。多谢。

出0入0汤圆

发表于 2015-8-1 21:09:08 | 显示全部楼层
http://www.rt-thread.org/phpBB3/topic2531.html
看看这个,支持任意数据类型

出0入0汤圆

 楼主| 发表于 2015-8-2 16:24:05 | 显示全部楼层
amwox 发表于 2015-8-1 21:09
http://www.rt-thread.org/phpBB3/topic2531.html
看看这个,支持任意数据类型

        thx,多谢分享。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-28 17:05

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表