1.evbuffer以队列的形式管理字节,从尾部添加,从头部取出(FIFO)
2.evbuffer内部存储形式是多个独立的连续内存
 
 
 
接口
//创建和删除
struct evbuffer *evbuffer_new(void);
void evbuffer_free(struct evbuffer *buf);
 
//加锁解锁
//默认情况下是没有加锁的,多线程并发访问不安全
//第二个参数lock为空,则自动分配一个锁( 使用evthread_set_lock_creation_callback()设置的锁创建函数)
int evbuffer_enable_locking(struct evbuffer *buf, void *lock);
//没有必要为单独的操作加锁,因为单独的操作已经是原子级别的了
void evbuffer_lock(struct evbuffer *buf);

void evbuffer_unlock(struct evbuffer *buf);

 
 
//获取evbuffer包含的字节数
size_t evbuffer_get_length(const struct evbuffer *buf);
 
//获取队列首部的连续空间长度
size_t evbuffer_get_contiguous_space(const struct evbuffer *buf);
 
//基础的读写数据接口
//将数据添加到尾部
int evbuffer_add(struct evbuffer *buf, const void *data, size_t datlen);
//格式化的添加数据到尾部
int evbuffer_add_printf(struct evbuffer *buf, const char *fmt, ...)
int evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap);
 
//修改最后一块连续内存,或者添加一块连续内存
int evbuffer_expand(struct evbuffer *buf, size_t datlen);
 
//从evbuffer移动数据到另一个evbuffer
int evbuffer_add_buffer(struct evbuffer *dst, struct evbuffer *src);
int evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst,
    size_t datlen);
 
//在首部添加数据
//这些函数不应该用于和bufferevent关联的evbuffer
int evbuffer_prepend(struct evbuffer *buf, const void *data, size_t size);
int evbuffer_prepend_buffer(struct evbuffer *dst, struct evbuffer* src);
 
//查看首部N字节的连续空间(首先必须确定这N字节空间是连续的,使用evbuffer_get_contiguous_space ()
//size参数为负数,则拷贝首部连续空间的所有数据
//如果size很大,该接口效率低
unsigned char *evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size);
 
//从evbuffer删除数据
//evbuffer_drain不拷贝数据,evbuffer_remove要拷贝数据
int evbuffer_drain(struct evbuffer *buf, size_t len);
int evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen);
 
//从首部拷贝而不删除数据
//如果效率不好可以使用 evbuffer_peek()
ev_ssize_t evbuffer_copyout(struct evbuffer *buf, void *data, size_t datlen);
ev_ssize_t evbuffer_copyout_from(struct evbuffer *buf,
     const struct evbuffer_ptr *pos,
     void *data_out, size_t datlen);
 
//按行进行读写
enum evbuffer_eol_style {
        EVBUFFER_EOL_ANY,     //已任何序列为换行符
        EVBUFFER_EOL_CRLF,   //回车换行的组合为换行标示 (\r\n或者\n)
        EVBUFFER_EOL_CRLF_STRICT,  //严格的\r\n
        EVBUFFER_EOL_LF,  //以\n为换行标示
        EVBUFFER_EOL_NUL //以NULL为换行标示
};
 
//返回的指针在堆上分配,n_read_out参数也是返回参数
char *evbuffer_readln(struct evbuffer *buffer, size_t *n_read_out,
    enum evbuffer_eol_style eol_style);
 
//在evbuffer中搜索
//表示位置的结构(pos是相对于开始位置的偏移值)
struct evbuffer_ptr {
ev_ssize_t pos;
struct {
/* internal fields */
} _internal;
};
struct evbuffer_ptr evbuffer_search(struct evbuffer *buffer,
    const char *what, size_t len, const struct evbuffer_ptr *start);
struct evbuffer_ptr evbuffer_search_range(struct evbuffer *buffer,
    const char *what, size_t len, const struct evbuffer_ptr *start,
    const struct evbuffer_ptr *end);
