1
#ifndef _VBUF_H_INCLUDED_
2
#define _VBUF_H_INCLUDED_
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.
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.
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.
31
typedef struct VBUF VBUF;
32
typedef int (*VBUF_GET_READY_FN) (VBUF *);
33
typedef int (*VBUF_PUT_READY_FN) (VBUF *);
34
typedef int (*VBUF_SPACE_FN) (VBUF *, int);
37
int flags; /* status, see below */
38
unsigned char *data; /* variable-length buffer */
39
int len; /* buffer length */
40
int cnt; /* bytes left to read/write */
41
unsigned char *ptr; /* read/write position */
42
VBUF_GET_READY_FN get_ready; /* read buffer empty action */
43
VBUF_PUT_READY_FN put_ready; /* write buffer full action */
44
VBUF_SPACE_FN space; /* request for buffer space */
48
* Typically, an application will embed a VBUF structure into a larger
49
* structure that also contains application-specific members. This approach
50
* gives us the best of both worlds. The application can still use the
51
* generic VBUF primitives for reading and writing VBUFs. The macro below
52
* transforms a pointer from VBUF structure to the structure that contains
55
#define VBUF_TO_APPL(vbuf_ptr,app_type,vbuf_member) \
56
((app_type *) (((char *) (vbuf_ptr)) - offsetof(app_type,vbuf_member)))
59
* Buffer status management.
61
#define VBUF_FLAG_ERR (1<<0) /* some I/O error */
62
#define VBUF_FLAG_EOF (1<<1) /* end of data */
63
#define VBUF_FLAG_TIMEOUT (1<<2) /* timeout error */
64
#define VBUF_FLAG_BAD (VBUF_FLAG_ERR | VBUF_FLAG_EOF | VBUF_FLAG_TIMEOUT)
65
#define VBUF_FLAG_FIXED (1<<3) /* fixed-size buffer */
67
#define vbuf_error(v) ((v)->flags & VBUF_FLAG_ERR)
68
#define vbuf_eof(v) ((v)->flags & VBUF_FLAG_EOF)
69
#define vbuf_timeout(v) ((v)->flags & VBUF_FLAG_TIMEOUT)
70
#define vbuf_clearerr(v) ((v)->flags &= ~VBUF_FLAG_BAD)
73
* Buffer I/O-like operations and results.
75
#define VBUF_GET(v) ((v)->cnt < 0 ? ++(v)->cnt, \
76
(int) *(v)->ptr++ : vbuf_get(v))
77
#define VBUF_PUT(v,c) ((v)->cnt > 0 ? --(v)->cnt, \
78
(int) (*(v)->ptr++ = (c)) : vbuf_put((v),(c)))
79
#define VBUF_SPACE(v,n) ((v)->space((v),(n)))
81
#define VBUF_EOF (-1) /* no more space or data */
83
extern int vbuf_get(VBUF *);
84
extern int vbuf_put(VBUF *, int);
85
extern int vbuf_unget(VBUF *, int);
86
extern int vbuf_read(VBUF *, char *, int);
87
extern int vbuf_write(VBUF *, const char *, int);
92
/* The Secure Mailer license must be distributed with this software.
95
/* IBM T.J. Watson Research
97
/* Yorktown Heights, NY 10598, USA