generated from sethub/template
[libxml2]Add libxml2 library
This commit is contained in:
@@ -0,0 +1,554 @@
|
||||
/*
|
||||
* xmlmemory.c: libxml memory allocator wrapper.
|
||||
*
|
||||
* Author: Daniel Veillard
|
||||
*/
|
||||
|
||||
#define IN_LIBXML
|
||||
#include "libxml.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <libxml/xmlerror.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/threads.h>
|
||||
|
||||
#include "private/error.h"
|
||||
#include "private/memory.h"
|
||||
#include "private/threads.h"
|
||||
|
||||
static unsigned long debugMemSize = 0;
|
||||
static unsigned long debugMemBlocks = 0;
|
||||
static xmlMutex xmlMemMutex;
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
* Macros, variables and associated types *
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
/*
|
||||
* Each of the blocks allocated begin with a header containing information
|
||||
*/
|
||||
|
||||
#define MEMTAG 0x5aa5U
|
||||
|
||||
typedef struct memnod {
|
||||
unsigned int mh_tag;
|
||||
size_t mh_size;
|
||||
} MEMHDR;
|
||||
|
||||
#ifdef SUN4
|
||||
#define ALIGN_SIZE 16
|
||||
#else
|
||||
#define ALIGN_SIZE sizeof(double)
|
||||
#endif
|
||||
#define RESERVE_SIZE (((sizeof(MEMHDR) + ALIGN_SIZE - 1) \
|
||||
/ ALIGN_SIZE ) * ALIGN_SIZE)
|
||||
|
||||
#define MAX_SIZE_T ((size_t)-1)
|
||||
|
||||
#define CLIENT_2_HDR(a) ((void *) (((char *) (a)) - RESERVE_SIZE))
|
||||
#define HDR_2_CLIENT(a) ((void *) (((char *) (a)) + RESERVE_SIZE))
|
||||
|
||||
/**
|
||||
* @deprecated don't use
|
||||
*
|
||||
* @param size an int specifying the size in byte to allocate.
|
||||
* @param file the file name or NULL
|
||||
* @param line the line number
|
||||
* @returns a pointer to the allocated area or NULL in case of lack of memory.
|
||||
*/
|
||||
void *
|
||||
xmlMallocLoc(size_t size, const char *file ATTRIBUTE_UNUSED,
|
||||
int line ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return(xmlMemMalloc(size));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated don't use
|
||||
*
|
||||
* @param size an unsigned int specifying the size in byte to allocate.
|
||||
* @param file the file name or NULL
|
||||
* @param line the line number
|
||||
* @returns a pointer to the allocated area or NULL in case of lack of memory.
|
||||
*/
|
||||
void *
|
||||
xmlMallocAtomicLoc(size_t size, const char *file ATTRIBUTE_UNUSED,
|
||||
int line ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return(xmlMemMalloc(size));
|
||||
}
|
||||
|
||||
/**
|
||||
* a malloc() equivalent, with logging of the allocation info.
|
||||
*
|
||||
* @param size an int specifying the size in byte to allocate.
|
||||
* @returns a pointer to the allocated area or NULL in case of lack of memory.
|
||||
*/
|
||||
void *
|
||||
xmlMemMalloc(size_t size)
|
||||
{
|
||||
MEMHDR *p;
|
||||
|
||||
xmlInitParser();
|
||||
|
||||
if (size > (MAX_SIZE_T - RESERVE_SIZE))
|
||||
return(NULL);
|
||||
|
||||
p = (MEMHDR *) malloc(RESERVE_SIZE + size);
|
||||
if (!p)
|
||||
return(NULL);
|
||||
p->mh_tag = MEMTAG;
|
||||
p->mh_size = size;
|
||||
|
||||
xmlMutexLock(&xmlMemMutex);
|
||||
debugMemSize += size;
|
||||
debugMemBlocks++;
|
||||
xmlMutexUnlock(&xmlMemMutex);
|
||||
|
||||
return(HDR_2_CLIENT(p));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated don't use
|
||||
*
|
||||
* @param ptr the initial memory block pointer
|
||||
* @param size an int specifying the size in byte to allocate.
|
||||
* @param file the file name or NULL
|
||||
* @param line the line number
|
||||
* @returns a pointer to the allocated area or NULL in case of lack of memory.
|
||||
*/
|
||||
void *
|
||||
xmlReallocLoc(void *ptr, size_t size, const char *file ATTRIBUTE_UNUSED,
|
||||
int line ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return(xmlMemRealloc(ptr, size));
|
||||
}
|
||||
|
||||
/**
|
||||
* a realloc() equivalent, with logging of the allocation info.
|
||||
*
|
||||
* @param ptr the initial memory block pointer
|
||||
* @param size an int specifying the size in byte to allocate.
|
||||
* @returns a pointer to the allocated area or NULL in case of lack of memory.
|
||||
*/
|
||||
void *
|
||||
xmlMemRealloc(void *ptr, size_t size) {
|
||||
MEMHDR *p, *tmp;
|
||||
size_t oldSize;
|
||||
|
||||
if (ptr == NULL)
|
||||
return(xmlMemMalloc(size));
|
||||
|
||||
xmlInitParser();
|
||||
|
||||
if (size > (MAX_SIZE_T - RESERVE_SIZE))
|
||||
return(NULL);
|
||||
|
||||
p = CLIENT_2_HDR(ptr);
|
||||
if (p->mh_tag != MEMTAG) {
|
||||
xmlPrintErrorMessage("xmlMemRealloc: Tag error\n");
|
||||
return(NULL);
|
||||
}
|
||||
oldSize = p->mh_size;
|
||||
p->mh_tag = ~MEMTAG;
|
||||
|
||||
tmp = (MEMHDR *) realloc(p, RESERVE_SIZE + size);
|
||||
if (!tmp) {
|
||||
p->mh_tag = MEMTAG;
|
||||
return(NULL);
|
||||
}
|
||||
p = tmp;
|
||||
p->mh_tag = MEMTAG;
|
||||
p->mh_size = size;
|
||||
|
||||
xmlMutexLock(&xmlMemMutex);
|
||||
debugMemSize -= oldSize;
|
||||
debugMemSize += size;
|
||||
xmlMutexUnlock(&xmlMemMutex);
|
||||
|
||||
return(HDR_2_CLIENT(p));
|
||||
}
|
||||
|
||||
/**
|
||||
* a free() equivalent, with error checking.
|
||||
*
|
||||
* @param ptr the memory block pointer
|
||||
*/
|
||||
void
|
||||
xmlMemFree(void *ptr)
|
||||
{
|
||||
MEMHDR *p;
|
||||
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
|
||||
if (ptr == (void *) -1) {
|
||||
xmlPrintErrorMessage("xmlMemFree: Pointer from freed area\n");
|
||||
return;
|
||||
}
|
||||
|
||||
p = CLIENT_2_HDR(ptr);
|
||||
if (p->mh_tag != MEMTAG) {
|
||||
xmlPrintErrorMessage("xmlMemFree: Tag error\n");
|
||||
return;
|
||||
}
|
||||
p->mh_tag = ~MEMTAG;
|
||||
memset(ptr, -1, p->mh_size);
|
||||
|
||||
xmlMutexLock(&xmlMemMutex);
|
||||
debugMemSize -= p->mh_size;
|
||||
debugMemBlocks--;
|
||||
xmlMutexUnlock(&xmlMemMutex);
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated don't use
|
||||
*
|
||||
* @param str the initial string pointer
|
||||
* @param file the file name or NULL
|
||||
* @param line the line number
|
||||
* @returns a pointer to the new string or NULL if allocation error occurred.
|
||||
*/
|
||||
char *
|
||||
xmlMemStrdupLoc(const char *str, const char *file ATTRIBUTE_UNUSED,
|
||||
int line ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return(xmlMemoryStrdup(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* a strdup() equivalent, with logging of the allocation info.
|
||||
*
|
||||
* @param str the initial string pointer
|
||||
* @returns a pointer to the new string or NULL if allocation error occurred.
|
||||
*/
|
||||
char *
|
||||
xmlMemoryStrdup(const char *str) {
|
||||
char *s;
|
||||
size_t size = strlen(str) + 1;
|
||||
MEMHDR *p;
|
||||
|
||||
xmlInitParser();
|
||||
|
||||
if (size > (MAX_SIZE_T - RESERVE_SIZE))
|
||||
return(NULL);
|
||||
|
||||
p = (MEMHDR *) malloc(RESERVE_SIZE + size);
|
||||
if (!p)
|
||||
return(NULL);
|
||||
p->mh_tag = MEMTAG;
|
||||
p->mh_size = size;
|
||||
|
||||
xmlMutexLock(&xmlMemMutex);
|
||||
debugMemSize += size;
|
||||
debugMemBlocks++;
|
||||
xmlMutexUnlock(&xmlMemMutex);
|
||||
|
||||
s = (char *) HDR_2_CLIENT(p);
|
||||
|
||||
memcpy(s, str, size);
|
||||
|
||||
return(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ptr pointer to the memory allocation
|
||||
* @returns the size of a memory allocation.
|
||||
*/
|
||||
|
||||
size_t
|
||||
xmlMemSize(void *ptr) {
|
||||
MEMHDR *p;
|
||||
|
||||
if (ptr == NULL)
|
||||
return(0);
|
||||
|
||||
p = CLIENT_2_HDR(ptr);
|
||||
if (p->mh_tag != MEMTAG)
|
||||
return(0);
|
||||
|
||||
return(p->mh_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the amount of memory currently allocated
|
||||
*
|
||||
* @returns an int representing the amount of memory allocated.
|
||||
*/
|
||||
|
||||
int
|
||||
xmlMemUsed(void) {
|
||||
return(debugMemSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the number of memory areas currently allocated
|
||||
*
|
||||
* @returns an int representing the number of blocks
|
||||
*/
|
||||
|
||||
int
|
||||
xmlMemBlocks(void) {
|
||||
int res;
|
||||
|
||||
xmlMutexLock(&xmlMemMutex);
|
||||
res = debugMemBlocks;
|
||||
xmlMutexUnlock(&xmlMemMutex);
|
||||
return(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This feature was removed.
|
||||
* @param fp a FILE descriptor
|
||||
* @param nbBytes the amount of memory to dump
|
||||
*/
|
||||
void
|
||||
xmlMemDisplayLast(FILE *fp ATTRIBUTE_UNUSED, long nbBytes ATTRIBUTE_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This feature was removed.
|
||||
* @param fp a FILE descriptor
|
||||
*/
|
||||
void
|
||||
xmlMemDisplay(FILE *fp ATTRIBUTE_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This feature was removed.
|
||||
* @param fp a FILE descriptor
|
||||
* @param nr number of entries to dump
|
||||
*/
|
||||
void
|
||||
xmlMemShow(FILE *fp ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This feature was removed.
|
||||
*/
|
||||
void
|
||||
xmlMemoryDump(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* *
|
||||
* Array growth helper *
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
/**
|
||||
* Grow an array, combining overflow-checked capacity growth with
|
||||
* reallocation.
|
||||
*
|
||||
* @param array pointer to the array (may be NULL for first allocation)
|
||||
* @param elemSize size of each element in bytes
|
||||
* @param capacity pointer to current capacity (updated on success)
|
||||
* @param min initial allocation size
|
||||
* @param max maximum number of elements
|
||||
* @returns the new pointer on success, or NULL on failure with the
|
||||
* original array and capacity preserved.
|
||||
*/
|
||||
void *
|
||||
xmlGrowArray(void *array, size_t elemSize, int *capacity, int min, int max) {
|
||||
void *tmp;
|
||||
int newSize;
|
||||
|
||||
if (capacity == NULL)
|
||||
return(NULL);
|
||||
|
||||
newSize = xmlGrowCapacity(*capacity, elemSize, min, max);
|
||||
if (newSize < 0)
|
||||
return(NULL);
|
||||
|
||||
tmp = xmlRealloc(array, (size_t) newSize * elemSize);
|
||||
if (tmp == NULL)
|
||||
return(NULL);
|
||||
|
||||
*capacity = newSize;
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* *
|
||||
* Initialization Routines *
|
||||
* *
|
||||
****************************************************************/
|
||||
|
||||
/**
|
||||
* @deprecated Alias for #xmlInitParser.
|
||||
*
|
||||
* @returns 0.
|
||||
*/
|
||||
int
|
||||
xmlInitMemory(void) {
|
||||
xmlInitParser();
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the memory layer.
|
||||
*/
|
||||
void
|
||||
xmlInitMemoryInternal(void) {
|
||||
xmlInitMutex(&xmlMemMutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This function is a no-op. Call #xmlCleanupParser
|
||||
* to free global state but see the warnings there. #xmlCleanupParser
|
||||
* should be only called once at program exit. In most cases, you don't
|
||||
* have call cleanup functions at all.
|
||||
*/
|
||||
void
|
||||
xmlCleanupMemory(void) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Free up all the memory allocated by the library for its own
|
||||
* use. This should not be called by user level code.
|
||||
*/
|
||||
void
|
||||
xmlCleanupMemoryInternal(void) {
|
||||
/*
|
||||
* Don't clean up mutex on Windows. Global state destructors can call
|
||||
* malloc functions after xmlCleanupParser was called. If memory
|
||||
* debugging is enabled, xmlMemMutex can be used after cleanup.
|
||||
*
|
||||
* See python/tests/thread2.py
|
||||
*/
|
||||
#if !defined(LIBXML_THREAD_ENABLED) || !defined(_WIN32)
|
||||
xmlCleanupMutex(&xmlMemMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the default memory access functions with a new set
|
||||
* This has to be called before any other libxml routines !
|
||||
*
|
||||
* Should this be blocked if there was already some allocations
|
||||
* done ?
|
||||
*
|
||||
* @param freeFunc the free() function to use
|
||||
* @param mallocFunc the malloc() function to use
|
||||
* @param reallocFunc the realloc() function to use
|
||||
* @param strdupFunc the strdup() function to use
|
||||
* @returns 0 on success
|
||||
*/
|
||||
int
|
||||
xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
|
||||
xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) {
|
||||
if (freeFunc == NULL)
|
||||
return(-1);
|
||||
if (mallocFunc == NULL)
|
||||
return(-1);
|
||||
if (reallocFunc == NULL)
|
||||
return(-1);
|
||||
if (strdupFunc == NULL)
|
||||
return(-1);
|
||||
xmlFree = freeFunc;
|
||||
xmlMalloc = mallocFunc;
|
||||
xmlMallocAtomic = mallocFunc;
|
||||
xmlRealloc = reallocFunc;
|
||||
xmlMemStrdup = strdupFunc;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the memory access functions set currently in use
|
||||
*
|
||||
* @param freeFunc place to save the free() function in use
|
||||
* @param mallocFunc place to save the malloc() function in use
|
||||
* @param reallocFunc place to save the realloc() function in use
|
||||
* @param strdupFunc place to save the strdup() function in use
|
||||
* @returns 0 on success
|
||||
*/
|
||||
int
|
||||
xmlMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc,
|
||||
xmlReallocFunc *reallocFunc, xmlStrdupFunc *strdupFunc) {
|
||||
if (freeFunc != NULL) *freeFunc = xmlFree;
|
||||
if (mallocFunc != NULL) *mallocFunc = xmlMalloc;
|
||||
if (reallocFunc != NULL) *reallocFunc = xmlRealloc;
|
||||
if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the default memory access functions with a new set
|
||||
* This has to be called before any other libxml routines !
|
||||
* The mallocAtomicFunc is specialized for atomic block
|
||||
* allocations (i.e. of areas useful for garbage collected memory allocators
|
||||
*
|
||||
* @deprecated Use #xmlMemSetup.
|
||||
*
|
||||
* Should this be blocked if there was already some allocations
|
||||
* done ?
|
||||
*
|
||||
* @param freeFunc the free() function to use
|
||||
* @param mallocFunc the malloc() function to use
|
||||
* @param mallocAtomicFunc the malloc() function to use for atomic allocations
|
||||
* @param reallocFunc the realloc() function to use
|
||||
* @param strdupFunc the strdup() function to use
|
||||
* @returns 0 on success
|
||||
*/
|
||||
int
|
||||
xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
|
||||
xmlMallocFunc mallocAtomicFunc, xmlReallocFunc reallocFunc,
|
||||
xmlStrdupFunc strdupFunc) {
|
||||
if (freeFunc == NULL)
|
||||
return(-1);
|
||||
if (mallocFunc == NULL)
|
||||
return(-1);
|
||||
if (mallocAtomicFunc == NULL)
|
||||
return(-1);
|
||||
if (reallocFunc == NULL)
|
||||
return(-1);
|
||||
if (strdupFunc == NULL)
|
||||
return(-1);
|
||||
xmlFree = freeFunc;
|
||||
xmlMalloc = mallocFunc;
|
||||
xmlMallocAtomic = mallocAtomicFunc;
|
||||
xmlRealloc = reallocFunc;
|
||||
xmlMemStrdup = strdupFunc;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the memory access functions set currently in use
|
||||
* The mallocAtomicFunc is specialized for atomic block
|
||||
* allocations (i.e. of areas useful for garbage collected memory allocators
|
||||
*
|
||||
* @deprecated Use #xmlMemGet.
|
||||
*
|
||||
* @param freeFunc place to save the free() function in use
|
||||
* @param mallocFunc place to save the malloc() function in use
|
||||
* @param mallocAtomicFunc place to save the atomic malloc() function in use
|
||||
* @param reallocFunc place to save the realloc() function in use
|
||||
* @param strdupFunc place to save the strdup() function in use
|
||||
* @returns 0 on success
|
||||
*/
|
||||
int
|
||||
xmlGcMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc,
|
||||
xmlMallocFunc *mallocAtomicFunc, xmlReallocFunc *reallocFunc,
|
||||
xmlStrdupFunc *strdupFunc) {
|
||||
if (freeFunc != NULL) *freeFunc = xmlFree;
|
||||
if (mallocFunc != NULL) *mallocFunc = xmlMalloc;
|
||||
if (mallocAtomicFunc != NULL) *mallocAtomicFunc = xmlMallocAtomic;
|
||||
if (reallocFunc != NULL) *reallocFunc = xmlRealloc;
|
||||
if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup;
|
||||
return(0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user