Postfix3.3.1
vbuf.h
[詳解]
1 #ifndef _VBUF_H_INCLUDED_
2 #define _VBUF_H_INCLUDED_
3 
4 /*++
5 /* NAME
6 /* vbuf 3h
7 /* SUMMARY
8 /* generic buffer
9 /* SYNOPSIS
10 /* #include <vbuf.h>
11 /* DESCRIPTION
12 /* .nf
13 
14  /*
15  * The VBUF buffer is defined by 1) its structure, by 2) the VBUF_GET() and
16  * 3) VBUF_PUT() operations that automatically handle buffer empty and
17  * buffer full conditions, and 4) by the VBUF_SPACE() operation that allows
18  * the user to reserve buffer space ahead of time, to allow for situations
19  * where calling VBUF_PUT() is not possible or desirable.
20  *
21  * The VBUF buffer does not specify primitives for memory allocation or
22  * deallocation. The purpose is to allow different applications to have
23  * different strategies: a memory-resident buffer; a memory-mapped file; or
24  * a stdio-like window to an open file. Each application provides its own
25  * get(), put() and space() methods that perform the necessary magic.
26  *
27  * This interface is pretty normal. With one exception: the number of bytes
28  * left to read is negated. This is done so that we can change direction
29  * between reading and writing on the fly. The alternative would be to use
30  * separate read and write counters per buffer.
31  */
32 typedef struct VBUF VBUF;
33 typedef int (*VBUF_GET_READY_FN) (VBUF *);
34 typedef int (*VBUF_PUT_READY_FN) (VBUF *);
35 typedef int (*VBUF_SPACE_FN) (VBUF *, ssize_t);
36 
37 struct VBUF {
38  int flags; /* status, see below */
39  unsigned char *data; /* variable-length buffer */
40  ssize_t len; /* buffer length */
41  ssize_t cnt; /* bytes left to read/write */
42  unsigned char *ptr; /* read/write position */
43  VBUF_GET_READY_FN get_ready; /* read buffer empty action */
44  VBUF_PUT_READY_FN put_ready; /* write buffer full action */
45  VBUF_SPACE_FN space; /* request for buffer space */
46 };
47 
48  /*
49  * Typically, an application will embed a VBUF structure into a larger
50  * structure that also contains application-specific members. This approach
51  * gives us the best of both worlds. The application can still use the
52  * generic VBUF primitives for reading and writing VBUFs. The macro below
53  * transforms a pointer from VBUF structure to the structure that contains
54  * it.
55  */
56 #define VBUF_TO_APPL(vbuf_ptr,app_type,vbuf_member) \
57  ((app_type *) (((char *) (vbuf_ptr)) - offsetof(app_type,vbuf_member)))
58 
59  /*
60  * Buffer status management.
61  */
62 #define VBUF_FLAG_RD_ERR (1<<0) /* read error */
63 #define VBUF_FLAG_WR_ERR (1<<1) /* write error */
64 #define VBUF_FLAG_ERR (VBUF_FLAG_RD_ERR | VBUF_FLAG_WR_ERR)
65 #define VBUF_FLAG_EOF (1<<2) /* end of data */
66 #define VBUF_FLAG_RD_TIMEOUT (1<<3) /* read timeout */
67 #define VBUF_FLAG_WR_TIMEOUT (1<<4) /* write timeout */
68 #define VBUF_FLAG_TIMEOUT (VBUF_FLAG_RD_TIMEOUT | VBUF_FLAG_WR_TIMEOUT)
69 #define VBUF_FLAG_BAD (VBUF_FLAG_ERR | VBUF_FLAG_EOF | VBUF_FLAG_TIMEOUT)
70 #define VBUF_FLAG_FIXED (1<<5) /* fixed-size buffer */
71 
72 #define vbuf_rd_error(v) ((v)->flags & (VBUF_FLAG_RD_ERR | VBUF_FLAG_RD_TIMEOUT))
73 #define vbuf_wr_error(v) ((v)->flags & (VBUF_FLAG_WR_ERR | VBUF_FLAG_WR_TIMEOUT))
74 #define vbuf_rd_timeout(v) ((v)->flags & VBUF_FLAG_RD_TIMEOUT)
75 #define vbuf_wr_timeout(v) ((v)->flags & VBUF_FLAG_WR_TIMEOUT)
76 
77 #define vbuf_error(v) ((v)->flags & (VBUF_FLAG_ERR | VBUF_FLAG_TIMEOUT))
78 #define vbuf_eof(v) ((v)->flags & VBUF_FLAG_EOF)
79 #define vbuf_timeout(v) ((v)->flags & VBUF_FLAG_TIMEOUT)
80 #define vbuf_clearerr(v) ((v)->flags &= ~VBUF_FLAG_BAD)
81 
82  /*
83  * Buffer I/O-like operations and results.
84  */
85 #define VBUF_GET(v) ((v)->cnt < 0 ? ++(v)->cnt, \
86  (int) *(v)->ptr++ : vbuf_get(v))
87 #define VBUF_PUT(v,c) ((v)->cnt > 0 ? --(v)->cnt, \
88  (int) (*(v)->ptr++ = (c)) : vbuf_put((v),(c)))
89 #define VBUF_SPACE(v,n) ((v)->space((v),(n)))
90 
91 #define VBUF_EOF (-1) /* no more space or data */
92 
93 extern int vbuf_get(VBUF *);
94 extern int vbuf_put(VBUF *, int);
95 extern int vbuf_unget(VBUF *, int);
96 extern ssize_t vbuf_read(VBUF *, void *, ssize_t);
97 extern ssize_t vbuf_write(VBUF *, const void *, ssize_t);
98 
99 /* LICENSE
100 /* .ad
101 /* .fi
102 /* The Secure Mailer license must be distributed with this software.
103 /* AUTHOR(S)
104 /* Wietse Venema
105 /* IBM T.J. Watson Research
106 /* P.O. Box 704
107 /* Yorktown Heights, NY 10598, USA
108 /*--*/
109 
110 #endif
int vbuf_unget(VBUF *, int)
Definition: vbuf.c:156
VBUF_GET_READY_FN get_ready
Definition: vbuf.h:43
ssize_t cnt
Definition: vbuf.h:41
unsigned char * ptr
Definition: vbuf.h:42
int(* VBUF_PUT_READY_FN)(VBUF *)
Definition: vbuf.h:34
unsigned char * data
Definition: vbuf.h:39
ssize_t vbuf_read(VBUF *, void *, ssize_t)
Definition: vbuf.c:184
int(* VBUF_SPACE_FN)(VBUF *, ssize_t)
Definition: vbuf.h:35
int vbuf_put(VBUF *, int)
Definition: vbuf.c:177
int flags
Definition: vbuf.h:38
Definition: vbuf.h:37
VBUF_SPACE_FN space
Definition: vbuf.h:45
int(* VBUF_GET_READY_FN)(VBUF *)
Definition: vbuf.h:33
ssize_t vbuf_write(VBUF *, const void *, ssize_t)
Definition: vbuf.c:210
VBUF_PUT_READY_FN put_ready
Definition: vbuf.h:44
int int
Definition: smtpd_proxy.h:21
ssize_t len
Definition: vbuf.h:40
int vbuf_get(VBUF *)
Definition: vbuf.c:170