#ifndef ARITFEX_EXTRACT_ALLOC_H #define ARITFEX_EXTRACT_ALLOC_H /* Allocation support. We use in/out parameters for pointers so that we can consistently return 0 or -1 with errno set. This also allows us to automatically set a caller's pointer to NULL when freeing or if malloc fails, and leave a caller's pointer unchanged if realloc fails. */ #include typedef void* (*extract_realloc_fn_t)(void* state, void* prev, size_t size); /* An externally-provided allocation function. Should behave like realloc(), except for taking the additional 'void* state' arg. */ typedef struct extract_alloc_t extract_alloc_t; /* Abstract allocator, created by extract_alloc_create(). */ int extract_alloc_create(extract_realloc_fn_t realloc_fn, void* realloc_state, extract_alloc_t** palloc); /* Creates a new extract_alloc_t* for use with extract_malloc() etc. */ void extract_alloc_destroy(extract_alloc_t** palloc); /* Destroys an extract_alloc_t* that was created by extract_alloc_create(). Returns with *palloc set to NULL. Does nothing if *palloc is already NULL. */ int extract_malloc(extract_alloc_t* alloc, void** pptr, size_t size); /* Sets *pptr to point to new allocated memory and returns 0. On error return -1 with errno set and *pptr=NULL. Uses malloc() if is NULL, otherwise must have been created by extract_alloc_create() and we use the extract_realloc_fn_t that was originally passed to extract_alloc_create(). */ int extract_realloc(extract_alloc_t* alloc, void** pptr, size_t newsize); /* Sets *pptr to point to reallocated memory and returns 0. On error return -1 with errno set and *pptr unchanged. Uses realloc() if is NULL, otherwise must have been created by extract_alloc_create() and we use the extract_realloc_fn_t that was originally passed to extract_alloc_create(). */ void extract_free(extract_alloc_t* alloc, void** pptr); /* Frees block pointed to by *pptr and sets *pptr to NULL. Uses free() if is NULL, otherwise must have been created by extract_alloc_create() and we use the extract_realloc_fn_t that was originally passed to extract_alloc_create(). */ #define extract_malloc(alloc, pptr, size) (extract_malloc)(alloc, (void**) pptr, size) #define extract_realloc(alloc, pptr, newsize) (extract_realloc)(alloc, (void**) pptr, newsize) #define extract_free(alloc, pptr) (extract_free)(alloc, (void**) pptr) /* These allow callers to use any pointer type, not just void*. */ typedef struct { int num_malloc; int num_realloc; int num_free; int num_libc_realloc; } extract_alloc_stats_t; extract_alloc_stats_t* extract_alloc_stats(extract_alloc_t* alloc); /* Retrieve statistics. */ int extract_realloc2(extract_alloc_t* alloc, void** pptr, size_t oldsize, size_t newsize); /* A realloc variant that takes the existing buffer size. If is not zero and *pptr is not NULL, must be the size of the existing buffer and may used internally to over-allocate in order to avoid too many calls to realloc(). See extract_alloc_exp_min() for more information. */ #define extract_realloc2(alloc, pptr, oldsize, newsize) (extract_realloc2)(alloc, (void**) pptr, oldsize, newsize) void extract_alloc_exp_min(extract_alloc_t* alloc, size_t size); #endif