/* @(#)buffer.h	19.1 (ESO-IPG) 02/25/03 13:49:26 */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.TYPE		Header
.NAME		buffer.h
.LANGUAGE	C
.AUTHOR		Francois Ochsenbein [ESO-IPG]
.CATEGORY	Buffer, Stack
.COMMENTS	Automatic processing of buffers.
.ENVIRONMENT
.VERSION 1.0   	23-Jun-1986: Extracted from STESODEF.
.VERSION 2.0	15-Apr-1988: Changed Names
.VERSION 2.1	07-Apr-1989: Added BUF_SaveString
------------------------------------------------------------*/

#ifndef BUFFER_DEF
#define BUFFER_DEF	0

#ifndef _TEMPLATES_
#include <compiler.h>
#endif

/*===========================================================================
 *		BUFFER Structure
 *===========================================================================*/

typedef struct BUFFER_struct {
	char	*buf;		/* Position of buffer in memory		*/
	int	allocated;	/* Presently available memory		*/
	int	increment;	/* Increment unit for expansion		*/
	int	used;		/* Presently used memory		*/
	int	offset;		/* For "locate"	or stacking facilities	*/
    } BUFFER;
#define NULL_BUFFER		(BUFFER *)0

#if _TEMPLATES_
/*===========================================================================
 *		Function Templates
 *===========================================================================*/
BUFFER 	*mm_bopen	(int size, int increment);
int	mm_bfree	(BUFFER *b);
int 	mm_bexp		(BUFFER *b, int new_size);
char 	*mm_bst		(BUFFER *b, char *record, int record_len);  /* Stack */
char 	*mm_bunst	(BUFFER *b);				  /* Unstack */
char 	*mm_bapp	(BUFFER *b, char *record, int length);    /* Append  */
char 	*mm_ball	(BUFFER *b, int length);		 /* Allocate */
char 	*mm_zfree	(BUFFER *b, int index, int item_len);   /* Free Item */
char 	*mm_zindex	(BUFFER *b, int index, int item_len);	/* Find Item */
char 	*mm_zloc	(BUFFER *b, int item_len);	   /* Find Free Item */

#else
BUFFER 	*mm_bopen();
char	*mm_ball(), *mm_bapp();
char	*mm_bst(), *mm_bunst();
char	*mm_zfree(), *mm_zindex(), *mm_zloc();
#endif

/*======================================================================*
 * 		Macros dealing with Buffers
 *======================================================================*/

#define BUF_Init(type, incr)		{(char *)0, 0, sizeof(type)*incr, 0, 0}
#define BUF_Open(type, n, incr)		mm_bopen(sizeof(type)*(n), \
						sizeof(type)*incr)
#define BUF_Expand(b, type, n)		mm_bexp(b, sizeof(type)*n)
#define BUF_Close(b)			mm_bfree(b)			
#define BUF_Clear(b)			(b)->used = 0, (b)->offset = 0

#define BUF_AllocateItems(b, type, n)	(type *)mm_ball(b, sizeof(type)*(n))
#define BUF_AllocateItem(b, type)	BUF_AllocateItems(b,type,1)

#define BUF_AppendItems(b, type, a, n)	(type *)mm_bapp(b, (char *)a, \
						sizeof(type)*(n))
#define BUF_AppendItem(b, type, a)	BUF_AppendItems(b,type,a,1)
#define BUF_AppendString(b, s)		BUF_AppendItems(b, char, s, strlen(s))
#define BUF_SaveString(b, s)		BUF_AppendItems(b, char, s, 1+strlen(s))

#define BUF_StackItem(b, type, a)	(type *)mm_bst(b, (char *)a, \
						sizeof(type))
#define BUF_StackString(b, s)		mm_bst(b, s, strlen(s))

#define BUF_UnstackItem(b, type)	(type *)mm_bunst(b)
#define BUF_Unstack(b)			mm_bunst(b)

#define BUF_ItemPosition(b, type)	(type *)((b)->buf + (b)->offset)
#define BUF_Items(b,type)		((b)->used - (b)->offset)/sizeof(type)

/*======================================================================*
 * 		Macros dealing with SETs (arrays of structures)
 *======================================================================*/

#define SET_Init(type, incr)		BUF_Init(type, incr)
#define SET_Open(type, n, incr)		BUF_Open(type, n, incr)
#define SET_Close(b)			BUF_Close(b)			

#define SET_FindItem(b, type, i)	(type *)mm_zindex(b, i, sizeof(type))
#define SET_FreeItem(b, type, i)	(type *)mm_zfree(b, i, sizeof(type))
#define SET_FindFreeItem(b, type)	(type *)mm_zloc(b, sizeof(type))

#define SET_Item(b, type)		((b)->offset / sizeof(type))
#define SET_Items(b, type)		((b)->used   / sizeof(type))

#define SET_FirstItem(b, type)		(type *)((b)->buf)
#define SET_EndItem(b, type)		(type *)((b)->buf + (b)->used)
#define SET_LastItem(b, type)		(type *)((b)->buf + (b)->used - sizeof(type))

#endif
