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);
 
 
 
 

最新文章

  1. 推荐几个jQuery插件
  2. MVC中Form表单的提交
  3. 外包采用Gradle生成多套app打包
  4. 【NS2仿真】RTP协议安装
  5. Redis作为多个Windows服务运行配置方法
  6. 21.allegro下鼠标形状设置[原创]
  7. aspose.word使用简单方法
  8. win8安装python环境和pip &amp; easy_install工具
  9. JavaScript高级程序设计35.pdf
  10. accumulate
  11. WCF全双工数据传输
  12. iOS 让UIButton根据文字内容自动计算宽高
  13. 内存泄漏(I)
  14. 【Java线程安全】 — ThreadLocal
  15. Objective-C 锁
  16. EasyUI动态修改easyui-textbox验证信息
  17. linux下构建MysqlCluster集群,NDB搜索引擎
  18. (原)java 向上转型中,任何域的访问操作都是由编译器解析,不是多态
  19. I - 取石子游戏
  20. Flask web开发之路八

热门文章

  1. js的一些笔记
  2. 汉字正则表达式[\u4E00-\u9FFF]原因
  3. composer安装
  4. .NET Framework 基础知识总结
  5. Java操作符
  6. Deformity PHP Webshell、Webshell Hidden Learning
  7. jsb里出现的 Invalid Native Object的一次bug修复的思考
  8. PCL—低层次视觉—点云分割(最小割算法)
  9. React 从0开始 消息传递
  10. AVFoundation自定义录制视频
  11. Ubuntu 简单安装和配置 GitLab
  12. 阿里云ecs遭到频繁的ddos攻击始末
  13. Spring ElasticsearchTemplate 经纬度按距离排序
  14. 使用pycharm 出现 interpreter field is empty 完美解决方法(转载 记录)
  15. ApplicationContext 配置里dataSource mysql连接数据源,设置ssl和utf-8
  16. distribution 分发数据库 灾难恢复 备份恢复
  17. apache目录别名
  18. 将一个文件中的内容,在另一个文件中生成. for line in f1, \n f2.write(line)
  19. PHP获取目录和文件的方法
  20. MySQL高级-全局查询日志