home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / d / desklib / !DeskLib / h_doc / DeskMem < prev    next >
Encoding:
Text File  |  1996-06-21  |  10.1 KB  |  362 lines

  1. /*
  2.     ####             #    #     # #
  3.     #   #            #    #       #          The FreeWare C library for 
  4.     #   #  ##   ###  #  # #     # ###             RISC OS machines
  5.     #   # #  # #     # #  #     # #  #   ___________________________________
  6.     #   # ####  ###  ##   #     # #  #                                      
  7.     #   # #        # # #  #     # #  #    Please refer to the accompanying
  8.     ####   ### ####  #  # ##### # ###    documentation for conditions of use
  9.     ________________________________________________________________________
  10.  
  11.     File:    DeskMem.h
  12.     Author:  Copyright © 1995 Julian Smith, based on idea from Ijith 
  13.                               Ponnampalavanar
  14.     Version: 1.20 (18 Nov 1995)
  15.     Purpose: Standard error-handling functions for allocating immovable bits
  16.              of memory.
  17.              Facilities for changing the raw allocation functions (they are
  18.              initially ANSI C's malloc, realloc, calloc and free).
  19.              Some functions for simple buffers.
  20.     History: 1.00 (07 Sep 1995)
  21.              1.10 (29 Sep 1995) JS Added Desk_DeskMem_Buffer* functions.
  22.              1.11 (10 Nov 1995) JS Split things into separate .c files etc.
  23.              1.12 (14 Nov 1995) JS Added support for debug DeskLib.
  24.              1.20 (18 Nov 1995) JS Added support for changing the raw
  25.                                    allocation functions - 
  26.                                    Desk_DeskMem_SetAllocFunctions. Also added
  27.                                    macros for accessing the raw functions
  28.                                    without Desk_DeskMem_Malloc's error-checking.
  29.              1.21 (13 Jun 1996) JS Desk_DeskMem_BufferInit sets buffer pointer
  30.                                    to NULL rather than initialising to increment.
  31. */
  32.  
  33.  
  34. #ifndef __Desk_DeskMem_h
  35. #define __Desk_DeskMem_h
  36.  
  37. #ifdef __cplusplus
  38.     extern "C" {
  39. #endif
  40.  
  41. #include <stdlib.h>
  42.  
  43. #include <stddef.h>
  44.  
  45. #ifndef __Desk_Core_h
  46. #include "Desk.Core.h"
  47. #endif
  48.  
  49.  
  50. void    *Desk_DeskMem_Malloc( size_t size);
  51. /*
  52. A safe replacement for 'malloc'. Calls Desk_Error2_Handle if it can't
  53. allocate 'size' bytes of memory, so never returns NULL.
  54.  */
  55.  
  56. void    *Desk_DeskMem_Calloc( size_t num, size_t size);
  57. /*
  58. A safe replacement for 'calloc'. Calls Desk_Error2_Handle if it can't
  59. allocate memory, so never returns NULL.
  60.  */
  61.  
  62. void    *Desk_DeskMem_Realloc( void *ptr, size_t size);
  63. /* 
  64. A safe replacement for 'realloc'. Calls Desk_Error2_Handle if it can't
  65. reallocate 'ptr' to point to 'size' bytes of memory, so never returns
  66. NULL.
  67.  */
  68.  
  69. void    Desk_DeskMem_Free( void *ptr);
  70. /*
  71. Use like 'free()'.
  72.  */
  73.  
  74.  
  75.  
  76. #define Desk_DeskMem_MallocType( type)    (type *) Desk_DeskMem_Malloc( sizeof( type))
  77. /*
  78. Use like:
  79. bigtypedef*    object = Desk_DeskMem_MallocType( bigtypedef);
  80.  
  81. Instead of:
  82. bigtypedef*    object = (bigtypedef *) Desk_DeskMem_Malloc( sizeof( bigtypedef));
  83.  */
  84.  
  85. #define    Desk_DeskMem_CallocType( n, type)    ((type *) Desk_DeskMem_Calloc( n, sizeof( type)))
  86. /*
  87. Use like:
  88. bigtypedef    *array = Desk_DeskMem_CallocType( 30, bigtypedef);
  89.  */
  90.  
  91.  
  92.  
  93. typedef struct Desk_deskmem_errorblock    {
  94.     size_t    size;
  95.     void*    ptr;
  96.     }
  97.     Desk_deskmem_errorblock;
  98. /*
  99. This structure is used to contain info on DeskMem errors, using the
  100. Error2 library's error-handling system.
  101.  */
  102.  
  103. #ifdef Desk__using_SDLS
  104.     extern    Desk_deskmem_errorblock*    Desk_DeskMem__Ref_errorblock( void);
  105. #endif
  106.  
  107.  
  108. #if defined( Desk__using_SDLS) && !defined( Desk__making_DeskMem)
  109.     #define    Desk_deskmem_globalerror    (*Desk_DeskMem__Ref_errorblock())
  110. #else
  111.     extern Desk_deskmem_errorblock    Desk_deskmem_globalerror;
  112. /*
  113. This is a global structure which contains details of any error from the
  114. last call to a DeskMem function.
  115.  */
  116. #endif
  117.  
  118.  
  119.  
  120.  
  121.  
  122. #ifdef Desk_DeskLib_DEBUG
  123.     extern int    Desk_deskmem_debuglevel;
  124. /*
  125. In the debug version of DeskLib, this is the DeskMem library's own
  126. version of Desk_debug_level. It is initially 0; any program can set it to
  127. different values to turn on/off different debug ouputs in the DeskMem
  128. library.
  129.  */
  130. #endif
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139. /*
  140. Here are some DeskMem things relating to changing the memory-allocation
  141. functions etc.
  142.  */
  143.  
  144. typedef void*    (*Desk_deskmem_mallocfn)    ( size_t);        /* The type of malloc()    */
  145. typedef void*    (*Desk_deskmem_reallocfn)    ( void *, size_t);    /* The type of realloc()*/
  146. typedef void*    (*Desk_deskmem_callocfn)    ( size_t, size_t);    /* The type of calloc()    */
  147. typedef void    (*Desk_deskmem_freefn)    ( void *);        /* The type of free()    */
  148.  
  149.  
  150. typedef struct    {
  151.     Desk_deskmem_mallocfn    malloc;
  152.     Desk_deskmem_reallocfn    realloc;
  153.     Desk_deskmem_callocfn    calloc;
  154.     Desk_deskmem_freefn        free;
  155.     }
  156.     Desk_deskmem_functionsblock;    
  157.  
  158.  
  159. void    Desk_DeskMem_SetAllocFunctions( 
  160.         Desk_deskmem_mallocfn    m,
  161.         Desk_deskmem_reallocfn    r,
  162.         Desk_deskmem_callocfn    c,
  163.         Desk_deskmem_freefn        f,
  164.         Desk_deskmem_functionsblock*    oldfunctions
  165.         );
  166. /*
  167. This sets the functions DeskMem will use for all future static memory
  168. allocation. 
  169.  
  170. If 'oldfunctions' isn't NULL, it also returns the functions that DeskMem
  171. was using prior to this call, by filling in the Desk_deskmem_functionsblock
  172. pointed to by 'oldfunctions'.
  173.  
  174. This is so that the new allocation functions can store the old
  175. functions. This could be useful if the new 'free' is called for a ptr
  176. that isn't recognised - the new 'free()' function could try calling the
  177. old function, or if the new functions are simple wrapper-functions.
  178.  */
  179.  
  180.  
  181. #ifdef Desk__using_SDLS
  182.     extern    Desk_deskmem_functionsblock*    Desk_DeskMem__Ref_functionsblock( void);
  183. #endif
  184.  
  185.  
  186. #if defined( Desk__using_SDLS) && !defined( Desk__making_DeskMem)
  187.     #define    Desk_deskmem__functions    (*Desk_DeskMem__Ref_functionsblock())
  188. #else
  189.     extern    Desk_deskmem_functionsblock    Desk_deskmem__functions;
  190. /*
  191. You shouldn't need to use this directly. It is used by all
  192. Desk_DeskMem_(X)M/C/Realloc functions. It is initially set to contain the
  193. standard ANSI C memory allocation functions: malloc, realloc, calloc and
  194. free.
  195.  */
  196. #endif
  197.  
  198.  
  199.  
  200. /*
  201. Note that if you are using the DeskMem DLL, the Desk_DeskMem_Raw* macros will
  202. have to make a function-call to get the address of 'Desk_deskmem__functions'.
  203. This will happen every time they are used.
  204.  
  205. If you are using Desk_DeskMem_RawMalloc etc and speed is important, you
  206. should cache this address at the start of you program, and write your
  207. own macros.
  208.  
  209. For example:
  210.  
  211. . |* main.c *|
  212. . Desk_deskmem_functionsblock*    Desk_client_deskmem__functions;
  213. . #define RawMalloc( size)    (Desk_client_deskmem__functions->malloc( size))
  214. . #define RawCalloc( num, size)    (Desk_client_deskmem__functions->calloc( num, size))
  215. .  etc etc
  216. . int    main( void)
  217. . {
  218. . Desk_client_deskmem__functions = &Desk_deskmem__functions;
  219. . ...
  220. . }
  221.  
  222.  */
  223.  
  224. #define    Desk_DeskMem_RawMalloc( size)    (Desk_deskmem__functions.malloc( size))
  225. /*
  226. This gives direct access to whatever malloc function DeskMem is using.
  227.  */
  228.  
  229. #define    Desk_DeskMem_RawRealloc( ptr, size)    (Desk_deskmem__functions.realloc( ptr, size))
  230. /*
  231. This gives direct access to whatever realloc function DeskMem is using.
  232.  */
  233.  
  234. #define    Desk_DeskMem_RawCalloc( num, size)    (Desk_deskmem__functions.calloc( num, size))
  235. /*
  236. This gives direct access to whatever calloc function DeskMem is using.
  237.  */
  238.  
  239. #define    Desk_DeskMem_RawFree( ptr)        (Desk_deskmem__functions.free( ptr))
  240. /*
  241. This gives direct access to whatever free function DeskMem is using.
  242.  */
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251. typedef struct    {
  252.  
  253.     void*    data;
  254.     
  255.     int    size;
  256.     int    datasize;
  257.     int    increment;
  258.     }
  259.     Desk_deskmem_buffer;
  260. /*
  261. This structure holds info on a buffer. Only access 'data' directly - use
  262. Desk_DeskMem_Buffer* functions for everything else.
  263.  
  264. A Desk_deskmem_buffer is useful for allocating some memory which might need
  265. to increase/decrease in size. Memory is only ever allocated in multiples
  266. of 'increment', which is set when the buffer is initialised with
  267. Desk_DeskMem_BufferInit. 
  268.  
  269. This allows you to use a Desk_desk_buffer to hold varying-size data whilst
  270. keeping the heap reasonably unfragmented.
  271.  */
  272.  
  273.  
  274. void    Desk_DeskMem_BufferInit( Desk_deskmem_buffer* buffer, int increment);
  275. /*
  276. Initialises 'buffer'. Calls Desk_DeskMem_BufferEnsure( buffer, increment) to
  277. set the initial size of the buffer to 0, so you don't have to bother
  278. freeing the buffer if you don't use it.
  279.  */
  280.  
  281. void    Desk_DeskMem_BufferFree( Desk_deskmem_buffer* buffer);
  282. /*
  283. Releases the memory associated with 'buffer'. Sets buffer->data to NULL.
  284.  
  285. Note that it is easy to call Desk_DeskMem_Free( &buffer) by mistake
  286. (which will crash the application), and CC won't warn about this -
  287. Desk_DeskMem_Free accepts any pointer.
  288.  */
  289.  
  290. void    Desk_DeskMem_BufferEnsure( Desk_deskmem_buffer* buffer, int min);
  291. /*
  292. Increases/decreases the size of buffer so it points to at least 'min'
  293. bytes of memory. This is done with Desk_DeskMem_Realloc, so it preserves the
  294. data pointed to by buffer->data.
  295.  */
  296.  
  297. void    Desk_DeskMem_BufferEnsureExtra( Desk_deskmem_buffer *buffer, int extra);
  298. /*
  299. Prepares the buffer so that it will hold at least 'extra' bytes more
  300. than is currently used.
  301.  */
  302.  
  303. #define    Desk_DeskMem_BufferGetSize( buffer)    ( (buffer)->size)
  304. /*
  305. This returns the amount of memory in the buffer, which will always be
  306. >= than the amount last passed to Desk_DeskMem_BufferEnsure.
  307.  
  308. In general, you will probably want to know the size of the data in the
  309. buffer, for which you should use Desk_DeskMem_BufferGetDataSize.
  310.  */
  311.  
  312. #define    Desk_DeskMem_BufferGetDataSize( buffer)    ( (buffer)->datasize)
  313. /*
  314. This returns the amount of used-memory in the buffer (ie from the last
  315. call to Desk_DeskMem_BufferEnsure).
  316.  
  317. Also see Desk_DeskMem_BufferGetSize.
  318.  */
  319.  
  320. #define Desk_DeskMem_BufferGetString( buffer)    ( (char*) (buffer)->data)
  321. /*
  322. Returns the data cast to a (char*)
  323.  */
  324.  
  325. #define Desk_DeskMem_BufferGetIntArray( buffer)    ( (int*) (buffer)->data)
  326. /*
  327. Returns the data cast to a (int*)
  328.  */
  329.  
  330. #define Desk_DeskMem_BufferGetDoubleArray( buffer)    ( (double*) (buffer)->data)
  331. /*
  332. Returns the data cast to a (double*)
  333.  */
  334.  
  335. void    Desk_DeskMem_BufferStrCat( Desk_deskmem_buffer* buffer, const char* extra);
  336. /*
  337. Treat like strcat - appends 'extra', ensuring there is enough space.
  338.  */
  339.  
  340. void    Desk_DeskMem_BufferStrNCat( Desk_deskmem_buffer* buffer, const char* extra, int extralen);
  341. /*
  342. Treat like strncat - appends the first 'extralen' characters of 'extra',
  343. ensuring there is enough space.
  344.  */
  345.  
  346. void    Desk_DeskMem_BufferStrCpy( Desk_deskmem_buffer* buffer, const char* s);
  347. /*
  348. Treat like strcpy - copies 's', ensuring there is enough space.
  349.  */
  350.  
  351.  
  352.  
  353.  
  354. #ifdef __cplusplus
  355. }
  356. #endif
  357.  
  358.  
  359. #endif
  360.