libevent笔记-buffer

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值