home *** CD-ROM | disk | FTP | other *** search
- /*
- #### # # # #
- # # # # # The FreeWare C library for
- # # ## ### # # # # ### RISC OS machines
- # # # # # # # # # # # ___________________________________
- # # #### ### ## # # # #
- # # # # # # # # # # Please refer to the accompanying
- #### ### #### # # ##### # ### documentation for conditions of use
- ________________________________________________________________________
-
- File: DeskMem.h
- Author: Copyright © 1995 Julian Smith, based on idea from Ijith
- Ponnampalavanar
- Version: 1.20 (18 Nov 1995)
- Purpose: Standard error-handling functions for allocating immovable bits
- of memory.
- Facilities for changing the raw allocation functions (they are
- initially ANSI C's malloc, realloc, calloc and free).
- Some functions for simple buffers.
- History: 1.00 (07 Sep 1995)
- 1.10 (29 Sep 1995) JS Added Desk_DeskMem_Buffer* functions.
- 1.11 (10 Nov 1995) JS Split things into separate .c files etc.
- 1.12 (14 Nov 1995) JS Added support for debug DeskLib.
- 1.20 (18 Nov 1995) JS Added support for changing the raw
- allocation functions -
- Desk_DeskMem_SetAllocFunctions. Also added
- macros for accessing the raw functions
- without Desk_DeskMem_Malloc's error-checking.
- 1.21 (13 Jun 1996) JS Desk_DeskMem_BufferInit sets buffer pointer
- to NULL rather than initialising to increment.
- */
-
-
- #ifndef __Desk_DeskMem_h
- #define __Desk_DeskMem_h
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- #include <stdlib.h>
-
- #include <stddef.h>
-
- #ifndef __Desk_Core_h
- #include "Desk.Core.h"
- #endif
-
-
- void *Desk_DeskMem_Malloc( size_t size);
- /*
- A safe replacement for 'malloc'. Calls Desk_Error2_Handle if it can't
- allocate 'size' bytes of memory, so never returns NULL.
- */
-
- void *Desk_DeskMem_Calloc( size_t num, size_t size);
- /*
- A safe replacement for 'calloc'. Calls Desk_Error2_Handle if it can't
- allocate memory, so never returns NULL.
- */
-
- void *Desk_DeskMem_Realloc( void *ptr, size_t size);
- /*
- A safe replacement for 'realloc'. Calls Desk_Error2_Handle if it can't
- reallocate 'ptr' to point to 'size' bytes of memory, so never returns
- NULL.
- */
-
- void Desk_DeskMem_Free( void *ptr);
- /*
- Use like 'free()'.
- */
-
-
-
- #define Desk_DeskMem_MallocType( type) (type *) Desk_DeskMem_Malloc( sizeof( type))
- /*
- Use like:
- bigtypedef* object = Desk_DeskMem_MallocType( bigtypedef);
-
- Instead of:
- bigtypedef* object = (bigtypedef *) Desk_DeskMem_Malloc( sizeof( bigtypedef));
- */
-
- #define Desk_DeskMem_CallocType( n, type) ((type *) Desk_DeskMem_Calloc( n, sizeof( type)))
- /*
- Use like:
- bigtypedef *array = Desk_DeskMem_CallocType( 30, bigtypedef);
- */
-
-
-
- typedef struct Desk_deskmem_errorblock {
- size_t size;
- void* ptr;
- }
- Desk_deskmem_errorblock;
- /*
- This structure is used to contain info on DeskMem errors, using the
- Error2 library's error-handling system.
- */
-
- #ifdef Desk__using_SDLS
- extern Desk_deskmem_errorblock* Desk_DeskMem__Ref_errorblock( void);
- #endif
-
-
- #if defined( Desk__using_SDLS) && !defined( Desk__making_DeskMem)
- #define Desk_deskmem_globalerror (*Desk_DeskMem__Ref_errorblock())
- #else
- extern Desk_deskmem_errorblock Desk_deskmem_globalerror;
- /*
- This is a global structure which contains details of any error from the
- last call to a DeskMem function.
- */
- #endif
-
-
-
-
-
- #ifdef Desk_DeskLib_DEBUG
- extern int Desk_deskmem_debuglevel;
- /*
- In the debug version of DeskLib, this is the DeskMem library's own
- version of Desk_debug_level. It is initially 0; any program can set it to
- different values to turn on/off different debug ouputs in the DeskMem
- library.
- */
- #endif
-
-
-
-
-
-
-
-
- /*
- Here are some DeskMem things relating to changing the memory-allocation
- functions etc.
- */
-
- typedef void* (*Desk_deskmem_mallocfn) ( size_t); /* The type of malloc() */
- typedef void* (*Desk_deskmem_reallocfn) ( void *, size_t); /* The type of realloc()*/
- typedef void* (*Desk_deskmem_callocfn) ( size_t, size_t); /* The type of calloc() */
- typedef void (*Desk_deskmem_freefn) ( void *); /* The type of free() */
-
-
- typedef struct {
- Desk_deskmem_mallocfn malloc;
- Desk_deskmem_reallocfn realloc;
- Desk_deskmem_callocfn calloc;
- Desk_deskmem_freefn free;
- }
- Desk_deskmem_functionsblock;
-
-
- void Desk_DeskMem_SetAllocFunctions(
- Desk_deskmem_mallocfn m,
- Desk_deskmem_reallocfn r,
- Desk_deskmem_callocfn c,
- Desk_deskmem_freefn f,
- Desk_deskmem_functionsblock* oldfunctions
- );
- /*
- This sets the functions DeskMem will use for all future static memory
- allocation.
-
- If 'oldfunctions' isn't NULL, it also returns the functions that DeskMem
- was using prior to this call, by filling in the Desk_deskmem_functionsblock
- pointed to by 'oldfunctions'.
-
- This is so that the new allocation functions can store the old
- functions. This could be useful if the new 'free' is called for a ptr
- that isn't recognised - the new 'free()' function could try calling the
- old function, or if the new functions are simple wrapper-functions.
- */
-
-
- #ifdef Desk__using_SDLS
- extern Desk_deskmem_functionsblock* Desk_DeskMem__Ref_functionsblock( void);
- #endif
-
-
- #if defined( Desk__using_SDLS) && !defined( Desk__making_DeskMem)
- #define Desk_deskmem__functions (*Desk_DeskMem__Ref_functionsblock())
- #else
- extern Desk_deskmem_functionsblock Desk_deskmem__functions;
- /*
- You shouldn't need to use this directly. It is used by all
- Desk_DeskMem_(X)M/C/Realloc functions. It is initially set to contain the
- standard ANSI C memory allocation functions: malloc, realloc, calloc and
- free.
- */
- #endif
-
-
-
- /*
- Note that if you are using the DeskMem DLL, the Desk_DeskMem_Raw* macros will
- have to make a function-call to get the address of 'Desk_deskmem__functions'.
- This will happen every time they are used.
-
- If you are using Desk_DeskMem_RawMalloc etc and speed is important, you
- should cache this address at the start of you program, and write your
- own macros.
-
- For example:
-
- . |* main.c *|
- . Desk_deskmem_functionsblock* Desk_client_deskmem__functions;
- .
- . #define RawMalloc( size) (Desk_client_deskmem__functions->malloc( size))
- . #define RawCalloc( num, size) (Desk_client_deskmem__functions->calloc( num, size))
- . etc etc
- .
- . int main( void)
- . {
- . Desk_client_deskmem__functions = &Desk_deskmem__functions;
- . ...
- . }
-
- */
-
- #define Desk_DeskMem_RawMalloc( size) (Desk_deskmem__functions.malloc( size))
- /*
- This gives direct access to whatever malloc function DeskMem is using.
- */
-
- #define Desk_DeskMem_RawRealloc( ptr, size) (Desk_deskmem__functions.realloc( ptr, size))
- /*
- This gives direct access to whatever realloc function DeskMem is using.
- */
-
- #define Desk_DeskMem_RawCalloc( num, size) (Desk_deskmem__functions.calloc( num, size))
- /*
- This gives direct access to whatever calloc function DeskMem is using.
- */
-
- #define Desk_DeskMem_RawFree( ptr) (Desk_deskmem__functions.free( ptr))
- /*
- This gives direct access to whatever free function DeskMem is using.
- */
-
-
-
-
-
-
-
-
- typedef struct {
-
- void* data;
-
- int size;
- int datasize;
- int increment;
- }
- Desk_deskmem_buffer;
- /*
- This structure holds info on a buffer. Only access 'data' directly - use
- Desk_DeskMem_Buffer* functions for everything else.
-
- A Desk_deskmem_buffer is useful for allocating some memory which might need
- to increase/decrease in size. Memory is only ever allocated in multiples
- of 'increment', which is set when the buffer is initialised with
- Desk_DeskMem_BufferInit.
-
- This allows you to use a Desk_desk_buffer to hold varying-size data whilst
- keeping the heap reasonably unfragmented.
- */
-
-
- void Desk_DeskMem_BufferInit( Desk_deskmem_buffer* buffer, int increment);
- /*
- Initialises 'buffer'. Calls Desk_DeskMem_BufferEnsure( buffer, increment) to
- set the initial size of the buffer to 0, so you don't have to bother
- freeing the buffer if you don't use it.
- */
-
- void Desk_DeskMem_BufferFree( Desk_deskmem_buffer* buffer);
- /*
- Releases the memory associated with 'buffer'. Sets buffer->data to NULL.
-
- Note that it is easy to call Desk_DeskMem_Free( &buffer) by mistake
- (which will crash the application), and CC won't warn about this -
- Desk_DeskMem_Free accepts any pointer.
- */
-
- void Desk_DeskMem_BufferEnsure( Desk_deskmem_buffer* buffer, int min);
- /*
- Increases/decreases the size of buffer so it points to at least 'min'
- bytes of memory. This is done with Desk_DeskMem_Realloc, so it preserves the
- data pointed to by buffer->data.
- */
-
- void Desk_DeskMem_BufferEnsureExtra( Desk_deskmem_buffer *buffer, int extra);
- /*
- Prepares the buffer so that it will hold at least 'extra' bytes more
- than is currently used.
- */
-
- #define Desk_DeskMem_BufferGetSize( buffer) ( (buffer)->size)
- /*
- This returns the amount of memory in the buffer, which will always be
- >= than the amount last passed to Desk_DeskMem_BufferEnsure.
-
- In general, you will probably want to know the size of the data in the
- buffer, for which you should use Desk_DeskMem_BufferGetDataSize.
- */
-
- #define Desk_DeskMem_BufferGetDataSize( buffer) ( (buffer)->datasize)
- /*
- This returns the amount of used-memory in the buffer (ie from the last
- call to Desk_DeskMem_BufferEnsure).
-
- Also see Desk_DeskMem_BufferGetSize.
- */
-
- #define Desk_DeskMem_BufferGetString( buffer) ( (char*) (buffer)->data)
- /*
- Returns the data cast to a (char*)
- */
-
- #define Desk_DeskMem_BufferGetIntArray( buffer) ( (int*) (buffer)->data)
- /*
- Returns the data cast to a (int*)
- */
-
- #define Desk_DeskMem_BufferGetDoubleArray( buffer) ( (double*) (buffer)->data)
- /*
- Returns the data cast to a (double*)
- */
-
- void Desk_DeskMem_BufferStrCat( Desk_deskmem_buffer* buffer, const char* extra);
- /*
- Treat like strcat - appends 'extra', ensuring there is enough space.
- */
-
- void Desk_DeskMem_BufferStrNCat( Desk_deskmem_buffer* buffer, const char* extra, int extralen);
- /*
- Treat like strncat - appends the first 'extralen' characters of 'extra',
- ensuring there is enough space.
- */
-
- void Desk_DeskMem_BufferStrCpy( Desk_deskmem_buffer* buffer, const char* s);
- /*
- Treat like strcpy - copies 's', ensuring there is enough space.
- */
-
-
-
-
- #ifdef __cplusplus
- }
- #endif
-
-
- #endif
-