//libevent笔记-buffer
//转载请注明出处: yuliying的csdn博客.
//libevent内置了一个自动扩容的evbuffer.使用时在尾部追加数据,从头部移除数据.
//初始化一个buffer
//struct evbuffer *evbuffer_new(void);
//销毁一个buffer
//void evbuffer_free(struct evbuffer *buf);
//获取buffer里数据的长度
//size_t evbuffer_get_length(const struct evbuffer *buf);
//获取第一个数据块里的数据长度,evbuffer里的数据存储可能会分为多个数据块.
//size_t evbuffer_get_contiguous_space(const struct evbuffer *buf);
//向evbuffer里追加数据,返回追加数据的长度.
//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);
//buffer手动扩容,使evbuffer能够存储datlen长度的数据而不用再次扩容,一般追加数据evbuffer会自动扩容.
//int evbuffer_expand(struct evbuffer *buf, size_t datlen);
//将src buffer的数据完全移除,然后追加到det buffer的末尾
//int evbuffer_add_buffer(struct evbuffer *dst, struct evbuffer *src);
//将src buffer的头部datlen长度的数据移除,然后追加到dst buffer的末尾,返回移动的数据长度.
//int evbuffer_remove_buffer(struct evbuffer *src, struct evbuffer *dst,size_t datlen);
//将数据加到evbuffer的前端.类似上面两个函数.这两个函数不应该在使用bufferevent时使用.
//int evbuffer_prepend(struct evbuffer *buf, const void *data, size_t size);
//int evbuffer_prepend_buffer(struct evbuffer *dst, struct evbuffer* src);
//使evbuffer前端的size字节代码在一个数据块里面(线性化).以便作为一个字节数组使用.
//如果size为负数,函数线性化整个evbuffer.
//如果size大于evbuffer的长度,函数返回NULL.否则返回字节数组的开头指针.
//unsigned char *evbuffer_pullup(struct evbuffer *buf, ev_ssize_t size);
//从evbuffer开头移除数据,并将移除的数据复制到用户提供的buffer里面
//失败时返回-1,否则返回移动的字节数.
//int evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen);
//从evbuffer开头移除数据
//int evbuffer_drain(struct evbuffer *buf, size_t len);
//将evbuffer头部数据复制出来,但是不移除数据.
//失败时返回-1,否则返回复制的字节数.
//ev_ssize_t evbuffer_copyout(struct evbuffer *buf, void *data, size_t datlen);
//从指定的偏移将evbuffer数据复制出来,但是不移除数据.(2.0版本里还没有这个函数)
//ev_ssize_t evbuffer_copyout_from(struct evbuffer *buf,const struct evbuffer_ptr *pos,void *data_out, size_t datlen);
//从evbuffer读取一行数据,可以设置行结束符类型,返回的buffer需要自己free掉. 该行数据会从evbuffer里移除
//如果读取到了一行,n_read_out是读取的数据长度,返回这行的指针. 否则返回NULL.
//返回的行不包括行结束符.
//evbuffer_eol_style有四种:
// 1.EVBUFFER_EOL_ANY ('\r\n','\n\r','\r','\n')
// 2.EVBUFFER_EOL_CRLF ("\n" , "\r\n")
// 3.EVBUFFER_EOL_CRLF_STRICT ("\r\n")
// 4.EVBUFFER_EOL_LF ("\n")
//char *evbuffer_readln(struct evbuffer *buffer, size_t *n_read_out,enum evbuffer_eol_style eol_style);
//evbuffer_ptr 结构指向一个evbuffer内部的地址.
//在evbuffer里面搜索字符串.如果没找到 evbuffer_ptr.pos 返回-1
//struct evbuffer_ptr evbuffer_search(struct evbuffer *buffer,const char *what, size_t len, const struct evbuffer_ptr *start);
//在evbuffer里面搜索字符串.并指定结束地址.
//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);
//在evbuffer里面搜索上述行结束字符串.
//如果eol_len_out不为NULL , 它返回行结束符的长度.
//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所指向的evbuffer内部的位置
//成功返回0,失败返回-1
//evbuffer_ptr_how 可以为两个值: EVBUFFER_PTR_SET(相对于evbuffer开头的绝对位置),EVBUFFER_PTR_ADD(相对于当前位置的相对位置)
//int evbuffer_ptr_set(struct evbuffer *buffer, struct evbuffer_ptr *pos,size_t position, enum evbuffer_ptr_how how);
//将buffer里的数据向套接字写尽可能多的数据.
//返回值同write函数.
//使用bufferevent时不需要使用这些函数,bufferevent会自动帮我们做这些.
//int evbuffer_write(struct evbuffer *buffer, evutil_socket_t fd);
//将buffer里的数据向套接字写数据.
//使用bufferevent时不需要使用这些函数,bufferevent会自动帮我们做这些.
//int evbuffer_write_atmost(struct evbuffer *buffer, evutil_socket_t fd,ev_ssize_t howmuch);
//从一个套接字里读数据到buffer.
//返回值同read()函数.
//如果howmuch为负数,将自动读取适当多的数据.
//使用bufferevent时不需要使用这些函数,bufferevent会自动帮我们做这些.
//int evbuffer_read(struct evbuffer *buffer, evutil_socket_t fd, int howmuch);
//从evbuffer获取内部各个数据块的起始位置和长度.
//传入一个struct evbuffer_iovec结构数组,n_vec是这个数组的长度.
//它的返回值将指示出evbuffer中各个数据块的数据起始指针位置和数据长度.
//当len小于0时,函数尝试填充所有的evbuffer_iovec结构数组,如果大于0,最多填充len bytes数据.
//如果结构体数组足够填充所有请求的数据,返回使用的结构体个数,否则返回需要的结构体个数.
//如果start_at不为NULL , 则从该位置开始.
//int evbuffer_peek(struct evbuffer *buffer, ev_ssize_t len,struct evbuffer_ptr *start_at,struct evbuffer_iovec *vec_out, int n_vec);
//打开锁功能/加锁/解锁.在多线程访问evbuffer的时候需要加锁.
//在单独调用libevent提供的函数的时候不需要加锁/解锁,因为如果打开了锁功能,每个操作已经是原子的了.
//只有调用几个函数,并且需要原子化的时候可以加锁.
//int evbuffer_enable_locking(struct evbuffer *buf, void *lock);
//void evbuffer_lock(struct evbuffer *buf);
//void evbuffer_unlock(struct evbuffer *buf);
//.....还有一些函数,感觉没啥用,就先不列出来了.
#include <event2/event.h>
#include <event2/buffer.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void print_buf(struct evbuffer * buf , struct evbuffer_ptr *from){
//evbuffer_peek
int n , i;
struct evbuffer_iovec v[10];
n = evbuffer_peek( buf , -1 , from , v , 10);
if ( n > 10) {
printf("can't print all data , at least [%d] struct evbuffer_iovec is need\n" , n);
n = 10;
}
for (i=0; i<n; ++i) {
fwrite(v[i].iov_base, 1, v[i].iov_len, stderr);
}
}
int main(){
//evbuffer_new
struct evbuffer * buf = evbuffer_new();
//evbuffer_add , evbuffer_add_printf
evbuffer_add( buf , "merry christmas\n" , strlen("merry christmas\n"));
evbuffer_add_printf( buf , "hello %s\n" , "world");
//evbuffer_get_length
size_t len = evbuffer_get_length(buf);
printf("===evbuffer_get_length() : [%d]===\n" , len);
//evbuffer_get_contiguous_space
len = evbuffer_get_contiguous_space(buf);
printf("===evbuffer_get_contiguous_space() : [%d]===\n" , len);
//evbuffer_readln
char * line = evbuffer_readln( buf , &len , EVBUFFER_EOL_ANY);
if ( line != NULL) {
printf("===evbuffer_readln(): line[%s] len[%d]===\n" , line , len);
free(line);
}
//evbuffer_copyout
char copy_out_buf[6];
memset( copy_out_buf , 0 , 6);
ev_ssize_t copy_out_n = evbuffer_copyout( buf , copy_out_buf , 5);
printf("===evbuffer_copyout() : data[%s] len[%d]===\n" , copy_out_buf , copy_out_n);
//evbuffer_add_buffer
struct evbuffer * tmpbuf = evbuffer_new();
evbuffer_add( tmpbuf , "love you\n" , strlen("love you\n"));
printf("===evbuffer_add_buffer() : before===\n");
print_buf(buf , NULL);
evbuffer_add_buffer( buf , tmpbuf);
printf("===evbuffer_add_buffer() : after===\n");
print_buf(buf , NULL);
//evbuffer_search
struct evbuffer_ptr ptr = evbuffer_search( buf , "lov" , 3 , NULL);
if (ptr.pos != -1){
printf("===evbuffer_search() : print buffer from search result point===\n");
print_buf( buf , &ptr);
}
//evbuffer_ptr_set
evbuffer_ptr_set(buf , &ptr , 1 , EVBUFFER_PTR_ADD);
printf("===evbuffer_ptr_set() : print buffer from ptr===\n");
print_buf( buf , &ptr);
//evbuffer_remove
printf("===evbuffer_remove(): before remove===\n");
print_buf(buf , NULL);
char remove_data[3];
memset(remove_data , 0 , 3);
int rm_len = evbuffer_remove( buf , remove_data , 2);
if (rm_len > 0){
printf( "===evbuffer_remove() : [%s] [%d]===\n" , remove_data , rm_len);
}
printf("===evbuffer_remove(): after remove===\n");
print_buf(buf , NULL);
//
evbuffer_free(buf);
evbuffer_free(tmpbuf);
}
libevent笔记-buffer
最新推荐文章于 2022-11-11 11:10:43 发布