struct evbuffer_ptr evbuffer_search_eol(struct evbuffer *buffer,
    struct evbuffer_ptr *start, size_t *eol_len_out,
    enum evbuffer_eol_style eol_style);
 
 
//偏移位置计算标示
//EVBUFFER_PTR_SET,将位置作为绝对位置来设置
//EVBUFFER_PTR_ADD,在当前位置加上参数指定的位置
enum evbuffer_ptr_how {
        EVBUFFER_PTR_SET,
        EVBUFFER_PTR_ADD
};
int evbuffer_ptr_set(struct evbuffer *buffer, struct evbuffer_ptr *pos,
    size_t position, enum evbuffer_ptr_how how);
 
 
//搜索所有的字符串
#include <event2/buffer.h>
#include <string.h>

/* Count the total occurrences of 'str' in 'buf'. */int count_instances(struct evbuffer *buf, const char *str)
{
    size_t len = strlen(str);
    int total = 0;
    struct evbuffer_ptr p;

if (!len)
        /* Don't try to count the occurrences of a 0-length string. */
        return -1;

evbuffer_ptr_set(buf, &p, 0, EVBUFFER_PTR_SET);

while (1) {
         p = evbuffer_search(buf, str, len, &p);
         if (p.pos < 0)
             break;
         total++;
         evbuffer_ptr_set(buf, &p, 1, EVBUFFER_PTR_ADD);
    }

return total;
}

 
 
//在不使用拷贝的情况下,直接查看evbuffer的数据
struct evbuffer_iovec {
        void *iov_base;
        size_t iov_len;
};

 
//修改被evbuffer_iovec指向的数据,将导致未定义行为
//任何修改evbuffer的函数被调用,将导致evbuffer_peek设置的指针失效

int evbuffer_peek(struct evbuffer *buffer, ev_ssize_t len,
    struct evbuffer_ptr *start_at,
    struct evbuffer_iovec *vec_out, int n_vec);

 
 
//直接向evbuffer写入数据,不存在数据拷贝
//获取evbuffer的内部指针,如果目前的空间不够,将会进行自动扩展
//目前的实现将不会使用多于两个的evbuffer_iovec
//如果提供一个evbuffer_iovec则会进行空间连续校验,以及导致evbuffer调整内部存储,所以最好提供大于1个的evbuffer_iovec
int evbuffer_reserve_space(struct evbuffer *buf, ev_ssize_t size,
    struct evbuffer_iovec *vec, int n_vecs);
 
//如果获取到指针后,有修改evbuffer数据的行为,将导致指针失效
//或者的指针的值不能被修改
//如果evbuffer以及有数据则,这些数据将加到已有数据的后面
 
//将数据提交的evbuffer
int evbuffer_commit_space(struct evbuffer *buf,
    struct evbuffer_iovec *vec, int n_vecs);
 
网络IO
 
//howmuch参数为负 对于读表示读多少由libevent自行判断,对于写表示写整个buffer的内容
//读到结尾返回值为0,返回负数表示失败,失败的原因应进一步确认,是非阻塞IO不能立即完成
//还是其他真实错误
 
//如果使用bufferevent则这些调用都由bufferevent完成,不需要用户调用
 
 
int evbuffer_write(struct evbuffer *buffer, evutil_socket_t fd);
int evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd,
        ev_ssize_t howmuch);
int evbuffer_read(struct evbuffer *buffer, evutil_socket_t fd, int howmuch);
 
 
Evbuffer and callback
//当数据增加或删除时的回调函数
struct evbuffer_cb_info {
        size_t orig_size;//变化前的长度
        size_t n_added;   //添加的长度
        size_t n_deleted;  //删除的长度
};

typedef void (*evbuffer_cb_func)(struct evbuffer *buffer,
    const struct evbuffer_cb_info *info, void *arg);

 
