3 #ifndef _VBUF_H_INCLUDED_
4 #define _VBUF_H_INCLUDED_
17 * The VBUF buffer is defined by 1) its structure, by 2) the VBUF_GET() and
18 * 3) VBUF_PUT() operations that automatically handle buffer empty and
19 * buffer full conditions, and 4) by the VBUF_SPACE() operation that allows
20 * the user to reserve buffer space ahead of time, to allow for situations
21 * where calling VBUF_PUT() is not possible or desirable.
23 * The VBUF buffer does not specify primitives for memory allocation or
24 * deallocation. The purpose is to allow different applications to have
25 * different strategies: a memory-resident buffer; a memory-mapped file; or
26 * a stdio-like window to an open file. Each application provides its own
27 * get(), put() and space() methods that perform the necessary magic.
29 * This interface is pretty normal. With one exception: the number of bytes
30 * left to read is negated. This is done so that we can change direction
31 * between reading and writing on the fly. The alternative would be to use
32 * separate read and write counters per buffer.
34 typedef struct VBUF VBUF
;
35 typedef int (*VBUF_GET_READY_FN
) (VBUF
*);
36 typedef int (*VBUF_PUT_READY_FN
) (VBUF
*);
37 typedef int (*VBUF_SPACE_FN
) (VBUF
*, ssize_t
);
40 int flags
; /* status, see below */
41 unsigned char *data
; /* variable-length buffer */
42 ssize_t len
; /* buffer length */
43 ssize_t cnt
; /* bytes left to read/write */
44 unsigned char *ptr
; /* read/write position */
45 VBUF_GET_READY_FN get_ready
; /* read buffer empty action */
46 VBUF_PUT_READY_FN put_ready
; /* write buffer full action */
47 VBUF_SPACE_FN space
; /* request for buffer space */
51 * Typically, an application will embed a VBUF structure into a larger
52 * structure that also contains application-specific members. This approach
53 * gives us the best of both worlds. The application can still use the
54 * generic VBUF primitives for reading and writing VBUFs. The macro below
55 * transforms a pointer from VBUF structure to the structure that contains
58 #define VBUF_TO_APPL(vbuf_ptr,app_type,vbuf_member) \
59 ((app_type *) (((char *) (vbuf_ptr)) - offsetof(app_type,vbuf_member)))
62 * Buffer status management.
64 #define VBUF_FLAG_ERR (1<<0) /* some I/O error */
65 #define VBUF_FLAG_EOF (1<<1) /* end of data */
66 #define VBUF_FLAG_TIMEOUT (1<<2) /* timeout error */
67 #define VBUF_FLAG_BAD (VBUF_FLAG_ERR | VBUF_FLAG_EOF | VBUF_FLAG_TIMEOUT)
68 #define VBUF_FLAG_FIXED (1<<3) /* fixed-size buffer */
70 #define vbuf_error(v) ((v)->flags & (VBUF_FLAG_ERR | VBUF_FLAG_TIMEOUT))
71 #define vbuf_eof(v) ((v)->flags & VBUF_FLAG_EOF)
72 #define vbuf_timeout(v) ((v)->flags & VBUF_FLAG_TIMEOUT)
73 #define vbuf_clearerr(v) ((v)->flags &= ~VBUF_FLAG_BAD)
76 * Buffer I/O-like operations and results.
78 #define VBUF_GET(v) ((v)->cnt < 0 ? ++(v)->cnt, \
79 (int) *(v)->ptr++ : vbuf_get(v))
80 #define VBUF_PUT(v,c) ((v)->cnt > 0 ? --(v)->cnt, \
81 (int) (*(v)->ptr++ = (c)) : vbuf_put((v),(c)))
82 #define VBUF_SPACE(v,n) ((v)->space((v),(n)))
84 #define VBUF_EOF (-1) /* no more space or data */
86 extern int vbuf_get(VBUF
*);
87 extern int vbuf_put(VBUF
*, int);
88 extern int vbuf_unget(VBUF
*, int);
89 extern ssize_t
vbuf_read(VBUF
*, char *, ssize_t
);
90 extern ssize_t
vbuf_write(VBUF
*, const char *, ssize_t
);
95 /* The Secure Mailer license must be distributed with this software.
98 /* IBM T.J. Watson Research
100 /* Yorktown Heights, NY 10598, USA