(十六)evbuffers缓冲区(下)

本文详细介绍了libevent的evbuffers缓冲区的读写操作,包括`evbuffer_drain`的使用,如何添加格式化字符串到缓冲区,以及不同类型的缓冲区读写操作,如写出、读入和读出一行数据。文章还探讨了相关函数的内部机制和注意事项。
摘要由CSDN通过智能技术生成

前言

在上节中,我们介绍了evbuffers的部分知识,在本小节中,我们将对剩余的部分一起分析总结。

evbuffer_drain

在上节中分析的evbuffer_add_buffer中,如果添加源缓冲区到目的缓冲区结尾成功,则会调用evbuffer_drain清除源缓冲区,但是它的功能除了清除整个有效缓冲区以外,还可以清除一部分,接下来我们来看看它的源码:

void
evbuffer_drain(struct evbuffer *buf, size_t len)
{
    size_t oldoff = buf->off;
    /* 要清除的缓冲区长度大于了有效缓冲区的长度
     * 则将有效缓冲区全部清除
     * 否则只清除len长度的有效缓冲区
     */
    if (len >= buf->off) {
        buf->off = 0;
        buf->buffer = buf->orig_buffer;
        buf->misalign = 0;
        /* 难得一见的goto语句
         * 但是这里好像可以用if-else替代
         */
        goto done;
    }
    /* 缩小有效缓冲区的大小 */
    buf->buffer += len;
    buf->misalign += len;

    buf->off -= len;

 done:
    /* Tell someone about changes in this buffer */
    /* 随着上面的一顿操作,缓冲区的大小如果已经改变,则回调处理函数 */
    if (buf->off != oldoff && buf->cb != NULL)
        (*buf->cb)(buf, oldoff, buf->off, buf->cbarg);

}

在当时调用evbuffer_add_buffer时,传递给evbuffer_drainlen是等与buf->off的,所以会清除整个缓冲区的大小,但是其实这个函数的作用是清除指定大小的有效缓冲区。逻辑也很简单:

  1. len的长度是否大于等于当前有效缓冲区的长度
  2. 如果大于等于,则清除整个有效缓冲区
  3. 否则清除指定大小的有效缓冲区(将buffer后移,调整off)
  4. 如果满足缓冲区大小被改变的条件,则调用回调函数

下面介绍一下evbuffer_remove,它和evbuffer_drain关系密切(毕竟里面就调用了evbuffer_drain),只不过会将该缓冲区指定大小的内容读出来,然后再消除缓冲区。代码如下:

/* Reads data from an event buffer and drains the bytes read */
int
evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen)
{
    size_t nread = datlen;
    //这里也是处理了一下指定大小大于有效缓冲区大小的情况
    if (nread >= buf->off)    
        nread = buf->off;
    /* 将数据拷贝到data
     * 然后清除已读的数据
     * 最后返回读取的大小
     */
    memcpy(data, buf->buffer, nread);
    evbuffer_drain(buf, nread);    

    return (nread);
}

添加格式化字符串到缓冲区

除了普通的数据,将格式化的字符串添加到缓冲区需要特殊的处理。这部分主要是由evbuffer_add_printf以及evbuffer_add_vprintf完成。

int
evbuffer_add_printf(struct evbuffer *buf, const char *fmt, ...)  
{
    int res = -1;
    va_list ap;

    va_start(ap, fmt);
    res = evbuffer_add_vprintf(buf, fmt, ap);   //调用该函数实现
    va_end(ap);

    return (res);
}

这个函数涉及到C语言中可变参数的用法,具体过程有时间我再整理出来。
里面主要调用的了evbuffer_add_vprintf函数,代码如下:

int
evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
{
    char *buffer;
    size_t space;
    size_t oldoff =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值