//设置回调函数
struct evbuffer_cb_entry;
struct evbuffer_cb_entry *evbuffer_add_cb(struct evbuffer *buffer,
    evbuffer_cb_func cb, void *cbarg);
 
//失效或删除回调函数
int evbuffer_remove_cb_entry(struct evbuffer *buffer,
    struct evbuffer_cb_entry *ent);
int evbuffer_remove_cb(struct evbuffer *buffer, evbuffer_cb_func cb,
    void *cbarg);

//使用 EVBUFFER_CB_ENABLED失效

#define EVBUFFER_CB_ENABLED 1
int evbuffer_cb_set_flags(struct evbuffer *buffer,
                          struct evbuffer_cb_entry *cb,
                          ev_uint32_t flags);
int evbuffer_cb_clear_flags(struct evbuffer *buffer,
                          struct evbuffer_cb_entry *cb,
                          ev_uint32_t flags);

 
 
//延迟回调函数的调用
int evbuffer_defer_callbacks(struct evbuffer *buffer, struct event_base *base);
 
 
//避免数据拷贝的 基本的ebuffer-IO
 
typedef void (*evbuffer_ref_cleanup_cb)(const void *data,
    size_t datalen, void *extra);

int evbuffer_add_reference(struct evbuffer *outbuf,
    const void *data, size_t datlen,
    evbuffer_ref_cleanup_cb cleanupfn, void *extra);

 
 
//直接发送文件相关接口,由于支持的版本很新,目前未测试
 
int evbuffer_add_file(struct evbuffer *output, int fd, ev_off_t offset,
    size_t length);
 
struct evbuffer_file_segment;

struct evbuffer_file_segment *evbuffer_file_segment_new(
        int fd, ev_off_t offset, ev_off_t length, unsigned flags);
void evbuffer_file_segment_free(struct evbuffer_file_segment *seg);
int evbuffer_add_file_segment(struct evbuffer *buf,
    struct evbuffer_file_segment *seg, ev_off_t offset, ev_off_t length);

 
 
typedef void (*evbuffer_file_segment_cleanup_cb)(
    struct evbuffer_file_segment const *seg, int flags, void *arg);

void evbuffer_file_segment_add_cleanup_cb(struct evbuffer_file_segment *seg,
        evbuffer_file_segment_cleanup_cb cb, void *arg);

 
 
int evbuffer_add_buffer_reference(struct evbuffer *outbuf,
    struct evbuffer *inbuf);
 
 
int evbuffer_freeze(struct evbuffer *buf, int at_front);
int evbuffer_unfreeze(struct evbuffer *buf, int at_front);
 
 
//过时的接口
char *evbuffer_readline(struct evbuffer *buffer);
unsigned char *evbuffer_find(struct evbuffer *buffer,
    const unsigned char *what, size_t len);
 
typedef void (*evbuffer_cb)(struct evbuffer *buffer,
    size_t old_len, size_t new_len, void *arg);
void evbuffer_setcb(struct evbuffer *buffer, evbuffer_cb cb, void *cbarg);
 
 
 
 

