zoukankan      html  css  js  c++  java
  • 一种C语言实现面向对象特性的继承,多态

    基类:

    //.h

    typedef int (*TELE_SEND_CB)(char *pdata, int len);
    
    
    //函数表结构
    typedef struct tele_pro_base_vtbl
    {
        int (*trans_data)(int chun,enum rtsp_frame_type type, char *pdata, unsigned int len,unsigned int ts);
        int (*send_cmd)(int cmd,char *para,unsigned int len);
        int (*parse_cmd)(char *data_in, int size_in, void *data_out);
    }tele_pro_base_vtbl_t;
    
     
    //基类
    typedef struct tele_pro_base
    {
        /*virtual table*/
        tele_pro_base_vtbl_t *vptr;
        TELE_SEND_CB   send_cb;    
    }tele_pro_base_t;
    
    
    
    int akp_tele_pro_low_send(tele_pro_base_t *this,char *pdata,unsigned int len);
    tele_pro_base_t * akp_tele_pro_base_ctor(TELE_SEND_CB send_cb);
    
    int akp_tele_pro_send_cmd(tele_pro_base_t *this,int cmd,char *pdata,unsigned int len);
    
    int akp_tele_pro_trans_data(tele_pro_base_t *this,int chun,enum rtsp_frame_type type, char *pdata, unsigned int len,unsigned int ts);
    
    int akp_tele_pro_parse_cmd(tele_pro_base_t *this, char *data_in, int size_in, void *data_out);

    // .c

    /******************************************************
    *                    Constant         
    ******************************************************/
    
    
    /******************************************************
    *                    Macro         
    ******************************************************/
    
    
    
    /******************************************************
    *                    Type Definitions         
    ******************************************************/
    
    
    /******************************************************
    *                    Global Variables         
    ******************************************************/
    static tele_pro_base_t *ptele_pro_base = NULL;
    
    /******************************************************
    *               Function interface
    ******************************************************/
    static int __send(char *pdata,unsigned int len)
    {
        int ret = 0;;
        if(NULL != ptele_pro_base->send_cb) {
            ret = ptele_pro_base->send_cb(pdata,len);
        }
        return ret;
    }
    
    static int anyka_trans_data(int chun,enum rtsp_frame_type type, 
            char *pdata, unsigned int len,unsigned int ts)
    {
        int ret = -1;
        
        ret = ak_rtsp_send_stream(chun,type,pdata,len,ts);
    
        return ret;
    }
    
    
    static int anyka_send_cmd(int cmd,char *pdata,unsigned int len)
    {
        int ret = 0;
    
        unsigned int len_out = 0;
        char *pout = malloc(len+TEL_CTRLPRO_FRAME_SIZE_MIN);
        
        akp_tel_ctrlpro_pack(cmd, pdata, len, pout, &len_out);
        if(len_out > len+TEL_CTRLPRO_FRAME_SIZE_MIN) {
            ak_print_error("akp_tel_ctrlpro_pack error
    ");
            ret = -1;
        }
        ret = __send(pout, len_out);
        free(pout);
        return ret;
    }
    
    
    /**
     * akp_tel_ctrlpro_parse-report net state to observer
     * @data_in[IN]: recv data.
     * @size_in[IN]: recv data lenght.
     * @data_out[IN]: out frame data.
     * eg: akp_tel_ctrlpro_parse(recv_buf, len,parse_buf);
     *     tel_video_set_t video_para = (tel_video_set_t)parse_buf;
     * return: > 0 command, -1 error, -2 continue recv
     * notes: if have data,pl ensure length > TEL_CTRLPRO_FRAME_SIZE_MAX
     */
    static int anyka_parse_cmd(char *data_in, int size_in, void *data_out)
    {
        return akp_tel_ctrlpro_parse(data_in, size_in,data_out);
    }
    
    /* 可多态的函数表 */
    static tele_pro_base_vtbl_t base_table =
    {
        anyka_trans_data,
        anyka_send_cmd,
        anyka_parse_cmd
    };
    
    
    //基类的构造函数
    tele_pro_base_t * akp_tele_pro_base_ctor(TELE_SEND_CB send_cb)
    {
        tele_pro_base_t *temp = (tele_pro_base_t *)malloc(sizeof(tele_pro_base_t));
        temp->vptr = &base_table;
        temp->send_cb = send_cb;
        ptele_pro_base = temp;
        return temp;
    }
    
    
    //基类方法
    int akp_tele_pro_low_send(tele_pro_base_t *this,char *pdata,unsigned int len)
    {
        int ret = 0;;
        
        if(NULL != this->send_cb) {
            ret = this->send_cb(pdata,len);
        }
        return ret;
    }
    
    int akp_tele_pro_send_cmd(tele_pro_base_t *this,int cmd,char *pdata,unsigned int len)
    {
        int ret = 0;
        if(NULL != this->vptr->send_cmd) {
            ret = this->vptr->send_cmd(cmd,pdata,len);
        } else {
            ak_print_warning_ex("tele pro send cmd fun is null
    ");
            ret = -1;
        }
        return ret;
    }
    
    int akp_tele_pro_trans_data(tele_pro_base_t *this,int chun,enum rtsp_frame_type type, char *pdata, unsigned int len,unsigned int ts)
    {
        int ret = 0;
        if(NULL != this->vptr->trans_data) {
            ret = this->vptr->trans_data(chun,type,pdata,len ,ts);
        } else {
            ak_print_warning_ex("tele pro trans data fun is null
    ");
            ret = -1;
        }
        return ret;
    }
    
    int akp_tele_pro_parse_cmd(tele_pro_base_t *this, char *data_in, int size_in, void *data_out)
    {
        int ret = 0;   
        if(NULL != this->vptr->parse_cmd) {
            ret = this->vptr->parse_cmd(data_in,size_in,data_out);
        } else {
            ak_print_warning_ex("tele pro parse cmd fun is null
    ");
            ret = -1;
        }
    
        return ret;
    }

    派生类:

    // .h

    #define JUAN_TXBUF_SIZE            1024
    #define JUAN_PARSE_BUF_SIZE        2048
    
    typedef struct tele_pro_juan {
        tele_pro_base_t base;
        
        unsigned int    ssrc;
        unsigned short  seqNumber;
        int             fw_type;
        unsigned int    fw_size;
        unsigned int    fw_seq; 
            
        int     buf_len;
        char    parse_buf[JUAN_PARSE_BUF_SIZE];
    
        int     tx_buf_length;
        char    tx_buf[JUAN_TXBUF_SIZE];
        ak_mutex_t mutex_tx; 
    }tele_pro_juan_t;
    
    
    
    int akp_telepro_juan_post_describe(int chun);
    
    tele_pro_juan_t* akp_tele_pro_juan_data_chun_ctor(TELE_SEND_CB send_cb);

    // .c

    //------------------基类函数的多态实现---------------------
    static int juan_trans_data(int chun,enum rtsp_frame_type type, char *pdata, unsigned int len,unsigned int ts_ms)
    {
        int ret = -1;
    
        static unsigned long bit_len = 0;
        static unsigned long t1 = 0;
        unsigned long t2;
    
        ak_thread_mutex_lock(&ptele_pro->mutex_tx);
        // calculate bsp
        if(0 == bit_len) {
            t1 = ak_get_tick_count_ms();
        }
        bit_len += len;
        t2 = ak_get_tick_count_ms();
        if(t2-t1 >= 1000) {
            ak_print_notice("[juan rtsp]: bps=%d
    ",bit_len*8);
            bit_len = 0;
        }
    
        unsigned int ts = ts_ms*1000;
        if(RTSP_AFRAME == type) {
            ret = __juan_data_chun_send_data(HICHIP_FRAME_TYPE_UNUSE,HICHIP_MD_TYPE_G711,pdata,len,ts);
        } else if(RTSP_IFRAME == type){
            ret = __juan_data_chun_send_data(HICHIP_FRAME_TYPE_BASE_IDRSLICE,HICHIP_MD_TYPE_H264,pdata,len,ts);
        } else if(RTSP_PFRAME == type) {
             ret = __juan_data_chun_send_data(HICHIP_FRAME_TYPE_UNUSE,HICHIP_MD_TYPE_H264,pdata,len,ts);
        } else {
            ak_print_error("[tele]: donot support this frame type=%d
    ",type);
        }        
          ak_thread_mutex_unlock(&ptele_pro->mutex_tx);
        
        return ret;
    }
    
    static int juan_data_chun_send_cmd(int cmd,char *para,unsigned int len)
    {
        int ret = 0;
    
        ak_thread_mutex_lock(&ptele_pro->mutex_tx);
        switch(cmd) {
        case TELE_MSG_SEND_LOGIN:
            ak_print_normal("[anyka]: UL_WAKEUP_IND_MSG
    ");
            __juan_data_chun_post_describe(0);
            __juan_data_chun_login();
            break;
    
        case TELE_MSG_SEND_DEVINFO: {
            ring_dev_info_t *dev_info = (ring_dev_info_t *)para;
            unsigned int event = 0;
            unsigned int io = 0;
            if(WAKEUP_EVENT_PIR == dev_info->wake_event) {
               event |= NK_HICHIP_EVENT_IO;
               io    |= NK_HICHIP_IO_PIR;
            }
            if(dev_info->md) {
                event |= NK_HICHIP_EVENT_MD;
            }
            ak_print_normal_ex("stream chun: event=%d io=%d
    ",event,io);
            __juan_data_chun_send_cmd(event,io);
            }break;
    
    
        default:
            //ak_print_warning_ex("[tele]: donot support this cmd=%d
    ",cmd);
            break;
        }  
         ak_thread_mutex_unlock(&ptele_pro->mutex_tx);
        
        return ret;
    }
    
    /**
     * akp_tel_ctrlpro_parse-report net state to observer
     * @data_in[IN]: recv data.
     * @size_in[IN]: recv data lenght.
     * @data_out[IN]: out frame data.
     * eg: akp_tel_ctrlpro_parse(recv_buf, len,parse_buf);
     *     tel_video_set_t video_para = (tel_video_set_t)parse_buf;
     * return: > 0 command, -1 error, -2 continue recv
     * notes: if have data,pl ensure length > TEL_CTRLPRO_FRAME_SIZE_MAX
     */
    static int juan_data_chun_parse_cmd(char* data_in, int size_in, void *data_out)
    {
        char *recv_buf = ptele_pro->parse_buf;
        int cmd_len;
        int ret = -2;
        int i;
        
        for(i = 0; i< size_in; i++) {
            juan_debug_log("%c",data_in[i]);
        }
        juan_debug_log("
    ");
    
    #if 1
        /* join data */
        memcpy(recv_buf+ptele_pro->buf_len,data_in, size_in);
        ptele_pro->buf_len += size_in;
    
        
        cmd_len = find_string(recv_buf,ptele_pro->buf_len,"
    ");
        juan_debug_log("cmd_len=%d
    ",cmd_len);
        if(cmd_len > 0)
        {
            ret = __juan_data_chun_do_cmd(recv_buf,cmd_len+2,data_out);
            //ak_print_normal("cmd ret = %d DL_START_VIDEO_MSG=%d
    ",ret,DL_START_VIDEO_MSG);
            
            memcpy(recv_buf, recv_buf+cmd_len, ptele_pro->buf_len-cmd_len);
            ptele_pro->buf_len -= cmd_len;
            memset(recv_buf + ptele_pro->buf_len, 0, cmd_len);
        }
    
        if(ptele_pro->buf_len > JUAN_PARSE_BUF_SIZE-64) {
            ak_print_warning_ex(" ptele_pro->parse_buf have too many data
    ");
        }
        return ret;
    #else
        if(strstr(data_in,"HTTP/1.1 100") != NULL)
        {      
            ret = DL_START_VIDEO_MSG; 
        }  
        return ret;
    #endif
    
    }
    
    /*函数表 */
    static tele_pro_base_vtbl_t vir_table =
    {
        juan_trans_data,
        juan_data_chun_send_cmd,
        juan_data_chun_parse_cmd
    };
    
    //派生类的构造函数
    tele_pro_juan_t* akp_tele_pro_juan_data_chun_ctor(TELE_SEND_CB send_cb)
    {
        tele_pro_juan_t *temp= (tele_pro_juan_t*)malloc(sizeof(tele_pro_juan_t));
        temp->base.vptr = &vir_table;
        temp->base.send_cb = send_cb;
        ptele_pro = temp;
    
        memset(ptele_pro->parse_buf,0,sizeof(ptele_pro->parse_buf));
        ptele_pro->buf_len = 0;
    
        ak_thread_mutex_init(&ptele_pro->mutex_tx,NULL);
        return temp;
    }
  • 相关阅读:
    case 条件语句
    shell 函数
    if条件语句
    IP地址分类和分段
    shell脚本的条件测试与比较
    bc命令
    [LeetCode]Remove Duplicates from Sorted Array II
    [LeetCode]Merge Two Sorted Lists
    [LeetCode]Climbing Stairs
    [LeetCode]Merge Intervals
  • 原文地址:https://www.cnblogs.com/mic-chen/p/9382790.html
Copyright © 2011-2022 走看看