/* pool.h
   Copyright (C) 1996-2000 Paul Sheer

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307, USA.
*/

/*
   The memory file will begin at a few bytes and double in size whenener
   you try to write past the end. Thus you can use it to hold
   contiguous data whose size is not none a priori. Use instead of
   malloc().
 */

#ifndef _POOL_H
#define _POOL_H

typedef struct pool_type {
    unsigned char *start;
    unsigned char *current;
    unsigned char *end;
    unsigned long length;
} POOL;

#define START_SIZE 256

#define pool_freespace(p) ((unsigned long) p->end - (unsigned long) p->current)
#define pool_start(p) ((p)->start)
#define pool_current(p) ((p)->current)
#define pool_length(p) ((unsigned long) (p)->current - (unsigned long) (p)->start)

/* returns NULL on error */
#ifdef HAVE_MAD
POOL *mad_pool_init (char *file, int line);
#define pool_init() mad_pool_init(__FILE__, __LINE__)
#else
POOL *pool_init (void);
#endif

/* free's a pool except for the actual data which is returned */
/* result must be free'd by the caller even if the pool_length is zero */
unsigned char *pool_break (POOL *p);

/* free's a pool and all its data */
void pool_free (POOL *p);

/* returns the number of bytes written into p */
#ifdef HAVE_MAD
#define pool_write(p,d,l) mad_pool_write (p, d, l, __FILE__ ,__LINE__)
unsigned long mad_pool_write (POOL * p, unsigned char *d, unsigned long l, char *file, int line);
#else
unsigned long pool_write (POOL * p, unsigned char *d, unsigned long l);
#endif

/* returns the number of bytes read into d */
unsigned long pool_read (POOL * p, unsigned char *d, unsigned long l);

/* sets the position in the pool */
unsigned long pool_seek (POOL * p, unsigned long l);

/* used like sprintf */
unsigned long pool_printf (POOL *p, const char *fmt,...);

/* make space for a forthcoming write of l bytes. leaves current untouched */
#ifdef HAVE_MAD
#define pool_advance(p,l) mad_pool_advance (p, l, __FILE__ ,__LINE__)
unsigned long mad_pool_advance (POOL * p, unsigned long l, char *file, int line);
#else
unsigned long pool_advance (POOL * p, unsigned long l);
#endif

/* removes the last line from the length, and null-terminates */
void pool_drop_last_line (POOL * p);

/* zero the char after the last char written/read without advancing current */
int pool_null (POOL *p);

#endif