libevent学习八(evbuffer)的更多相关文章

  1. libevent学习之二:Windows7(Win7)下编译libevent

    Linux下编译参考源码中的README文件即可,这里主要记录Windows下的编译. 一.准备工作 去官网下载最新的稳定发布版本libevent-2.0.22-stable 官网地址:http:// ...

  2. Python Tutorial 学习(八)--Errors and Exceptions

    Python Tutorial 学习(八)--Errors and Exceptions恢复 Errors and Exceptions 错误与异常 此前,我们还没有开始着眼于错误信息.不过如果你是一 ...

  3. SVG 学习<八> SVG的路径——path(2)贝塞尔曲线命令、光滑贝塞尔曲线命令

    目录 SVG 学习<一>基础图形及线段 SVG 学习<二>进阶 SVG世界,视野,视窗 stroke属性 svg分组 SVG 学习<三>渐变 SVG 学习<四 ...

  4. libevent学习笔记 一、基础知识【转】

    转自:https://blog.csdn.net/majianfei1023/article/details/46485705 欢迎转载,转载请注明原文地址:http://blog.csdn.net/ ...

  5. Libevent学习笔记(五) 根据例子学习bufferevent

    libevent中提供了一个Hello-world.c 的例子,从这个例子可以学习libevent是如何使用bufferevent的. 这个例子在Sample中 这个例子之前讲解过,这次主要看下buf ...

  6. libevent学习笔记(参考libevent深度剖析)

    最近自学libevent事件驱动库,参考的资料为libevent2.2版本以及张亮提供的<Libevent源码深度剖析>, 参考资料: http://blog.csdn.net/spark ...

  7. 【传智播客】Libevent学习笔记(一):简介和安装

    目录 00. 目录 01. libevent简介 02. Libevent的好处 03. Libevent的安装和测试 04. Libevent成功案例 00. 目录 @ 01. libevent简介 ...

  8. PHP中的Libevent学习

    wangbin@2012,1,3 目录 Libevent在php中的应用学习 1.      Libevent介绍 2.      为什么要学习libevent 3.      Php libeven ...

  9. Libevent学习之SocketPair实现

    Libevent设计的精化之一在于把Timer事件.Signal事件和IO事件统一集成在一个Reactor中,以统一的方式去处理这三种不同的事件,更确切的说是把Timer事件和Signal事件融合到了 ...

随机推荐

  1. Cloud Tool 小探索

    Google Apps不用多说. Google drive免费提供15GB的容量. Microsoft Windows Live感觉功能上和google相比无亮点和优势. SkyDrive免费提供7G ...

  2. Yii 多表关联relations

    1,首先多表关联是在models/xx.php的relations里配置的.而且是互配,但有区别.格式:'VarName'=>array('RelationType', 'ClassName', ...

  3. BZOJ2882:工艺(SAM)

    Description 小敏和小燕是一对好朋友. 他们正在玩一种神奇的游戏,叫Minecraft. 他们现在要做一个由方块构成的长条工艺品.但是方块现在是乱的,而且由于机器的要求,他们只能做到把这个工 ...

  4. 【[SCOI2008]奖励关】

    又抄了一篇题解 要凉了要凉了,开学了我还什么都不会 文化课凉凉,NOIP还要面临爆零退役的历史进程 这道题挺神的,期望+状态压缩 我们设\(dp[i][S]\)表示在第\(i\)天前,捡的宝物状态为\ ...

  5. jquery基础介绍-转

    学习目的:理解 Ajax 及其工作原理,构建网站的一种有效方法. Ajax 是 Asynchronous JavaScript and XML(以及 DHTML 等)的缩写. 下面是 Ajax 应用程 ...

  6. fc全连接层的作用、卷积层的作用、pooling层、激活函数的作用

    fc:1.起到分类器的作用.对前层的特征进行一个加权和,(卷积层是将数据输入映射到隐层特征空间)将特征空间通过线性变换映射到样本标记空间(也就是label) 2.1*1卷积等价于fc:跟原featur ...

  7. iview中table里嵌套i-switch、input、select等

    iview中table内嵌套 input render:(h,params) => { return h('Input',{ props: { value:'', size:'small', } ...

  8. POJ 1328 Radar Installation(很新颖的贪心,区间贪心)

    Radar Installation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 106491   Accepted: 2 ...

  9. window下安装composer

    1.什么是composer 一个智能的下载工具.比如说我的项目要安装yii框架,而yii是依赖于其他东西的,仅仅安装yii是不够的,这样会导致我的项目也不能正常运行:怎么办呢,我们可以一个一个手动的将 ...

  10. MyBatis之Mapper XML 文件详解(三)-Result Maps

    resultMap 元素是 MyBatis 中最重要最强大的元素.它就是让你远离 90%的需要从结果 集中取出数据的 JDBC 代码的那个东西, 而且在一些情形下允许你做一些 JDBC 不支持的事 情 ...