/*
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: rcbputastr.c,v 1.2 2007/10/23 03:56:31 ca Exp $")

#include "sm/assert.h"
#include "sm/magic.h"
#include "sm/error.h"
#include "sm/memops.h"
#include "sm/rpool.h"
#include "sm/limits.h"
#include "sm/rcb.h"
#include "sm/str-int.h"
#include "sm/str2rcb.h"
#include "sm/reccom.h"

#if MTA_USE_RCBV_STRN
/*
**  SM_RCB_PUTASTR -- Append n values to the end of a sm_rcb_P.
**		In contrast to other sm_rcb_putX functions, this one
**		"knows" about the structure of entries:
**		rt, number of bytes to follow, value, value, ...
**
**	Parameters:
**		rcb -- sm_rcb_P object to append onto.
**		rt -- record type
**		n -- number of values to append.
**		strv -- array of values to append (size: n)
**
**	Returns:
**		usual sm_error code; ENOMEM, SM_E_OVFLW_SC, SM_E_OVFLW_NS
**
**	Last code review:
**	Last code change:
*/

sm_ret_T
sm_rcb_putastr(sm_rcb_P rcb, uint32_t rt, uint n, sm_str_P *strv)
{
	uint nsize, u, ne;
	uint32_t v;
	sm_ret_T ret;
	sm_str_P str;

	SM_IS_RCB(rcb);

	ne = n + 2;	/* total number of entries: n + rt + counter itself */
	if (ne <= n)
		return sm_error_perm(SM_EM_RECCOM, SM_E_OVFLW_SC);
	nsize = rcb->sm_rcb_len + sizeof(sm_str_P) * ne;

	/* overflow? */
	if (nsize <= rcb->sm_rcb_len)
		return sm_error_perm(SM_EM_RECCOM, SM_E_OVFLW_SC);

	/* do we really want to do this? */
	if (rcb->sm_rcb_rw >= 0 && (int)(ne * sizeof(sm_str_P)) > rcb->sm_rcb_rw)
		return sm_error_perm(SM_EM_RECCOM, SM_E_FULL);
	if (nsize > rcb->sm_rcb_size)
		SM_STR_INCREASE_R(rcb, nsize);

	/* record type */
	sm_uint32_2buf(rt, rcb->sm_rcb_base + rcb->sm_rcb_len);
	rcb->sm_rcb_len += sizeof(uint32_t);

	/* number of bytes to follow */
	v = n * sizeof(sm_str_P);
	sm_uint32_2buf(v, rcb->sm_rcb_base + rcb->sm_rcb_len);
	rcb->sm_rcb_len += sizeof(sm_str_P);

	for (u = 0; u < n; u++) {
		str = *strv++;
		SM_IS_BUF(str);
		ret = sm_rcb_putn(rcb, sm_str_data(str), sm_str_getlen(str));
		if (sm_is_err(ret))
			goto err1;
	}
	if (rcb->sm_rcb_rw >= 0)
		rcb->sm_rcb_rw -= sizeof(uint32_t) * ne;
	return SM_SUCCESS;

 err1:
	return ret;
}
#endif /* MTA_USE_RCBV_STRN */


syntax highlighted by Code2HTML, v. 0.9.1