acl/lib_acl/include/stdlib/acl_vbuf.h
2022-09-14 16:24:54 +08:00

91 lines
2.9 KiB
C

#ifndef ACL_VBUF_INCLUDE_H
#define ACL_VBUF_INCLUDE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "acl_define.h"
#include "acl_dbuf_pool.h"
#include "acl_slice.h"
typedef struct ACL_VBUF ACL_VBUF;
typedef int (*ACL_VBUF_GET_READY_FN) (ACL_VBUF *);
typedef int (*ACL_VBUF_PUT_READY_FN) (ACL_VBUF *);
typedef int (*ACL_VBUF_SPACE_FN) (ACL_VBUF *, ssize_t);
struct ACL_VBUF {
unsigned char *data; /* variable-length buffer */
unsigned char *ptr; /* read/write position */
ssize_t len; /* buffer length */
unsigned flags; /* status, see below */
ACL_FILE_HANDLE fd;
#if defined(_WIN32) || defined(_WIN64)
ACL_FILE_HANDLE hmap;
#endif
union {
ACL_SLICE_POOL *slice;
ACL_DBUF_POOL *dbuf;
} alloc;
#if 0
ACL_VBUF_GET_READY_FN get_ready; /* read buffer empty action */
ACL_VBUF_PUT_READY_FN put_ready; /* write buffer full action */
ACL_VBUF_SPACE_FN space; /* request for buffer space */
#endif
};
/*
* Typically, an application will embed a VBUF structure into a larger
* structure that also contains application-specific members. This approach
* gives us the best of both worlds. The application can still use the
* generic VBUF primitives for reading and writing VBUFs. The macro below
* transforms a pointer from VBUF structure to the structure that contains
* it.
*/
#define ACL_VBUF_TO_APPL(vbuf_ptr,app_type,vbuf_member) \
((app_type *) (((char *) (vbuf_ptr)) - offsetof(app_type,vbuf_member)))
/*
* Buffer status management.
*/
#define ACL_VBUF_FLAG_ERR (1<<0) /* some I/O error */
#define ACL_VBUF_FLAG_EOF (1<<1) /* end of data */
#define ACL_VBUF_FLAG_TIMEOUT (1<<2) /* timeout error */
#define ACL_VBUF_FLAG_BAD \
(ACL_VBUF_FLAG_ERR | ACL_VBUF_FLAG_EOF | ACL_VBUF_FLAG_TIMEOUT)
#define ACL_VBUF_FLAG_FIXED (1<<3) /* fixed-size buffer */
#define ACL_VBUF_FLAG_SLICE (1<<4) /* use slice allocator */
#define ACL_VBUF_FLAG_DBUF (1<<5) /* use dbuf allocator */
#define ACL_VBUF_FLAG_MMAP (1<<6) /* use file mmap allocator */
#define acl_vbuf_error(v) ((v)->flags & ACL_VBUF_FLAG_BAD)
#define acl_vbuf_eof(v) ((v)->flags & ACL_VBUF_FLAG_EOF)
#define acl_vbuf_timeout(v) ((v)->flags & ACL_VBUF_FLAG_TIMEOUT)
#define acl_vbuf_clearerr(v) ((v)->flags &= ~ACL_VBUF_FLAG_BAD)
#define ACL_VBUF_PUT(v,c) ((v)->ptr < (v)->data + (v)->len ? \
(int) (*(v)->ptr++ = (c)) : acl_vbuf_put((v),(c)))
ACL_API int acl_vbuf_space(struct ACL_VBUF *bp, ssize_t len);
#define ACL_VBUF_SPACE acl_vbuf_space
#define ACL_VBUF_TERM(v) ((v)->ptr < (v)->data + (v)->len ? \
*(v)->ptr = 0 : ACL_VBUF_SPACE((v), 1), *(v)->ptr = 0)
#define ACL_VBUF_CHARAT(v, offset) ((int) (v).data[offset])
#define ACL_VBUF_EOF (-1) /* no more space or data */
ACL_API int acl_vbuf_put(ACL_VBUF *, int);
ACL_API int acl_vbuf_write(ACL_VBUF *, const char *, int);
#ifdef __cplusplus
}
#endif
#endif