/*
    ####             #    #     # #
    #   #            #    #       #          The FreeWare C library for
    #   #  ##   ###  #  # #     # ###             RISC OS machines
    #   # #  # #     # #  #     # #  #   ___________________________________
    #   # ####  ###  ##   #     # #  #
    #   # #        # # #  #     # #  #    Please refer to the accompanying
    ####   ### ####  #  # ##### # ###    documentation for conditions of use
    ________________________________________________________________________

    File:    DynamArea.h
    Author:  Copyright  1996 Julian Smith.
    Version: 1.00 
    Purpose: Simple management of dynamic areas.
    History: 1.00 (12 Jul 1996)

 */


/*
These functions allow dynamic areas to be easily created, resized and
deleted.

The main reason for this library is that the SWI provided by RISC OS for
changing the size of a DA (OS_ChangeDynamicArea) is rather tricky to
use, for two reasons:

1	It expects the change in the size of the dynamic area, rather
	than an absolute size.
2	This change is relative to the actual size of the DA, rather
	than the size last requested (DAs are rounded up to a multiple
	of a page-size).

Also, this library keeps a list of created DAs, and can delete them all
when the program finishes.

No facility is provided for heap-management within individual dynamic
areas.
 */

#ifndef __Desk_DynamArea_h
#define __Desk_DynamArea_h


typedef struct Desk_DynamicArea_block	{
	int				id;		/* Used with OS_ChangeDynamicArea SWI etc	*/
	void*				data;		/* Pointer to start of dynamic area		*/
	size_t				datasize;	/* Last size passed to Desk_DynamicArea_SetSize	*/
	size_t				size;		/* Actual size of the dynamic area - probably 	*/
							/* 'datasize' rounded up to multiple of machine	*/
							/* page-size.					*/
	struct Desk_DynamicArea_block*	previous;	/* Maintains single-linked list of DAs.		*/
	}
	Desk_DynamicArea_block;
/*
Information the Desk_DynamicArea library uses to keep track of all its
dynamic areas.

Do /not/ use the fields directly - use only the functions/macros provided.
 */


void	Desk_DynamicArea_Create( Desk_DynamicArea_block* da, size_t maxsize, const char* name);
/*
Creates a dynamic area for use with Desk_DynamicArea_* calls.

da		Pointer to a Desk_DynamicArea_block that must exist for the life of
		the dynamic area.
maxsize		Maximum size the dynamic area will ever be. -1 means the amount
		of RAM in the machine.
name		Name of the dynamic area in the Tasks Manager's window.
 */


void	Desk_DynamicArea_Delete( Desk_DynamicArea_block* da);
/*
Completely removes the specified dynamic area.

da		Pointer to Desk_DynamicArea_block for the dynamic area
		to delete.
 */


void	Desk_DynamicArea_DeleteAll( void);
/*
This deleted all the dynamic areas created with Desk_DynamicArea_Create.
It is called automatically when the program finishes, using atexit().

Note that module builds /don't/ use atexit() in this way, because
atexit() doesn't seem to work reliably in modules. You should therefore
call Desk_DynamicArea_DeleteAll from a modules finalisation code.
 */


void*	Desk_DynamicArea_SetSize( Desk_DynamicArea_block* da, size_t size);
/*
Makes the specified dynamic area contain at least 'size' bytes. Any
existing data is preserved, up to whatever is the minimum of the the old
and new sizes (ie it behaves like realloc).

Returns a pointer to the data.

da		Pointer to Desk_DynamicArea_block for the dynamic area
		to set size of.
size		New size of dynamic area.
 */



#define	Desk_DynamicArea_GetSize( da)		( (da)->size)
/*
size_t	Desk_DynamicArea_GetSize( Desk_DynamicArea_block* da);

Returns the actual size of the DA.
 */

#define	Desk_DynamicArea_GetDataSize( da)	( (da)->datasize)
/*
size_t	Desk_DynamicArea_GetDataSize( Desk_DynamicArea_block* da);

Returns the last-requested size of the DA (ie the size past to the last
succesfull call to Desk_DynamicArea_SetSize).
 */


#define	Desk_DynamicArea_GetData( da)		( (da)->data)
/*
void*	Desk_DynamicArea_GetData( Desk_DynamicArea_block* da);

Returns a (void*) to the DA data.
 */


#endif
