/*
* Copyright (c) 2002-2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: rcb.h,v 1.67 2007/01/31 04:18:17 ca Exp $
*/
#ifndef SM_RCB_H
#define SM_RCB_H 1
/*
** Notice: This is almost a copy of sm/str.h
*/
#include "sm/generic.h"
#include "sm/types.h"
#include "sm/error.h"
#include "sm/magic.h"
#include "sm/rpool.h"
#include "sm/str.h"
#if SM_RCB_ST
# include "statethreads/st.h"
#endif
#if !SM_NO_CSTR
# include "sm/cstr.h"
#endif
#ifndef SM_STR_READ
# define SM_STR_READ 1
#endif
#ifndef MTA_USE_RCBV_INT2
# define MTA_USE_RCBV_INT2 1
#endif
#ifndef MTA_USE_RCBV_INTN
# define MTA_USE_RCBV_INTN 1
#endif
#ifndef MTA_USE_RCBV_STRN
# define MTA_USE_RCBV_STRN 0
#endif
#if SM_STR_CHECK
# ifndef SM_RCB_CHECK
# define SM_RCB_CHECK 1
# endif
#endif
#ifndef SM_RCB_END_RCB
/* activate code to mark end of RCB: currently broken! */
# define SM_RCB_END_RCB 0
#endif
typedef struct sm_rcb_S sm_rcb_T, *sm_rcb_P;
/*
** sm_rcb_T -- Stores rcb data and length information.
**
** Members:
** sm_rcb_base -- uchar * to data (doesn't need to end with '\0').
** sm_rcb_size -- Total bytes allocated.
** sm_rcb_len -- Total number of characters in rcb.
** sm_rcb_max -- Maximum number of characters in rcb.
** sm_rcb_rpool -- rpool to allocate from.
** sm_rcb_rw -- read index/space left to write.
**
** Invariants:
** both modes:
** sm_rcb_len <= sm_rcb_size <= sm_rcb_max
** read mode:
** sm_rcb_rw <= sm_str_len
** write mode:
** no length specified: sm_rcb_rw < 0
** length specified: sm_rcb_rw > sizeof(data) to put into RCB
**
** Notices:
** See sm/str.h
**
** Content of an RCB:
** first 4 bytes: total length of RCB
** then a sequence of records:
** 4 bytes: length of "payload" of record: value "l"
** 4 bytes: record type
** l bytes: "payload" of record: l bytes
** records are aligned to 4 bytes.
*/
struct sm_rcb_S
{
sm_magic_T sm_magic;
uchar *sm_rcb_base;
uint sm_rcb_len;
uint sm_rcb_size;
uint sm_rcb_max;
int sm_rcb_rw; /* read index, must be last to match str */
sm_rpool_P sm_rcb_rpool;
#if SM_STR_CHECK
uint sm_rcb_state;
#endif
};
sm_rcb_P sm_rcb_new(sm_rpool_P _rpool, uint _len, uint _max);
#if 0
sm_rcb_P sm_rcb_crt(sm_rpool_P rpool, uchar *rcb, uint len, uint maxlen);
#endif
/* defines for rcb_putv() */
#define SM_RCBV_INT 1
#if MTA_USE_RCBV_INT2
# define SM_RCBV_INT2 2
#endif
#define SM_RCBV_INT64 3
#define SM_RCBV_STR 4
#define SM_RCBV_CSTR 5
#define SM_RCBV_BUF 6
#define SM_RCBV_RDSTR 7
#if MTA_USE_RCBV_INTN
# define SM_RCBV_INTN 8
# define SM_RCBV_INTA 9
#endif
#if MTA_USE_RCBV_STRN
# define SM_RCBV_STRA 10
#endif
#define SM_RCBV_END 11
#if SIZEOF_OFF_T == 4
#define SM_RCBV_OFF SM_RCBV_INT
#elif SIZEOF_OFF_T == 8
#define SM_RCBV_OFF SM_RCBV_INT64
#else
ERROR _SIZEOF_OFF_T is neither 4 not 8: SIZEOF_OFF_T
#endif
#if SM_RCB_ST
# define rcb_fd_T st_netfd_t
#else
# define rcb_fd_T int
#endif
sm_ret_T sm_rcb_put(sm_rcb_P _rcb, uchar _c);
#if SM_STR_CHECK
int sm_rcb_get(sm_rcb_P _rcb);
#define SM_RCB_PUT(rcb, c) sm_rcb_put((rcb), (c))
#define SM_RCB_GET(rcb) sm_rcb_get(rcb)
#else /* SM_STR_CHECK */
#define SM_RCB_GET(rcb) (((rcb)->sm_rcb_len <= (rcb)->sm_rcb_rw) \
? sm_error_perm(SM_EM_RECCOM, SM_E_OVFLW_NS) \
: (rcb)->sm_rcb_base[(rcb)->sm_rcb_rw++])
#define SM_RCB_PUT(rcb, c) (((rcb)->sm_rcb_len == (rcb)->sm_rcb_size) ? \
sm_rcb_put((rcb), (c)) : \
((rcb)->sm_rcb_base[(rcb)->sm_rcb_len++] = (c)), SM_SUCCESS)
#endif /* SM_STR_CHECK */
#if SM_RCB_END_RCB
/* end of RCB marker length: l + record type + value: 3 * sizeof(uint32_t) */
#define SM_RCB_EORCB_LEN 12
#define SM_RCB_ISEOB(rcb) ((rcb)->sm_rcb_len <= (rcb)->sm_rcb_rw + SM_RCB_EORCB_LEN)
#else /* SM_RCB_END_RCB */
#define SM_RCB_EORCB_LEN 0
#define SM_RCB_ISEOB(rcb) ((int) (rcb)->sm_rcb_len <= (rcb)->sm_rcb_rw)
#endif /* SM_RCB_END_RCB */
sm_ret_T sm_rcb_putuint32(sm_rcb_P _rcb, uint32_t _n);
sm_ret_T sm_rcb_putuint64(sm_rcb_P _rcb, uint64_t _u);
sm_ret_T sm_rcb_put2uint32(sm_rcb_P _rcb, uint32_t _n1, uint32_t _n2);
sm_ret_T sm_rcb_put3uint32(sm_rcb_P _rcb, uint32_t _n1, uint32_t _n2, uint32_t _n3);
#if MTA_USE_RCBV_INT2
sm_ret_T sm_rcb_put4uint32(sm_rcb_P _rcb, uint32_t _n1, uint32_t _n2, uint32_t _n3, uint32_t _n4);
#endif
sm_ret_T sm_rcb_put3uint64(sm_rcb_P _rcb, uint32_t _n1, uint32_t _n2, uint64_t _u);
#if MTA_USE_RCBV_INTN
sm_ret_T sm_rcb_putnuint32(sm_rcb_P _rcb, uint32_t _rt, uint _n, ...);
sm_ret_T sm_rcb_putauint32(sm_rcb_P _rcb, uint32_t _rt, uint _n, uint32_t *_av);
#endif
#if MTA_USE_RCBV_STRN
sm_ret_T sm_rcb_putastr(sm_rcb_P _rcb, uint32_t _rt, uint _n, sm_str_P *_strv);
#endif
#if SIZEOF_OFF_T == 4
# define sm_rcb_putoff_t(rcb, n) sm_rcb_putuint32((rcb), (uint32_t) (n))
# define sm_rcb_put3off_t(rcb, n1, n2, n3) sm_rcb_put3uint32((rcb), (n1), (n2), (uint32_t) (n3))
# define sm_rcb_getoff_t(rcb, pv1) sm_rcb_getuint32((rcb), (uint32_t *) (pv1))
# define sm_rcb_get3off_t(rcb, pv1, pv2, pv3) sm_rcb_get3uint32((rcb), (pv1), (pv2), (uint32_t *) (pv3))
#elif SIZEOF_OFF_T == 8
# define sm_rcb_putoff_t(rcb, n) sm_rcb_putuint64((rcb), (uint64_t) (n))
# define sm_rcb_put3off_t(rcb, n1, n2, n3) sm_rcb_put3uint64((rcb), (n1), (n2), (uint64_t) (n3))
# define sm_rcb_getoff_t(rcb, pv1) sm_rcb_getuint64((rcb), (uint64_t *) (pv1))
# define sm_rcb_get3off_t(rcb, pv1, pv2, pv3) sm_rcb_get3uint64((rcb), (pv1), (pv2), (uint64_t *) (pv3))
#else
ERROR _SIZEOF_OFF_T is neither 4 not 8: SIZEOF_OFF_T
#endif
/* flag values for sm_rcb_putv() */
#define RCB_PUTV_NONE 0x00
#define RCB_PUTV_FIRST 0x01
#define RCB_PUTV_OPEN 0x02
#define RCB_PUTV_CLOSE 0x04
/* flag values for sm_rcb_putrec() */
#define RCB_PUTR_NONE 0x00 /* do nothing special */
#define RCB_PUTR_FIRST 0x01
#define RCB_PUTR_OPEN 0x02
#define RCB_PUTR_CLOSE 0x04
#define RCB_PUTR_DFLT 0x07 /* default */
sm_ret_T sm_rcb_putv(sm_rcb_P _rcb, uint _flags, ...);
sm_ret_T sm_rcb_putrec(sm_rcb_P _rcb, uint _flags, uint32_t _sz, int _n, ...);
sm_ret_T sm_rcb_putstr(sm_rcb_P _dst, const sm_rcb_P _src);
sm_ret_T sm_rcb_getuint32(sm_rcb_P _rcb, uint32_t *_pval);
sm_ret_T sm_rcb_getuint64(sm_rcb_P _rcb, uint64_t *_pu);
sm_ret_T sm_rcb_get2uint32(sm_rcb_P _rcb, uint32_t *_pv1, uint32_t *_pv2);
sm_ret_T sm_rcb_get3uint32(sm_rcb_P _rcb, uint32_t *_pv1, uint32_t *_pv2, uint32_t *_pv3);
#if MTA_USE_RCBV_INT2
sm_ret_T sm_rcb_get4uint32(sm_rcb_P _rcb, uint32_t *_pv1, uint32_t *_pv2, uint32_t *_pv3, uint32_t *_pv4);
#endif
sm_ret_T sm_rcb_get3uint64(sm_rcb_P _rcb, uint32_t *_pv1, uint32_t *_pv2, uint64_t *_pu);
sm_ret_T sm_rcb_peek2uint32(sm_rcb_P _rcb, uint32_t *_pv1, uint32_t *_pv2);
#if MTA_USE_RCBV_INTN
sm_ret_T sm_rcb_getauint32(sm_rcb_P _rcb, uint _nmax, uint *_pn, uint32_t *_prt, uint32_t *_pv);
#endif
sm_ret_T sm_rcb_putn(sm_rcb_P _rcb, const uchar *_put, uint n);
sm_ret_T sm_rcb_getn(sm_rcb_P _rcb, uchar *_get, uint _n);
sm_ret_T sm_rcb_getstr(sm_rcb_P _rcb, sm_str_P _str, uint _n);
sm_ret_T sm_rcb_getnstr(sm_rcb_P _rcb, sm_str_P *_str, uint _n);
sm_ret_T sm_rcb_getn0str(sm_rcb_P _rcb, sm_str_P *_str, uint _n);
sm_ret_T sm_rcb_getdata(sm_rcb_P _rcb, const uchar **_data, uint _n);
#if !SM_NO_CSTR
sm_ret_T sm_rcb_getncstr(sm_rcb_P _rcb, sm_cstr_P *_cstr, uint _n);
#endif
sm_ret_T sm_rcb_skip(sm_rcb_P _rcb, uint _n);
sm_ret_T sm_rcb_resize_data(sm_rcb_P _rcb, uint _len);
#if SM_STR_CHECK
uint sm_rcb_getlen(sm_rcb_P _rcb);
uint sm_rcb_getsize(sm_rcb_P _rcb);
int sm_rcb_setmax(sm_rcb_P _rcb, uint _max);
uint sm_rcb_getmax(sm_rcb_P _rcb);
uchar sm_rcb_elem(sm_rcb_P _rcb, uint _i);
uint sm_rcb_space(sm_rcb_P _rcb, uint _new_len);
#else /* SM_STR_CHECK */
# define sm_rcb_getrd(rcb) ((rcb)->sm_rcb_rw)
# define sm_rcb_getlen(rcb) ((rcb)->sm_rcb_len)
# define sm_rcb_getsize(rcb) ((rcb)->sm_rcb_size)
# define sm_rcb_setmax(rcb, m) (rcb)->sm_rcb_max = (m)
# define sm_rcb_getmax(rcb) (rcb)->sm_rcb_max
# define sm_rcb_elem(rcb, i) ((rcb)->sm_rcb_base[i])
# define sm_rcb_space(rcb, new_len) \
(((new_len) <= (rcb)->sm_rcb_size) ? (rcb)->sm_rcb_size \
: sm_rcb_resize_data((rcb), (new_len)))
#endif /* SM_STR_CHECK */
/* XXX Careful: filled externally, e.g., reuse RCB and fill buffer directly */
#define sm_rcb_setlen(rcb, len) ((rcb)->sm_rcb_len) = (len)
#define sm_rcb_data(rcb) ((rcb)->sm_rcb_base)
void sm_rcb_free(sm_rcb_P _rcb);
#define SM_RCB_FREE(ptr) do { \
if ((ptr) != NULL) { \
sm_rcb_free(ptr); \
(ptr) = NULL; \
} \
} while (0)
#if SM_STR_CHECK
void sm_rcb_clr(sm_rcb_P _rcb);
# define SM_RCB_CLR(rcb) sm_rcb_clr(rcb)
#else
# define SM_RCB_CLR(rcb) do { \
(rcb)->sm_rcb_len = 0; \
(rcb)->sm_rcb_rw = 0; \
} while (0)
#endif /* SM_STR_CHECK */
# define sm_rcb_getinit(rcb) (rcb)->sm_rcb_rw = 0
sm_ret_T sm_rcb_putinit(sm_rcb_P _rcb, int _n);
#if SM_RCB_ST
sm_ret_T sm_rcb_rcv(rcb_fd_T _fd, sm_rcb_P _rcb, uint _rs, st_utime_t _timeout);
sm_ret_T sm_rcb_snd(rcb_fd_T _fd, sm_rcb_P _rcb, st_utime_t _timeout);
#else
sm_ret_T sm_rcb_rcv(rcb_fd_T _fd, sm_rcb_P _rcb, uint _rs);
sm_ret_T sm_rcb_snd(rcb_fd_T _fd, sm_rcb_P _rcb);
#endif
sm_ret_T sm_rcb_open_rcv(sm_rcb_P _rcb);
sm_ret_T sm_rcb_open_dec(sm_rcb_P _rcb);
sm_ret_T sm_rcb_open_enc(sm_rcb_P _rcb, int _n);
sm_ret_T sm_rcb_open_snd(sm_rcb_P _rcb);
sm_ret_T sm_rcb_close_rcv(sm_rcb_P _rcb);
sm_ret_T sm_rcb_close_dec(sm_rcb_P _rcb);
sm_ret_T sm_rcb_close_enc(sm_rcb_P _rcb);
sm_ret_T sm_rcb_close_snd(sm_rcb_P _rcb);
sm_ret_T sm_rcb_open_rcvn(sm_rcb_P _rcb);
sm_ret_T sm_rcb_open_decn(sm_rcb_P _rcb);
sm_ret_T sm_rcb_open_encn(sm_rcb_P _rcb, int _n);
sm_ret_T sm_rcb_open_sndn(sm_rcb_P _rcb);
sm_ret_T sm_rcb_close_rcvn(sm_rcb_P _rcb);
sm_ret_T sm_rcb_close_decn(sm_rcb_P _rcb);
sm_ret_T sm_rcb_close_encn(sm_rcb_P _rcb);
sm_ret_T sm_rcb_close_sndn(sm_rcb_P _rcb);
sm_ret_T sm_rcb_close_n(sm_rcb_P _rcb);
#if SM_STR_CHECK
# define SM_RCB_NONE 0
# define SM_RCB_RCV 1
# define SM_RCB_DEC 2
# define SM_RCB_ENC 4
# define SM_RCB_SND 8
#endif /* SM_STR_CHECK */
#ifndef SM_MIN_RCB_SIZE
# define SM_MIN_RCB_SIZE 64
#endif
#ifndef SM_MIN_BUF_SIZE
# define SM_MIN_BUF_SIZE SM_MIN_RCB_SIZE
#endif
#ifndef SM_RCB_MAX_LEN
# define SM_RCB_MAX_LEN 65536
#endif
#ifndef SM_STR_MAX_LEN
# define SM_STR_MAX_LEN SM_RCB_MAX_LEN
#endif
#define SM_IS_RCB(rcb) SM_REQUIRE_ISA((rcb), SM_RCB_MAGIC)
#endif /* SM_RCB_H */
syntax highlighted by Code2HTML, v. 0.9.1