acl  3.5.3.0
acl_vstream.h
浏览该文件的文档.
1 #ifndef ACL_VSTREAM_INCLUDE_H
2 #define ACL_VSTREAM_INCLUDE_H
3 
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7 
8 #include "acl_define.h"
9 #include <time.h>
10 #include <sys/types.h>
11 
12 #ifdef ACL_UNIX
13 #include <sys/time.h>
14 #include <sys/types.h>
15 #include <sys/uio.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18 #include <netinet/in.h>
19 #endif
20 
21 #include "acl_array.h"
22 #include "acl_htable.h"
23 #include "acl_vstring.h"
24 
25 #define ACL_VSTREAM_EOF (-1) /* no more space or data */
26 
27 #ifdef ACL_UNIX
28 
29 # ifndef O_RDONLY
30 # define O_RDONLY 0
31 # endif
32 # ifndef O_WRONLY
33 # define O_WRONLY 1
34 # endif
35 # ifndef O_RDWR
36 # define O_RDWR 2
37 # endif
38 #endif
39 
40 #define ACL_VSTREAM_BUFSIZE 4096
41 
42 typedef struct ACL_VSTREAM ACL_VSTREAM;
43 
44 typedef int (*ACL_VSTREAM_RD_FN)(ACL_SOCKET fd, void *buf, size_t size,
45  int timeout, ACL_VSTREAM *fp, void *context);
46 typedef int (*ACL_VSTREAM_WR_FN)(ACL_SOCKET fd, const void *buf,
47  size_t size, int timeout, ACL_VSTREAM *fp, void *context);
48 typedef int (*ACL_VSTREAM_WV_FN)(ACL_SOCKET fd, const struct iovec *vec,
49  int count, int timeout, ACL_VSTREAM *fp, void *context);
50 typedef int (*ACL_FSTREAM_RD_FN)(ACL_FILE_HANDLE fh, void *buf, size_t size,
51  int timeout, ACL_VSTREAM *fp, void *context);
52 typedef int (*ACL_FSTREAM_WR_FN)(ACL_FILE_HANDLE fh, const void *buf,
53  size_t size, int timeout, ACL_VSTREAM *fp, void *context);
54 typedef int (*ACL_FSTREAM_WV_FN)(ACL_FILE_HANDLE fh, const struct iovec *vec,
55  int count, int timeout, ACL_VSTREAM *fp, void *context);
56 
57 /* 当关闭或释放一个数据流时, 需要回调一些释放函数, 此结果定义了该回调
58  * 函数的句柄类型 ---add by zsx, 2006.6.20
59  */
60 typedef struct ACL_VSTREAM_CLOSE_HANDLE {
61  void (*close_fn)(ACL_VSTREAM*, void*);
62  void *context;
64 
65 /* 数据读写流类型定义 */
66 struct ACL_VSTREAM {
67  union {
68  ACL_SOCKET sock; /**< the master socket */
69  ACL_FILE_HANDLE h_file; /**< the file handle */
70  } fd;
71 
72  int is_nonblock; /**< just for WINDOWS, because the ioctlsocket is too weak */
73  int type; /**< defined as: ACL_VSTREAM_TYPE_XXX */
74 #define ACL_VSTREAM_TYPE_SOCK (1 << 0)
75 #define ACL_VSTREAM_TYPE_FILE (1 << 1)
76 #define ACL_VSTREAM_TYPE_LISTEN (1 << 2)
77 #define ACL_VSTREAM_TYPE_LISTEN_INET (1 << 3)
78 #define ACL_VSTREAM_TYPE_LISTEN_UNIX (1 << 4)
79 #define ACL_VSTREAM_TYPE_LISTEN_IOCP (1 << 5)
80 #define ACL_VSTREAM_TYPE_INET4 (1 << 6)
81 #define ACL_VSTREAM_TYPE_INET6 (1 << 7)
82 #define ACL_VSTREAM_TYPE_UNIX (1 << 8)
83 
84  acl_off_t offset; /**< cached seek info */
85  acl_off_t sys_offset; /**< cached seek info */
86 
87  unsigned char *wbuf; /**< used when call acl_vstream_buffed_writen */
88  int wbuf_size; /**< used when call acl_vstream_buffed_writen */
89  int wbuf_dlen; /**< used when call acl_vstream_buffed_writen */
90 
91  unsigned char *read_buf; /**< read buff */
92  int read_buf_len; /**< read_buf's capacity */
93  int read_cnt; /**< data's length in read_buf */
94  unsigned char *read_ptr; /**< pointer to next position in read_buf */
95  int read_ready; /**< if the system buffer has some data */
96 
97  acl_off_t total_read_cnt; /**< total read count of the fp */
98  acl_off_t total_write_cnt; /**< total write count of the fp */
99 
100  void *ioctl_read_ctx; /**< only for acl_ioctl_xxx in acl_ioctl.c */
101  void *ioctl_write_ctx; /**< only for acl_ioctl_xxx in acl_ioctl.c */
102  void *fdp; /**< only for event */
103 
104  unsigned int flag; /**< defined as: ACL_VSTREAM_FLAG_XXX */
105 #define ACL_VSTREAM_FLAG_READ (1 << 0)
106 #define ACL_VSTREAM_FLAG_WRITE (1 << 1)
107 #define ACL_VSTREAM_FLAG_RW (1 << 2)
108 #define ACL_VSTREAM_FLAG_CACHE_SEEK (1 << 3)
109 #define ACL_VSTREAM_FLAG_DEFER_FREE (1 << 4) /**< 延迟关闭 */
110 
111 #define ACL_VSTREAM_FLAG_ERR (1 << 10) /**< 其它错误 */
112 #define ACL_VSTREAM_FLAG_EOF (1 << 11) /**< 结束 */
113 #define ACL_VSTREAM_FLAG_TIMEOUT (1 << 12) /**< 超时 */
114 #define ACL_VSTREAM_FLAG_RDSHORT (1 << 13) /**< 读的不够 */
115 #define ACL_VSTREAM_FLAG_BAD (ACL_VSTREAM_FLAG_ERR \
116  | ACL_VSTREAM_FLAG_EOF \
117  | ACL_VSTREAM_FLAG_TIMEOUT)
118 #define ACL_VSTREAM_FLAG_CLIENT (1 << 14)
119 #define ACL_VSTREAM_FLAG_CONNECT (1 << 15)
120 #define ACL_VSTREAM_FLAG_SOCKPAIR (1 << 16)
121 
122 #define ACL_VSTREAM_FLAG_TAGYES (1 << 17) /* 若读到要求的标志位则置位 */
123 
124 #define ACL_VSTREAM_FLAG_CONNECTING (1 << 18) /* 正在连接过程中 */
125 #define ACL_VSTREAM_FLAG_PREREAD (1 << 19) /* 对于 acl_vstream_can_read 调用过程是否允许预读 */
126 
127 #define ACL_VSTREAM_FLAG_MS (1 << 20) /**< 毫秒超时级别 */
128 #define ACL_VSTREAM_FLAG_US (1 << 21) /**< 微秒超时级别 */
129 #define ACL_VSTREAM_FLAG_NS (1 << 22) /**< 纳秒超时级别 */
130 
131 /* 设置毫秒级超时 */
132 #define ACL_VSTREAM_SET_MS(x) ((x)->flag |= ACL_VSTREAM_FLAG_MS)
133 /* 设置微秒级超时 */
134 #define ACL_VSTREAM_SET_US(x) ((x)->flag |= ACL_VSTREAM_FLAG_US)
135 /* 设置纳秒级超时 */
136 #define ACL_VSTREAM_SET_NS(x) ((x)->flag |= ACL_VSTREAM_FLAG_NS)
137 
138 /* 清除毫秒级超时 */
139 #define ACL_VSTREAM_CLR_MS(x) ((x)->flag &= ~ACL_VSTREAM_FLAG_MS)
140 /* 清除微秒级超时 */
141 #define ACL_VSTREAM_CLR_US(x) ((x)->flag &= ~ACL_VSTREAM_FLAG_US)
142 /* 清除纳秒级超时 */
143 #define ACL_VSTREAM_CLR_NS(x) ((x)->flag &= ~ACL_VSTREAM_FLAG_NS)
144 
145 /* 判断是否设置了毫秒级超时 */
146 #define ACL_VSTREAM_IS_MS(x) (((x)->flag & ACL_VSTREAM_FLAG_MS) != 0)
147 /* 判断是否设置了微秒级超时 */
148 #define ACL_VSTREAM_IS_US(x) (((x)->flag & ACL_VSTREAM_FLAG_US) != 0)
149 /* 判断是否设置了纳秒级超时 */
150 #define ACL_VSTREAM_IS_NS(x) (((x)->flag & ACL_VSTREAM_FLAG_NS) != 0)
151 
152  int errnum; /**< record the system errno here */
153  int rw_timeout; /**< read/write timeout */
154  char *addr_local; /**< the local addr of the fp */
155  char *addr_peer; /**< the peer addr of the fp */
156  struct sockaddr *sa_local; /**< for IPV4/IPV6/UNIX */
157  struct sockaddr *sa_peer; /**< for IPV4/IPV6/UNIX */
159  size_t sa_peer_size;
160  size_t sa_local_len;
161  size_t sa_peer_len;
162  char *path; /**< the path just for file operation */
163  void *context; /**< the application's special data */
164 
165  ACL_ARRAY *close_handle_lnk; /**< before this fp is free,
166  * function in close_handle_lnk
167  * will be called.
168  * add by zsx, 2006.6.20
169  */
170  int (*sys_getc)(ACL_VSTREAM*); /**< called by ACL_VSTREAM_GETC()/1 */
171  ACL_VSTREAM_RD_FN read_fn; /**< system socket read API */
172  ACL_VSTREAM_WR_FN write_fn; /**< system socket write API */
173  ACL_VSTREAM_WV_FN writev_fn; /**< system socket writev API */
174 
175  ACL_FSTREAM_RD_FN fread_fn; /**< system file read API */
176  ACL_FSTREAM_WR_FN fwrite_fn; /**< system file write API */
177  ACL_FSTREAM_WV_FN fwritev_fn; /**< system file writev API */
178 
179  int (*close_fn)(ACL_SOCKET); /**< system socket close API */
180  int (*fclose_fn)(ACL_FILE_HANDLE); /**< system file close API */
181 
182  unsigned int oflags; /**< the system's open flags */
183  /* general flags(ANSI):
184  * O_RDONLY: 0x0000, O_WRONLY: 0x0001, O_RDWR: 0x0002, O_APPEND: 0x0008,
185  * O_CREAT: 0x0100, O_TRUNC: 0x0200, O_EXCL: 0x0400;
186  * just for win32:
187  * O_TEXT: 0x4000, O_BINARY: 0x8000, O_RAW: O_BINARY,
188  * O_SEQUENTIAL: 0x0020, O_RANDOM: 0x0010.
189  */
190 
191  unsigned int omode; /**< open mode, such as: 0600, 0777 */
192 
193  int nrefer; /**< refer count, used for engine moudle */
194 
195 #if defined(_WIN32) || defined(_WIN64)
196  int pid;
197  HANDLE hproc;
198  ACL_SOCKET iocp_sock;
199 #elif defined(ACL_UNIX)
200  pid_t pid;
201 #endif
203 };
204 
205 extern ACL_API ACL_VSTREAM acl_vstream_fstd[]; /**< pre-defined streams */
206 #define ACL_VSTREAM_IN (&acl_vstream_fstd[0]) /**< 标准输入 */
207 #define ACL_VSTREAM_OUT (&acl_vstream_fstd[1]) /**< 标准输出 */
208 #define ACL_VSTREAM_ERR (&acl_vstream_fstd[2]) /**< 标准错误输出 */
209 
210 /*--------------------------------------------------------------------------*/
211 /**
212  * 初始化ACL_VSTREAM流的函数库
213  * 对于_WIN32来说,如果想要用标准输入输出,则需要调用此函数进行初始化
214  */
215 ACL_API void acl_vstream_init(void);
216 
217 /**
218  * 功能: 探测流中有多少数据, 包含缓冲区中的数据与系统缓冲区的数据
219  * @param fp {ACL_VSTREAM*} 流指针, 不能为空
220  * @return ret {int}, ret > 0 OK; ret <= 0 Error
221  * 注: 仅适应于网络套接字
222  */
223 ACL_API int acl_vstream_peekfd(ACL_VSTREAM *fp);
224 
225 /**
226  * 克隆一个ACL_VSTREAM流,除ioctl_read_ctx, ioctl_write_ctx, fdp
227  * 外所有数据都拷贝,如果是动态内存数据,则新的流将在内部动态分配
228  * 内存且将源数据进行拷贝
229  * @param stream_src {ACL_VSTREAM*} 源流指针
230  * @return {ACL_VSTREAM*} 目的流指针
231  */
232 ACL_API ACL_VSTREAM *acl_vstream_clone(const ACL_VSTREAM *stream_src);
233 
234 /**
235  * 设置数据流的类型,该函数将根据所给类型设定用于该数据流上的读、写、关闭函数
236  * @param fp {ACL_VSTREAM*} 流指针, 不能为空
237  * @param type {int} 数据流的类型,defined above: ACL_VSTREAM_TYPE_XXX
238  * @return ret {int}, ret >= 0 OK; ret < 0 Error
239  */
240 ACL_API int acl_vstream_set_fdtype(ACL_VSTREAM *fp, int type);
241 
242 /**
243  * 分配一文件句柄所对应的数据流
244  * @param fh {ACL_FILE_HANDLE} 文件句柄
245  * @param oflags {unsigned int} 标志位, We're assuming that O_RDONLY: 0x0000,
246  * O_WRONLY: 0x0001, O_RDWR: 0x0002, O_APPEND: 0x0008, O_CREAT: 0x0100,
247  * O_TRUNC: 0x0200, O_EXCL: 0x0400; just for win32, O_TEXT: 0x4000,
248  * O_BINARY: 0x8000, O_RAW: O_BINARY, O_SEQUENTIAL: 0x0020, O_RANDOM: 0x0010.
249  * 同时设置
250  * @return {ACL_VSTREAM*} 数据流句柄
251  */
252 ACL_API ACL_VSTREAM *acl_vstream_fhopen(ACL_FILE_HANDLE fh, unsigned int oflags);
253 
254 /**
255  * 分配一个数据流
256  * @param fd {ACL_SOCKET} 描述符(可以为网络描述字也可以为文件描述字)
257  * @param oflags {unsigned int} 标志位, We're assuming that O_RDONLY: 0x0000,
258  * O_WRONLY: 0x0001, O_RDWR: 0x0002, O_APPEND: 0x0008, O_CREAT: 0x0100,
259  * O_TRUNC: 0x0200, O_EXCL: 0x0400; just for win32, O_TEXT: 0x4000,
260  * O_BINARY: 0x8000, O_RAW: O_BINARY, O_SEQUENTIAL: 0x0020, O_RANDOM: 0x0010.
261  * @param buflen {size_t} 内置缓冲区的大小
262  * @param rw_timeo {int} 读写超时时间(以秒为单位)
263  * @param fdtype {int} ACL_VSTREAM_TYPE_FILE, ACL_VSTREAM_TYPE_SOCK,
264  * ACL_VSTREAM_TYPE_LISTEN | ACL_VSTREAM_TYPE_LISTEN_INET | ACL_VSTREAM_TYPE_LISTEN_UNIX
265  * @return ret {ACL_VSTREAM*}, ret == NULL: 出错, ret != NULL: OK
266  */
267 ACL_API ACL_VSTREAM *acl_vstream_fdopen(ACL_SOCKET fd, unsigned int oflags,
268  size_t buflen, int rw_timeo, int fdtype);
269 
270 /**
271  * 打开一个文件的数据流
272  * @param path {const char*} 文件名
273  * @param oflags {unsigned int} 标志位, We're assuming that O_RDONLY: 0x0000,
274  * O_WRONLY: 0x0001, O_RDWR: 0x0002, O_APPEND: 0x0008, O_CREAT: 0x0100,
275  * O_TRUNC: 0x0200, O_EXCL: 0x0400; just for win32, O_TEXT: 0x4000,
276  * O_BINARY: 0x8000, O_RAW: O_BINARY, O_SEQUENTIAL: 0x0020, O_RANDOM: 0x0010.
277  * @param mode {int} 打开文件句柄时的模式(如: 0600)
278  * @param buflen {size_t} 内置缓冲区的大小
279  * @return ret {ACL_VSTREAM*}, ret== NULL: 出错, ret != NULL: OK
280  */
281 ACL_API ACL_VSTREAM *acl_vstream_fopen(const char *path, unsigned int oflags,
282  int mode, size_t buflen);
283 
284 /**
285  * 读取整个文件内容于内存中
286  * @param path {const char*} 文件名, 如: /opt/acl/conf/service/test.cf
287  * @return {char*} 存有文件全部内容的缓冲区, 用完后用户需要调用 acl_myfree
288  * 释放该内存区
289  */
290 ACL_API char *acl_vstream_loadfile(const char *path);
291 
292 /**
293  * 读取整个文件内容于内存中
294  * @param path {const char*} 文件名, 如: /opt/acl/conf/service/test.cf
295  * @param size {ssize_t*} 如果非空,则该值存储返回的缓冲区大小,如果读取内容
296  * 出错,则该值会被置 -1
297  * @return {char*} 存有文件全部内容的缓冲区, 用完后用户需要调用 acl_myfree
298  * 释放该内存区
299  */
300 ACL_API char *acl_vstream_loadfile2(const char *path, ssize_t *size);
301 
302 /**
303  * 设置流的各个参数
304  * @param fp {ACL_VSTREAM*} 流指针
305  * @param name {int} 所设置的参数类型中的第一个参数类型名,
306  * defined as ACL_VSTREAM_CTL_
307  */
308 ACL_API void acl_vstream_ctl(ACL_VSTREAM *fp, int name,...);
309 #define ACL_VSTREAM_CTL_END 0
310 #define ACL_VSTREAM_CTL_READ_FN 1
311 #define ACL_VSTREAM_CTL_WRITE_FN 2
312 #define ACL_VSTREAM_CTL_PATH 3
313 #define ACL_VSTREAM_CTL_FD 4
314 #define ACL_VSTREAM_CTL_TIMEOUT 5
315 #define ACL_VSTREAM_CTL_CONTEXT 6
316 #define ACL_VSTREAM_CTL_CTX ACL_VSTREAM_CTL_CONTEXT
317 #define ACL_VSTREAM_CTL_CACHE_SEEK 7
318 
319 /**
320  * 定位文件指针
321  * @param fp {ACL_VSTREAM*} 数据流指针
322  * @param offset {acl_off_t} 偏移量
323  * @param whence {int} 偏移方向, SEEK_SET, SEEK_CUR, SEEK_END
324  * @return ret {acl_off_t}, ret >= 0: 正确, ret < 0: 出错
325  * 注: acl_vstream_fseek() 效率更高些, 其充分利用了缓冲区的功能,
326  * 且比 acl_vstream_fseek2() 少调用一次 lseek() 系统调用.
327  */
328 ACL_API acl_off_t acl_vstream_fseek(ACL_VSTREAM *fp, acl_off_t offset, int whence);
329 
330 /**
331  * 定位文件指针
332  * @param fp {ACL_VSTREAM*} 数据流指针
333  * @param offset {acl_off_t} 偏移量
334  * @param whence {int} 移动方向:SEEK_SET(从文件起始位置后移动),
335  * SEEK_CUR(从当前文件指针位置向后移动), SEEK_END(从文件尾向前移动)
336  * @return ret {acl_off_t}, ret >= 0: 正确, ret < 0: 出错
337  * @DEPRECATED 该函数的效率较低
338  */
339 ACL_API acl_off_t acl_vstream_fseek2(ACL_VSTREAM *fp, acl_off_t offset, int whence);
340 
341 /**
342  * 返回当前文件指针所在位置
343  * @param fp {ACL_VSTREAM*} 数据流指针
344  * @return {acl_off_t} 当前文件指针所在位置, -1 表示出错
345  */
347 
348 /**
349  * 将源文件进程截断
350  * @param fp {ACL_VSTREAM*} 数据流指针
351  * @param length {acl_off_t} 数据长度(>=0)
352  * @return {int} 0: ok, -1: error
353  */
354 ACL_API int acl_file_ftruncate(ACL_VSTREAM *fp, acl_off_t length);
355 
356 /**
357  * 将源文件进程截断
358  * @param path {const char*} 文件名(可以是全路径或相对路径)
359  * @param length {acl_off_t} 数据长度(>=0)
360  * @return {int} 0: ok, -1: error
361  */
362 ACL_API int acl_file_truncate(const char *path, acl_off_t length);
363 
364 /**
365  * 查看一个文件流句柄的属性
366  * @param fp {ACL_VSTREAM *} 文件流句柄
367  * @param buf {acl_stat *} 存储结果的结构地址
368  * @return {int} 0: ok; -1: error
369  */
370 ACL_API int acl_vstream_fstat(ACL_VSTREAM *fp, struct acl_stat *buf);
371 
372 /**
373  * 查看一个文件的大小
374  * @param fp {ACL_VSTREAM *} 文件流句柄
375  * @return {int} >= 0: ok; -1: error
376  */
377 ACL_API acl_int64 acl_vstream_fsize(ACL_VSTREAM *fp);
378 
379 /**
380  * 从流中读取一个字节
381  * @param fp {ACL_VSTREAM*} 数据流指针
382  * @return {int} ACL_VSTREAM_EOF(出错) 或所读到的某个字节的ASCII
383  * 或为 ACL_VSTREAM_EOF: 读出错或对方关闭了连接, 应该关闭该数据流
384  */
385 ACL_API int acl_vstream_getc(ACL_VSTREAM *fp);
386 #define acl_vstream_get_char acl_vstream_getc
387 
388 /**
389  * 从流中非阻塞地一次性最大读取 size 个字节
390  * @param fp {ACL_VSTREAM*} 数据流指针
391  * @param buf {char*} 用户传来的内存缓存区
392  * @param size {int} buf 缓存区的空间大小
393  * @return {int} 所读取的字节数 n, 如果 n == ACL_VSTREAM_EOF 表明出错, 否则
394  * n >= 0 正确.
395  */
396 ACL_API int acl_vstream_nonb_readn(ACL_VSTREAM *fp, char *buf, int size);
397 
398 /**
399  * 判断一个给定的数据流是否已经被系统关闭了,当数据流缓存区没有数据时,
400  * 该函数会调用系统的读函数(即读一个字节)来判断是否socket出错或已经
401  * 关闭;如成功读取一个字节,则说明socket正常,同时将所读的数据放回缓存
402  * 区, 如果读返回ACL_VSTREAM_EOF, 便需要判断错误号是否被关闭
403  * @param fp {ACL_VSTREAM*} 数据流指针
404  * @return {int}, 0 说明该socket正常; -1 该socket出错或已经被系统关闭
405  */
406 ACL_API int acl_vstream_probe_status(ACL_VSTREAM *fp);
407 
408 /**
409  * 将一个字符放回数据流中
410  * @param fp {ACL_VSTREAM*} 数据流指针
411  * @param ch {int} 字符的 ASCII 码
412  * @return {int} 字符的 ASCII 码, 该函数应不会出错, 除非内部内存分配失败而产生
413  * core 文件.
414  */
415 ACL_API int acl_vstream_ungetc(ACL_VSTREAM *fp, int ch);
416 
417 /**
418  * 将指定长度的数据放回至数据流中
419  * @param fp {ACL_VSTREAM*} 数据流指针
420  * @param ptr {const void *} 需要放回至流中的数据的起始地址
421  * @param length {size_t} 需要放回至流中的数据的长度
422  * @return {int} 被成功放回至流中的数据长度, 应该永不会出错, 除非内部内存分配
423  * 失败而自动产生 core 文件!
424  */
425 ACL_API int acl_vstream_unread(ACL_VSTREAM *fp, const void *ptr, size_t length);
426 
427 /**
428  * 从数据流中读取一行数据, 直到读到 "\n" 或读结束为止, 正常情况下包括 "\n"
429  * @param fp {ACL_VSTREAM*} 数据流
430  * @param vptr {void*} 用户所给的内存缓冲区指针
431  * @param maxlen {size_t} vptr 缓冲区的大小
432  * @return ret {int}, ret == ACL_VSTREAM_EOF: 读出错或对方关闭了连接,
433  * 应该关闭本地数据流; n > 0: 读到 了 n 个字节的数据, 如果该 n 个数据
434  * 的最后一个非 0 字符为 "\n" 表明读到了一个完整的行, 否则表明读到了 n
435  * 个数据但对方未发送 "\n" 就关闭了连接; 还可以通过检查
436  * (fp->flag & ACL_VSTREAM_FLAG_TAGYES)
437  * 不等于 0 来判断是否读到了 "\n", 如果非 0 则表示读到了 "\n".
438  */
439 ACL_API int acl_vstream_gets(ACL_VSTREAM *fp, void *vptr, size_t maxlen);
440 #define acl_vstream_readline acl_vstream_gets
441 #define acl_vstream_fgets acl_vstream_gets
442 
443 /**
444  * 从数据流中读取一行数据, 直到读到 "\n" 或读结束为止, 返回的结果中不包括 "\n"
445  * @param fp {ACL_VSTREAM*} 数据流
446  * @param vptr {void*} 用户所给的内存缓冲区指针
447  * @param maxlen {size_t} vptr 缓冲区的大小
448  * @return ret {int}, ret == ACL_VSTREAM_EOF: 读出错或对方关闭了连接,
449  * 应该关闭本地数据流, n == 0: 读到了一行数据, 但该行数据仅有 "\r\n",
450  * n > 0: 读到 了 n 个字节的数据.
451  */
452 ACL_API int acl_vstream_gets_nonl(ACL_VSTREAM *fp, void *vptr, size_t maxlen);
453 
454 /**
455  * 从数据流中获得以字符串为标志结束位的内容
456  * @param fp {ACL_VSTREAM*} 类型指针
457  * @param vptr {void*} 数据存储缓冲区
458  * @param maxlen {size_t} vptr 缓冲区大小
459  * @param tag {const char*} 字符串标志
460  * @param taglen {size_t} tag 中内容的长度大小
461  * @return ret {int}, ret == ACL_VSTREAM_EOF: 读出错或对方关闭了连接,
462  * 应该关闭本地数据流, n > 0: 读到 了 n 个字节的数据, 如果读到了所需要的
463  * 标志串, 则 fp 流中 (fp->flag & ACL_VSTREAM_FLAG_TAGYES) 不等于 0.
464  */
465 ACL_API int acl_vstream_readtags(ACL_VSTREAM *fp, void *vptr, size_t maxlen,
466  const char *tag, size_t taglen);
467 
468 /**
469  * 循环读取 maxlen 个数据, 直到读到 maxlen 个字节为止或读出错
470  * @param fp {ACL_VSTREAM*} 数据流
471  * @param vptr {void*} 用户的数据缓冲区指针地址
472  * @param maxlen {size_t} vptr 数据缓冲区的空间大小
473  * @return ret {int}, ret == ACL_VSTREAM_EOF: 读出错或对方关闭了连接, 应该
474  * 关闭本地数据流 n > 0: 成功读取了 maxlen 个字节的数据
475  * 如果实际读取的字节数与 maxlen 不相等也返回错误(ACL_VSTREAM_EOF)
476  */
477 ACL_API int acl_vstream_readn(ACL_VSTREAM *fp, void *vptr, size_t maxlen);
478 
479 /**
480  * 将缓冲区内的数据拷贝到 vptr 中
481  * @param fp {ACL_VSTREAM*} 数据流
482  * @param vptr {void*} 用户的数据缓冲区指针地址
483  * @param maxlen {size_t} vptr 数据缓冲区的空间大小
484  * @return ret {int}, ret == ACL_VSTREAM_EOF: 表示出错, 应该关闭本地数据流,
485  * ret >= 0: 成功从 fp 数据流的缓冲区中读取了 ret 个字节的数据
486  */
487 ACL_API int acl_vstream_bfcp_some(ACL_VSTREAM *fp, void *vptr, size_t maxlen);
488 
489 /**
490  * 从数据流中一次性读取 n 个数据, 该 n 有可能会小于用户所需要的 maxlen
491  * @param fp {ACL_VSTREAM*} 数据流
492  * @param vptr {void*} 用户的数据缓冲区指针地址
493  * @param maxlen {size_t} vptr 数据缓冲区的空间大小
494  * @return ret {int}, ret == ACL_VSTREAM_EOF: 表示出错, 应该关闭本地数据流,
495  * ret > 0: 表示读到了 ret 个字节的数据
496  * 注: 如果缓冲区内有数据, 则直接把缓冲区内的数据复制到用户的缓冲区然后直接返回;
497  * 如果缓冲区内无数据, 则需要调用系统读操作(有可能会阻塞在系统读操作上), 该
498  * 次调用返回后则把读到数据复制到用户缓冲区返回.
499  * 在这两种情况下都不能保证读到的字节数等于所要求的字节数, 若想读到所要求的
500  * 字节后才返回则请调用 vstream_loop_readn() 函数.
501  */
502 ACL_API int acl_vstream_read(ACL_VSTREAM *fp, void *vptr, size_t maxlen);
503 
504 /**
505  * 一次性从 ACL_VSTREAM 流或系统缓存区中读取一行数据, 包括回车换行符
506  * (调用者自行解决WINDOWS与UNIX对于回车换行的兼容性问题), 如果未读到
507  * 回车换行符, 也将数据拷贝至用户的内存缓冲区.
508  * @param fp {ACL_VSTREAM*} 数据流
509  * @param buf {ACL_VSTRING*} 数据缓冲区,当 buf->maxlen > 0 时,则限制每行数据
510  * 的长度,即当 buf 中的数据长度达到 maxlen 时,即使没有读到完整一行数据,该
511  * 函数也会返回,且会将 ready 置 1,调用者需调用 fp->flag 标志位中是否包含
512  * ACL_VSTREAM_FLAG_TAGYES 来判断是否读到一行数据
513  * @param ready {int*} 是否按要求读到所需数据的标志位指针, 不能为空
514  * @return ret {int}, ret == ACL_VSTREAM_EOF 时,如果 acl_last_error() 系统错误
515  * 号为 ACL_EWOULDBLOCK 或 ACL_EAGAIN,则表示在非阻塞套接字上未读到数据,否则,
516  * 表示出错,应该关闭该流对象;
517  * ret >= 0: 成功从 fp 数据流的缓冲区中读取了 ret 个字节的数据
518  */
519 ACL_API int acl_vstream_gets_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf, int *ready);
520 
521 /**
522  * 一次性从 ACL_VSTREAM 流或系统缓存区中读取一行数据, 如果未读到回车换行符,
523  * 也将数据拷贝至用户的内存缓冲区, 如果读到回车换行符便将回车换行符自动去掉,
524  * 并将回车换行符前的数据拷贝至用户内存区.
525  * @param fp {ACL_VSTREAM*} 数据流
526  * @param buf {ACL_VSTRING*} 数据缓冲区,当 buf->maxlen > 0 时,则限制每行数据
527  * 的长度,即当 buf 中的数据长度达到 maxlen 时,即使没有读到完整一行数据,该
528  * 函数也会返回,且会将 ready 置 1,调用者需调用 fp->flag 标志位中是否包含
529  * ACL_VSTREAM_FLAG_TAGYES 来判断是否读到一行数据
530  * @param ready {int*} 是否按要求读到所需数据的标志位指针, 不能为空
531  * @return ret {int}, ret == ACL_VSTREAM_EOF 时,如果 acl_last_error() 系统错误
532  * 号为 ACL_EWOULDBLOCK 或 ACL_EAGAIN,则表示在非阻塞套接字上未读到数据,否则,
533  * 表示出错,应该关闭该流对象;
534  * ret >= 0: 成功从 fp 数据流的缓冲区中读取了 ret 个字节的数据, 如果仅
535  * 读到了一个空行, 则 ret == 0.
536  */
537 ACL_API int acl_vstream_gets_nonl_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf, int *ready);
538 
539 /**
540  * 一次性从 ACL_VSTREAM 流或系统缓存区中读取固定长度的数据, 如果未读到所要求的
541  * 数据, 也将数据拷贝至用户内存缓冲区, 如果读到所要求的数据, 则将 ready 标志位置位.
542  * @param fp {ACL_VSTREAM*} 数据流
543  * @param buf {ACL_VSTRING*} 数据缓冲区
544  * @param cnt {int} 所需要读的数据的长度
545  * @param ready {int*} 是否按要求读到所需数据的标志位指针, 不能为空
546  * @return ret {int}, ret == ACL_VSTREAM_EOF 时,如果 acl_last_error() 系统错误
547  * 号为 ACL_EWOULDBLOCK 或 ACL_EAGAIN,则表示在非阻塞套接字上未读到数据,否则,
548  * 表示出错,应该关闭该流对象;
549  * ret >= 0: 成功从 fp 数据流的缓冲区中读取了 ret 个字节的数据,
550  * (*ready) != 0: 表示读到了所要求长度的数据.
551  */
552 ACL_API int acl_vstream_readn_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf, int cnt, int *ready);
553 
554 /**
555  * 一次性从 ACL_VSTREAM 流或系统缓存区中读取不固定长度的数据
556  * @param fp {ACL_VSTREAM*} 数据流
557  * @param buf {ACL_VSTRING*} 数据缓冲区
558  * @return ret {int}, ret == ACL_VSTREAM_EOF 时,如果 acl_last_error() 系统错误
559  * 号为 ACL_EWOULDBLOCK 或 ACL_EAGAIN,则表示在非阻塞套接字上未读到数据,否则,
560  * 表示出错,应该关闭该流对象;
561  * ret >= 0: 成功从 fp 数据流的缓冲区中读取了 ret 个字节的数据.
562  */
563 ACL_API int acl_vstream_read_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf);
564 
565 /**
566  * 一次性从 ACL_VSTREAM 流或系统缓存区中读取不固定长度的数据
567  * @param fp {ACL_VSTREAM*} 数据流
568  * @param buf {void*} 数据缓冲区
569  * @param size {size_t} buf 长度
570  * @return ret {int}, ret == ACL_VSTREAM_EOF 时,如果 acl_last_error() 系统错误
571  * 号为 ACL_EWOULDBLOCK 或 ACL_EAGAIN,则表示在非阻塞套接字上未读到数据,否则,
572  * 表示出错,应该关闭该流对象;
573  * ret >= 0: 成功从 fp 数据流的缓冲区中读取了 ret 个字节的数据.
574  */
575 ACL_API int acl_vstream_read_peek3(ACL_VSTREAM *fp, void *buf, size_t size);
576 
577 /**
578  * 检查 ACL_VSTREAM 流是否可读或出错
579  * @param fp {ACL_VSTREAM*} 数据流
580  * @return {int} 0: 表示无数据可读; ACL_VSTREAM_EOF 表示出错; > 0 表示有数据可读
581  */
582 ACL_API int acl_vstream_can_read(ACL_VSTREAM *fp);
583 
584 /**
585  * 将文件流中的系统缓冲区及流缓冲区中的数据都直接同步至硬盘
586  * @param fp {ACL_VSTREAM*} 文件流指针
587  * @return {int} 0: ok; ACL_VSTREAM_EOF: error
588  */
589 ACL_API int acl_vstream_fsync(ACL_VSTREAM *fp);
590 
591 /**
592  * 对于带缓冲方式的写,该函数保证缓冲区空间非空
593  * @param fp {ACL_VSTREAM*} 数据流
594  */
595 ACL_API void acl_vstream_buffed_space(ACL_VSTREAM *fp);
596 
597 /**
598  * 刷新写缓冲区里的数据
599  * @param fp socket 数据流
600  * @return 刷新写缓冲区里的数据量或出错 ACL_VSTREAM_EOF
601  */
602 ACL_API int acl_vstream_fflush(ACL_VSTREAM *fp);
603 
604 /**
605  * 带缓冲式写
606  * @param fp {ACL_VSTREAM*} 数据流
607  * @param vptr {const void*} 数据指针起始位置
608  * @param dlen {size_t} 要写入的数据量
609  * @return {int} 写入的数据量或出错 ACL_VSTREAM_EOF
610  */
611 ACL_API int acl_vstream_buffed_writen(ACL_VSTREAM *fp, const void *vptr, size_t dlen);
612 #define acl_vstream_buffed_fwrite acl_vstream_buffed_writen
613 
614 /**
615  * 缓冲带格式的流输出, 类似于 vfprintf()
616  * @param fp {ACL_VSTREAM*} 数据流
617  * @param fmt {const char*} 数据格式
618  * @param ap {va_list}
619  * @return ret {int}, ret == ACL_VSTREAM_EOF: 表示写出错, 应该关闭本地数据流,
620  * ret > 0: 表示成功写了 dlen 个字节的数据
621  */
622 ACL_API int acl_vstream_buffed_vfprintf(ACL_VSTREAM *fp, const char *fmt, va_list ap);
623 
624 /**
625  * 缓冲带格式的流输出, 类似于 fprintf()
626  * @param fp {ACL_VSTREAM*} 数据流
627  * @param fmt {const char*} 数据格式
628  * @param ... 变参序列
629  * @return ret {int}, ret == ACL_VSTREAM_EOF: 表示写出错, 应该关闭本地数据流,
630  * ret > 0: 表示成功写了 dlen 个字节的数据
631  */
632 ACL_API int ACL_PRINTF(2, 3) acl_vstream_buffed_fprintf(ACL_VSTREAM *fp,
633  const char *fmt, ...);
634 
635 /**
636  * 向标准输出打印信息
637  * @param ... 变参序列
638  * @return {int}, ACL_VSTREAM_EOF: 表示写出错, > 0: 表示成功写了 dlen 个字节的数据
639  */
640 ACL_API int acl_vstream_buffed_printf(const char*, ...);
641 
642 /**
643  * 向流缓冲区中写入一行数据
644  * @param s {const char*} 源字符串
645  * @param fp {ACL_VSTREAM*} 数据流
646  * @return {int} 0 成功; ACL_VSTREAM_EOF 失败
647  */
648 ACL_API int acl_vstream_buffed_fputs(const char *s, ACL_VSTREAM *fp);
649 
650 /**
651  * 向标准输出流缓冲区中写入一行数据
652  * @param s {const char*} 源字符串
653  * @return {int} 0 成功; ACL_VSTREAM_EOF 失败
654  */
655 ACL_API int acl_vstream_buffed_puts(const char *s);
656 
657 /**
658 * 一次性写入流操作, 返回实际写入的字节数.
659 * @param fp {ACL_VSTREAM*} 数据流
660 * @param vptr {const void*} 数据区指针地址
661 * @param dlen {int} 待写的数据区数据长度
662 * @return ret {int}, ret == ACL_VSTREAM_EOF: 表示写出错, 应该关闭本地数据流,
663 * ret > 0: 表示成功写了 ret 个字节的数据
664 */
665 ACL_API int acl_vstream_write(ACL_VSTREAM *fp, const void *vptr, int dlen);
666 
667 /**
668  * 一次性写入流操作,采用 writev 模式,返回实际写入的字节数
669  * @param fp {ACL_VSTREAM*}
670  * @param vector {const struct iovec*}
671  * @param count {int} vector 数组的长度
672  * @return {int} 返回成功写入的字节数,如果出错,则返回 ACL_VSTREAM_EOF
673  */
674 ACL_API int acl_vstream_writev(ACL_VSTREAM *fp, const struct iovec *vector, int count);
675 
676 /**
677  * 采用 writev 模式往流中写,直至全部数据写完为止或出错
678  * @param fp {ACL_VSTREAM*}
679  * @param vector {const struct iovec*}
680  * @param count {int} vector 数组的长度
681  * @return {int} 返回成功写入的字节数,如果出错,则返回 ACL_VSTREAM_EOF
682  */
683 ACL_API int acl_vstream_writevn(ACL_VSTREAM *fp, const struct iovec *vector, int count);
684 
685 /**
686  * 带格式的流输出, 类似于 vfprintf()
687  * @param fp {ACL_VSTREAM*} 数据流
688  * @param fmt {const char*} 数据格式
689  * @param ap {va_list}
690  * @return ret {int}, ret == ACL_VSTREAM_EOF: 表示写出错, 应该关闭本地数据流,
691  * ret > 0: 表示成功写了 dlen 个字节的数据
692  */
693 ACL_API int acl_vstream_vfprintf(ACL_VSTREAM *fp, const char *fmt, va_list ap);
694 
695 /**
696  * 带格式的流输出, 类似于 fprintf()
697  * @param fp {ACL_VSTREAM*} 数据流
698  * @param fmt {const char*} 数据格式
699  * @param ... 变参序列
700  * @return ret {int}, ret == ACL_VSTREAM_EOF: 表示写出错, 应该关闭本地数据流,
701  * ret > 0: 表示成功写了 dlen 个字节的数据
702  */
703 ACL_API int ACL_PRINTF(2, 3) acl_vstream_fprintf(ACL_VSTREAM *fp,
704  const char *fmt, ...);
705 
706 /**
707  * 向标准输出打印信息
708  * @param ... 变参序列
709  * @return {int}, ACL_VSTREAM_EOF: 表示写出错, > 0: 表示成功写了 dlen 个字节的数据
710  */
711 ACL_API int acl_vstream_printf(const char*, ...);
712 
713 /**
714  * 向流中写入一行数据
715  * @param s {const char*} 源字符串
716  * @param fp {ACL_VSTREAM*} 数据流
717  * @return {int} 0 成功; ACL_VSTREAM_EOF 失败
718  */
719 ACL_API int acl_vstream_fputs(const char *s, ACL_VSTREAM *fp);
720 
721 /**
722  * 向标准输出流中写入一行数据
723  * @param s {const char*} 源字符串
724  * @return {int} 0 成功; ACL_VSTREAM_EOF 失败
725  */
726 ACL_API int acl_vstream_puts(const char *s);
727 
728 /**
729  * 循环向数据流中写 dlen 个字节的数据直至写完或出错为止
730  * @param fp {ACL_VSTREAM*} 数据流
731  * @param vptr {const char*} 数据区指针地址
732  * @param dlen {size_t} 待写的数据区数据长度
733  * @return ret {int}, ret == ACL_VSTREAM_EOF: 表示写出错, 应该关闭本地数据流,
734  * ret > 0: 表示成功写了 dlen 个字节的数据
735  */
736 ACL_API int acl_vstream_writen(ACL_VSTREAM *fp, const void *vptr, size_t dlen);
737 #define acl_vstream_fwrite acl_vstream_writen
738 
739 /**
740  * 释放一个数据流的内存空间, 但并不关闭 socket 描述符
741  * @param fp {ACL_VSTREAM*} 数据流
742  */
743 ACL_API void acl_vstream_free(ACL_VSTREAM *fp);
744 
745 /**
746  * 释放一个数据流的内存空间并关闭其所携带的 socket 描述符
747  * @param fp {ACL_VSTREAM*} 数据流
748  */
749 ACL_API int acl_vstream_close(ACL_VSTREAM *fp);
750 #define acl_vstream_fclose acl_vstream_close
751 
752 /**
753  * 调用数据流中的所有关闭回调函数同时清除这些回调函数
754  * @param fp {ACL_VSTREAM*} 数据流
755  */
757 
758 /**
759  * 注册一个关闭函数
760  * @param fp {ACL_VSTREAM*} 数据流
761  * @param close_fn {void (*)(ACL_VSTREAM*, void*)} 关闭函数指针
762  * @param context {void*} close_fn 所需要的参数
763  */
765  void (*close_fn)(ACL_VSTREAM*, void*), void *context);
766 
767 /**
768  * 删除一个关闭句柄.
769  * @param fp {ACL_VSTREAM*} 数据流
770  * @param close_fn {void (*)(ACL_VSTREAM*, void*)} 关闭函数指针
771  * @param context {void*} close_fn 所需要的参数
772  */
774  void (*close_fn)(ACL_VSTREAM*, void*), void *context);
775 /**
776  * 清除一个数据流中所有的关闭句柄
777  * @param fp {ACL_VSTREAM*} 数据流
778  */
780 
781 /**
782  * 重新复位数据流的内部数据指针及计数值
783  * @param fp {ACL_VSTREAM*} 数据流
784  */
785 ACL_API void acl_vstream_reset(ACL_VSTREAM *fp);
786 
787 /**
788  * 取得当前数据流的错误状态
789  * @param fp {ACL_VSTREAM*} 数据流
790  * @return {const char*} 错误描述
791  */
792 ACL_API const char *acl_vstream_strerror(ACL_VSTREAM *fp);
793 
794 /*----------------------- 以下为常用的宏函数 ------------------------------*/
795 /**
796  * 从流中读取一个字节的宏实现,效率要比 acl_vstream_getc()/1 高
797  * @param stream_ptr {ACL_VSTREAM*} 数据流指针
798  * @return {int} ACL_VSTREAM_EOF(出错) 或所读到的某个字节的ASCII,
799  * 若为 ACL_VSTREAM_EOF: 读出错或对方关闭了连接, 应该关闭该数据流
800  */
801 #define ACL_VSTREAM_GETC(stream_ptr) ( \
802  (stream_ptr)->read_cnt > 0 ? \
803  (stream_ptr)->read_cnt--, \
804  (stream_ptr)->offset++, \
805  *(stream_ptr)->read_ptr++: \
806  (stream_ptr)->sys_getc((stream_ptr)))
807 
808 /**
809  * 向流中写一个字节的宏实现
810  * @param stream_ptr {ACL_VSTREAM*} 数据流指针
811  * @return {int} ACL_VSTREAM_EOF(出错) 或所写入字节的 ASCII
812  */
813 #define ACL_VSTREAM_PUTC(ch, stream_ptr) ( \
814  (stream_ptr)->wbuf_size == 0 ? \
815  (acl_vstream_buffed_space((stream_ptr)), \
816  ((stream_ptr)->wbuf[(size_t) (stream_ptr)->wbuf_dlen++] = (ch))) \
817  : ((stream_ptr)->wbuf_dlen == stream_ptr->wbuf_size ? \
818  (acl_vstream_fflush((stream_ptr)) == ACL_VSTREAM_EOF ? \
819  ACL_VSTREAM_EOF \
820  : ((stream_ptr)->wbuf[(size_t) (stream_ptr)->wbuf_dlen++] = (ch))) \
821  : ((stream_ptr)->wbuf[(size_t) (stream_ptr)->wbuf_dlen++] = (ch))))
822 
823 /**
824  * 由流获得套接字
825  * @param stream_ptr {ACL_VSTREAM*}
826  */
827 #define ACL_VSTREAM_SOCK(stream_ptr) ((stream_ptr)->fd.sock)
828 
829 /**
830  * 由流获得文件句柄
831  * @param stream_ptr {ACL_VSTREAM*}
832  */
833 #define ACL_VSTREAM_FILE(stream_ptr) ((stream_ptr)->fd.h_file)
834 
835 /**
836  * 获得文件流句柄的文件路径名
837  * @param stream_ptr {ACL_VSTREAM*}
838  */
839 #define ACL_VSTREAM_PATH(stream_ptr) ((stream_ptr)->path)
840 
841 /**
842  * 当 ACL_VSTREAM 为文件流时,设置文件流的路径
843  * @param fp {ACL_VSTREAM*} 文件流
844  * @param path {const char*} 文件路径
845  */
846 ACL_API void acl_vstream_set_path(ACL_VSTREAM *fp, const char *path);
847 
848 /**
849  * 当 ACL_VSTREAM 为网络流时,用此宏取得对方的地址
850  */
851 #define ACL_VSTREAM_PEER(stream_ptr) ((stream_ptr)->addr_peer)
852 
853 /**
854  * 当 ACL_VSTREAM 为网络流时,此函数设置远程连接地址
855  * @param fp {ACL_VSTREAM*} 网络流,非空
856  * @param addr {const char*} 远程连接地址,非空
857  */
858 ACL_API void acl_vstream_set_peer(ACL_VSTREAM *fp, const char *addr);
859 
860 /**
861  * 当 ACL_VSTREAM 为网络流时,此函数设置远程连接地址
862  * @param fp {ACL_VSTREAM*} 网络流,非空
863  * @param sa {const struct sockaddr *} 远程连接地址,非空
864  * @return {int} 返回值 == 0 表示成功,< 0 表示失败
865  */
866 ACL_API int acl_vstream_set_peer_addr(ACL_VSTREAM *fp, const struct sockaddr *sa);
867 
868 /**
869  * 当 ACL_VSTREAM 为网络流时,用此宏取得本地的地址
870  */
871 #define ACL_VSTREAM_LOCAL(stream_ptr) ((stream_ptr)->addr_local)
872 
873 /**
874  * 当 ACL_VSTREAM 为网络流时,此函数设置本地地址
875  * @param fp {ACL_VSTREAM*} 网络流,非空
876  * @param addr {const char*} 本地地址,非空
877  */
878 ACL_API void acl_vstream_set_local(ACL_VSTREAM *fp, const char *addr);
879 
880 /**
881  * 当 ACL_VSTREAM 为网络流时,此函数设置本地地址
882  * @param fp {ACL_VSTREAM*} 网络流,非空
883  * @param sa {const sockaddr*} 本地地址,非空
884  * @return {int} 返回值 == 0 表示成功,< 0 表示失败
885  */
886 ACL_API int acl_vstream_set_local_addr(ACL_VSTREAM *fp, const struct sockaddr *sa);
887 
888 ACL_API int acl_vstream_add_object(ACL_VSTREAM *fp, const char *key, void *obj);
889 ACL_API int acl_vstream_del_object(ACL_VSTREAM *fp, const char *key);
890 ACL_API void *acl_vstream_get_object(ACL_VSTREAM *fp, const char *key);
891 
892 ACL_API void acl_socket_read_hook(ACL_VSTREAM_RD_FN read_fn);
893 ACL_API void acl_socket_write_hook(ACL_VSTREAM_WR_FN write_fn);
894 ACL_API void acl_socket_writev_hook(ACL_VSTREAM_WV_FN writev_fn);
895 ACL_API void acl_socket_close_hook(int (*close_fn)(ACL_SOCKET));
896 
897 /**
898  * 设定流的读/写套接字
899  * @param stream_ptr {ACL_VSTREAM*}
900  * @param _fd {ACL_SOCKET} 套接字
901  */
902 #define ACL_VSTREAM_SET_SOCK(stream_ptr, _fd) do { \
903  ACL_VSTREAM *__stream_ptr = stream_ptr; \
904  __stream_ptr->fd.sock = _fd; \
905 } while (0)
906 
907 /**
908  * 设置流中的文件句柄
909  * @param stream_ptr {ACL_VSTREAM*}
910  * @param _fh {ACL_FILE_HANDLE}
911  */
912 #define ACL_VSTREAM_SET_FILE(stream_ptr, _fh) do { \
913  ACL_VSTREAM *__stream_ptr = stream_ptr; \
914  __stream_ptr->fd.h_file = _fh; \
915 } while (0)
916 
917 /* 一些比较快速的宏的运算模式 */
918 
919 /**
920  * 流中在读缓冲区中的数据量大小
921  * @param stream_ptr {ACL_VSTREAM*) 类型的指针
922  * @return -1: 表示出错, >= 0 此值即为流读缓冲区中的数据量大小
923  */
924 #define ACL_VSTREAM_BFRD_CNT(stream_ptr) \
925  ((stream_ptr) == NULL ? -1 : (stream_ptr)->read_cnt)
926 
927 /**
928  * 设定流的读写超时值
929  * @param stream_ptr {ACL_VSTREAM*) 类型的指针
930  * @param _rw_timeo {int} 超时值大小(以秒为单位)
931  */
932 #define ACL_VSTREAM_SET_RWTIMO(stream_ptr, _rw_timeo) do { \
933  ACL_VSTREAM *__stream_ptr = stream_ptr; \
934  __stream_ptr->rw_timeout = _rw_timeo; \
935 } while (0)
936 
937 /**
938  * 将流置为结束状态
939  * @param stream_ptr {ACL_VSTREAM*) 类型的指针
940  */
941 #define ACL_VSTREAM_SET_EOF(stream_ptr) do { \
942  ACL_VSTREAM *__stream_ptr = stream_ptr; \
943  __stream_ptr->flag |= ACL_VSTREAM_FLAG_EOF; \
944 } while (0)
945 
946 /**
947  * 判断数据流是否出了错
948  * @param stream_ptr: ACL_VSTREAM 类型的指针
949  * @return 0表示正常, 非0表示出错
950  */
951 #define ACL_IF_VSTREAM_ERR(stream_ptr) \
952  ((stream_ptr)->flag & ACL_VSTREAM_FLAG_BAD)
953 
954 #ifdef __cplusplus
955 }
956 #endif
957 
958 /**
959  * 从数据流中取出与该流读写有关的系统错误号
960  * @param stream_ptr {ACL_VSTREAM*) 类型的指针
961  * @return err {int} 整形错误号,调用者可以用 strerror(err) 的方式查看具体含义
962  */
963 #define ACL_VSTREAM_ERRNO(stream_ptr) ((stream_ptr)->errnum)
964 
965 /**
966  * 判断一个流是否超时
967  * @param stream_ptr {ACL_VSTREAM*) 类型的指针
968  * @return {int} 0: 否; != 0: 是
969  */
970 #define acl_vstream_ftimeout(stream_ptr) \
971  ((stream_ptr)->flag & ACL_VSTREAM_FLAG_TIMEOUT)
972 
973 #endif
unsigned int oflags
Definition: acl_vstream.h:182
unsigned int flag
Definition: acl_vstream.h:104
ACL_API int acl_vstream_set_local_addr(ACL_VSTREAM *fp, const struct sockaddr *sa)
ACL_FSTREAM_RD_FN fread_fn
Definition: acl_vstream.h:175
ACL_API int const char ACL_API int acl_vstream_buffed_printf(const char *,...)
ACL_API int acl_vstream_readn(ACL_VSTREAM *fp, void *vptr, size_t maxlen)
void * context
Definition: acl_vstream.h:163
ACL_API int acl_vstream_buffed_puts(const char *s)
ACL_API int acl_vstream_buffed_vfprintf(ACL_VSTREAM *fp, const char *fmt, va_list ap)
ACL_API int const char ACL_API int acl_vstream_printf(const char *,...)
ACL_API int acl_vstream_puts(const char *s)
ACL_HTABLE * objs_table
Definition: acl_vstream.h:202
ACL_API int acl_vstream_vfprintf(ACL_VSTREAM *fp, const char *fmt, va_list ap)
ACL_API void acl_vstream_ctl(ACL_VSTREAM *fp, int name,...)
HTTP_API void const char * name
Definition: lib_http.h:620
ACL_API ACL_VSTREAM acl_vstream_fstd[]
ACL_API int acl_file_truncate(const char *path, acl_off_t length)
int is_nonblock
Definition: acl_vstream.h:72
ACL_API void * acl_vstream_get_object(ACL_VSTREAM *fp, const char *key)
ACL_API ACL_VSTREAM * acl_vstream_fdopen(ACL_SOCKET fd, unsigned int oflags, size_t buflen, int rw_timeo, int fdtype)
ACL_API int acl_vstream_write(ACL_VSTREAM *fp, const void *vptr, int dlen)
struct ACL_VSTREAM_CLOSE_HANDLE ACL_VSTREAM_CLOSE_HANDLE
ACL_API ACL_VSTREAM * acl_vstream_fopen(const char *path, unsigned int oflags, int mode, size_t buflen)
unsigned int omode
Definition: acl_vstream.h:191
ACL_ARRAY * close_handle_lnk
Definition: acl_vstream.h:165
ACL_API int acl_vstream_buffed_writen(ACL_VSTREAM *fp, const void *vptr, size_t dlen)
char * addr_peer
Definition: acl_vstream.h:155
int(* close_fn)(ACL_SOCKET)
Definition: acl_vstream.h:179
int(* ACL_VSTREAM_WR_FN)(ACL_SOCKET fd, const void *buf, size_t size, int timeout, ACL_VSTREAM *fp, void *context)
Definition: acl_vstream.h:46
ACL_API int acl_vstream_fsync(ACL_VSTREAM *fp)
size_t sa_local_size
Definition: acl_vstream.h:158
int(* ACL_FSTREAM_WV_FN)(ACL_FILE_HANDLE fh, const struct iovec *vec, int count, int timeout, ACL_VSTREAM *fp, void *context)
Definition: acl_vstream.h:54
ACL_VSTREAM_WR_FN write_fn
Definition: acl_vstream.h:172
int(* ACL_FSTREAM_WR_FN)(ACL_FILE_HANDLE fh, const void *buf, size_t size, int timeout, ACL_VSTREAM *fp, void *context)
Definition: acl_vstream.h:52
ACL_API int acl_vstream_fstat(ACL_VSTREAM *fp, struct acl_stat *buf)
ACL_API void acl_vstream_set_local(ACL_VSTREAM *fp, const char *addr)
void * ioctl_read_ctx
Definition: acl_vstream.h:100
char * path
Definition: acl_vstream.h:162
ACL_API void acl_socket_close_hook(int(*close_fn)(ACL_SOCKET))
ACL_API int ACL_PRINTF(2, 3) acl_vstream_buffed_fprintf(ACL_VSTREAM *fp
ACL_API acl_off_t acl_vstream_ftell(ACL_VSTREAM *fp)
ACL_API void acl_vstream_clean_close_handle(ACL_VSTREAM *fp)
int(* sys_getc)(ACL_VSTREAM *)
Definition: acl_vstream.h:170
ACL_API int acl_vstream_writev(ACL_VSTREAM *fp, const struct iovec *vector, int count)
ACL_API void acl_vstream_delete_close_handle(ACL_VSTREAM *fp, void(*close_fn)(ACL_VSTREAM *, void *), void *context)
ACL_API void acl_vstream_call_close_handles(ACL_VSTREAM *fp)
union ACL_VSTREAM::@5 fd
acl_off_t total_read_cnt
Definition: acl_vstream.h:97
unsigned char * read_ptr
Definition: acl_vstream.h:94
struct sockaddr * sa_local
Definition: acl_vstream.h:156
ACL_API void acl_vstream_init(void)
ACL_FILE_HANDLE h_file
Definition: acl_vstream.h:69
int(* ACL_VSTREAM_RD_FN)(ACL_SOCKET fd, void *buf, size_t size, int timeout, ACL_VSTREAM *fp, void *context)
Definition: acl_vstream.h:44
ACL_API int acl_vstream_gets_nonl(ACL_VSTREAM *fp, void *vptr, size_t maxlen)
ACL_API int acl_vstream_writen(ACL_VSTREAM *fp, const void *vptr, size_t dlen)
int(* fclose_fn)(ACL_FILE_HANDLE)
Definition: acl_vstream.h:180
ACL_API int acl_vstream_can_read(ACL_VSTREAM *fp)
ACL_API void acl_vstream_free(ACL_VSTREAM *fp)
ACL_API void acl_socket_write_hook(ACL_VSTREAM_WR_FN write_fn)
ACL_API void acl_socket_writev_hook(ACL_VSTREAM_WV_FN writev_fn)
ACL_API int acl_vstream_close(ACL_VSTREAM *fp)
ACL_API int acl_vstream_bfcp_some(ACL_VSTREAM *fp, void *vptr, size_t maxlen)
size_t sa_peer_len
Definition: acl_vstream.h:161
ACL_API int acl_vstream_read(ACL_VSTREAM *fp, void *vptr, size_t maxlen)
ACL_API int acl_vstream_getc(ACL_VSTREAM *fp)
ACL_API int acl_vstream_gets(ACL_VSTREAM *fp, void *vptr, size_t maxlen)
ACL_SOCKET sock
Definition: acl_vstream.h:68
ACL_VSTREAM_RD_FN read_fn
Definition: acl_vstream.h:171
int(* ACL_VSTREAM_WV_FN)(ACL_SOCKET fd, const struct iovec *vec, int count, int timeout, ACL_VSTREAM *fp, void *context)
Definition: acl_vstream.h:48
ACL_API int acl_vstream_ungetc(ACL_VSTREAM *fp, int ch)
ACL_API int acl_vstream_add_object(ACL_VSTREAM *fp, const char *key, void *obj)
int(* ACL_FSTREAM_RD_FN)(ACL_FILE_HANDLE fh, void *buf, size_t size, int timeout, ACL_VSTREAM *fp, void *context)
Definition: acl_vstream.h:50
acl_off_t sys_offset
Definition: acl_vstream.h:85
ACL_API ACL_VSTREAM * acl_vstream_fhopen(ACL_FILE_HANDLE fh, unsigned int oflags)
ACL_API void acl_vstream_buffed_space(ACL_VSTREAM *fp)
size_t sa_local_len
Definition: acl_vstream.h:160
ACL_API int acl_vstream_peekfd(ACL_VSTREAM *fp)
ACL_API acl_off_t acl_vstream_fseek2(ACL_VSTREAM *fp, acl_off_t offset, int whence)
ACL_API char * acl_vstream_loadfile2(const char *path, ssize_t *size)
ACL_FSTREAM_WV_FN fwritev_fn
Definition: acl_vstream.h:177
ACL_API int acl_vstream_set_peer_addr(ACL_VSTREAM *fp, const struct sockaddr *sa)
ACL_API void acl_vstream_set_peer(ACL_VSTREAM *fp, const char *addr)
ACL_API void acl_vstream_set_path(ACL_VSTREAM *fp, const char *path)
size_t sa_peer_size
Definition: acl_vstream.h:159
ACL_API int acl_vstream_fflush(ACL_VSTREAM *fp)
acl_off_t total_write_cnt
Definition: acl_vstream.h:98
ACL_API int acl_vstream_nonb_readn(ACL_VSTREAM *fp, char *buf, int size)
ACL_FSTREAM_WR_FN fwrite_fn
Definition: acl_vstream.h:176
ACL_API int acl_vstream_del_object(ACL_VSTREAM *fp, const char *key)
ACL_API int acl_vstream_probe_status(ACL_VSTREAM *fp)
void * ioctl_write_ctx
Definition: acl_vstream.h:101
ACL_API int acl_vstream_gets_nonl_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf, int *ready)
ACL_API acl_int64 acl_vstream_fsize(ACL_VSTREAM *fp)
ACL_API int acl_file_ftruncate(ACL_VSTREAM *fp, acl_off_t length)
acl_off_t offset
Definition: acl_vstream.h:84
int read_ready
Definition: acl_vstream.h:95
ACL_API int acl_vstream_read_peek3(ACL_VSTREAM *fp, void *buf, size_t size)
ACL_API acl_off_t acl_vstream_fseek(ACL_VSTREAM *fp, acl_off_t offset, int whence)
ACL_API void acl_vstream_reset(ACL_VSTREAM *fp)
int read_buf_len
Definition: acl_vstream.h:92
ACL_API int acl_vstream_fputs(const char *s, ACL_VSTREAM *fp)
ACL_API const char * acl_vstream_strerror(ACL_VSTREAM *fp)
struct sockaddr * sa_peer
Definition: acl_vstream.h:157
ACL_API void acl_vstream_add_close_handle(ACL_VSTREAM *fp, void(*close_fn)(ACL_VSTREAM *, void *), void *context)
ACL_API char * acl_vstream_loadfile(const char *path)
ACL_API int acl_vstream_buffed_fputs(const char *s, ACL_VSTREAM *fp)
ACL_API int acl_vstream_readtags(ACL_VSTREAM *fp, void *vptr, size_t maxlen, const char *tag, size_t taglen)
ACL_API int const char * fmt
Definition: acl_vstream.h:633
unsigned char * read_buf
Definition: acl_vstream.h:91
void(* close_fn)(ACL_VSTREAM *, void *)
Definition: acl_vstream.h:61
unsigned char * wbuf
Definition: acl_vstream.h:87
ACL_API void acl_socket_read_hook(ACL_VSTREAM_RD_FN read_fn)
ACL_API int acl_vstream_gets_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf, int *ready)
acl_int64 acl_off_t
Definition: acl_define.h:12
ACL_API int acl_vstream_writevn(ACL_VSTREAM *fp, const struct iovec *vector, int count)
char * addr_local
Definition: acl_vstream.h:154
ACL_API int acl_vstream_readn_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf, int cnt, int *ready)
ACL_API int acl_vstream_set_fdtype(ACL_VSTREAM *fp, int type)
ACL_API ACL_VSTREAM * acl_vstream_clone(const ACL_VSTREAM *stream_src)
ACL_VSTREAM_WV_FN writev_fn
Definition: acl_vstream.h:173
ACL_API int acl_vstream_unread(ACL_VSTREAM *fp, const void *ptr, size_t length)
ACL_API int acl_vstream_read_peek(ACL_VSTREAM *fp, ACL_VSTRING *buf)
void * fdp
Definition: acl_vstream.h:102