环形缓存的实现

环形缓存的结构

typedef struct ql_ring_buf_struct {
    int capacity;
    int rpos;
    int wpos;
    OSASemaRef wcond;
    OSASemaRef rcond;
    unsigned char data[0]; //零长度数组
}ql_ring_buf_t;
 

typedef struct quec_uart_data_struct
{
    unsigned char uart_state;
    uart_callback uart_cb;
    uart_callback_ex uart_cb_ex;
    void *callback_private_argv;
    ql_ring_buf_t *tx_rb;  //使用环形缓存
    ql_ring_buf_t *rx_rb;  //使用环形缓存

    BOOL IsSendingStatus;
}quec_uart_data_t;

1.创建环形缓存

static ql_ring_buf_t *__ql_rb_create(unsigned int size)
{
    ql_ring_buf_t *rb = NULL;
    
    if (size <= 0) {
        return NULL;
    }

    rb = malloc(sizeof(ql_ring_buf_t));
    if (NULL == rb) {
        return NULL;
    }
    memset(rb, 0, sizeof(ql_ring_buf_t));
    
    rb->data = malloc(size);
    memset(rb->data, 0, size);
    if (NULL == rb->data) {
        free(rb);
        return NULL;
    }

    rb->size = size;

    return rb;
}

2.释放环形缓存

static void __ql_rb_destroy(ql_ring_buf_t **rb)
{
    if (*rb) {
        if ((*rb)->data) {
            free((*rb)->data);
            (*rb)->data = NULL;
        }
        free(*rb);
        *rb = NULL;
    }
}

3.判断缓存是否为空

static unsigned int __ql_rb_is_empty(ql_ring_buf_t *rb)
{
    return (rb->wpos == rb->rpos);
}

4.判断环形缓存是否已满

static unsigned int __ql_rb_is_full(ql_ring_buf_t *rb)
{
    return (rb->size == (rb->wpos-rb->rpos));
}

5.缓存里面数据的多少

static unsigned int __ql_rb_data_len(ql_ring_buf_t *rb)
{
    return (rb->wpos - rb->rpos);
}

6.缓存里面剩余空间

static unsigned int __ql_rb_free_space(ql_ring_buf_t *rb)
{
    return (rb->size - (rb->wpos - rb->rpos));
}

7.数据写入缓存

static unsigned int __ql_rb_write(ql_ring_buf_t *rb, unsigned char *data, unsigned int len)
{
    unsigned int w_size = 0, w_free_size = 0;
    unsigned int r_free_size = 0;

    if (!rb || !data || (len <= 0)) {
        //quec_log("%s,rb=%#x,data=%#x,len=%d",__func__,rb,data,len);
        return 0;
    }
    
    r_free_size = __ql_rb_free_space(rb);
    w_size = len < r_free_size ? len : r_free_size;
    
    /* first put the data starting from write_pos to buffer end */ 
    w_free_size = w_size < (rb->size-(rb->wpos&(rb->size-1))) ? w_size : (rb->size-(rb->wpos&(rb->size-1)));

    memcpy(rb->data+(rb->wpos&(rb->size-1)), data, w_free_size);
    /* then put the rest (if any) at the beginning of the buffer */ 
    memcpy(rb->data, data+w_free_size, w_size-w_free_size);

    rb->wpos += w_size;

    return w_size;
}

8.数据从缓存读出

static unsigned int __ql_rb_read(ql_ring_buf_t *rb, unsigned char *data, unsigned int len)
{
    unsigned int r_size = 0, r_free_size = 0;
    unsigned int r_data_len = 0;
    
    if (!rb || !data || (len <= 0)) {
        //quec_log("%s,rb=%#x,data=%#x,len=%d",__func__,rb,data,len);
        return 0;
    }
    
    r_data_len = __ql_rb_data_len(rb);
    r_size = len < r_data_len ? len : r_data_len;
    
    /* first get the data from ring_buf->read_pos until the end of the buffer */
    r_free_size = r_size < (rb->size-(rb->rpos&(rb->size-1))) ? r_size : (rb->size-(rb->rpos&(rb->size-1)));
    
    memcpy(data, rb->data+(rb->rpos&(rb->size-1)), r_free_size);
    /* then get the rest (if any) from the beginning of the buffer */
    memcpy(data+r_free_size, rb->data, r_size-r_free_size);

    rb->rpos += r_size;

    return r_size;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值