OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ****************************************************************************** |
| 3 * |
| 4 * Copyright (C) 2002-2003, International Business Machines |
| 5 * Corporation and others. All Rights Reserved. |
| 6 * |
| 7 ****************************************************************************** |
| 8 * |
| 9 * File cmemory.c ICU Heap allocation. |
| 10 * All ICU heap allocation, both for C and C++ new of ICU |
| 11 * class types, comes through these functions. |
| 12 * |
| 13 * If you have a need to replace ICU allocation, this is the |
| 14 * place to do it. |
| 15 * |
| 16 * Note that uprv_malloc(0) returns a non-NULL pointer, and |
| 17 * that a subsequent free of that pointer value is a NOP. |
| 18 * |
| 19 ****************************************************************************** |
| 20 */ |
| 21 #include "unicode/uclean.h" |
| 22 #include "cmemory.h" |
| 23 #include <stdlib.h> |
| 24 |
| 25 /* uprv_malloc(0) returns a pointer to this read-only data. */ |
| 26 static const int32_t zeroMem[] = {0, 0, 0, 0, 0, 0}; |
| 27 |
| 28 /* Function Pointers for user-supplied heap functions */ |
| 29 static const void *pContext; |
| 30 static UMemAllocFn *pAlloc; |
| 31 static UMemReallocFn *pRealloc; |
| 32 static UMemFreeFn *pFree; |
| 33 |
| 34 /* Flag indicating whether any heap allocations have happened. |
| 35 * Used to prevent changing out the heap functions after allocations have been
made */ |
| 36 static UBool gHeapInUse; |
| 37 |
| 38 U_CAPI void * U_EXPORT2 |
| 39 uprv_malloc(size_t s) { |
| 40 if (s > 0) { |
| 41 gHeapInUse = TRUE; |
| 42 if (pAlloc) { |
| 43 return (*pAlloc)(pContext, s); |
| 44 } else { |
| 45 return malloc(s); |
| 46 } |
| 47 } else { |
| 48 return (void *)zeroMem; |
| 49 } |
| 50 } |
| 51 |
| 52 U_CAPI void * U_EXPORT2 |
| 53 uprv_realloc(void * buffer, size_t size) { |
| 54 if (buffer == zeroMem) { |
| 55 return uprv_malloc(size); |
| 56 } else if (size == 0) { |
| 57 if (pFree) { |
| 58 (*pFree)(pContext, buffer); |
| 59 } else { |
| 60 free(buffer); |
| 61 } |
| 62 return (void *)zeroMem; |
| 63 } else { |
| 64 gHeapInUse = TRUE; |
| 65 if (pRealloc) { |
| 66 return (*pRealloc)(pContext, buffer, size); |
| 67 } else { |
| 68 return realloc(buffer, size); |
| 69 } |
| 70 } |
| 71 } |
| 72 |
| 73 U_CAPI void U_EXPORT2 |
| 74 uprv_free(void *buffer) { |
| 75 if (buffer != zeroMem) { |
| 76 if (pFree) { |
| 77 (*pFree)(pContext, buffer); |
| 78 } else { |
| 79 free(buffer); |
| 80 } |
| 81 } |
| 82 } |
| 83 |
| 84 U_CAPI void U_EXPORT2 |
| 85 u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMem
FreeFn *f, UErrorCode *status) |
| 86 { |
| 87 if (U_FAILURE(*status)) { |
| 88 return; |
| 89 } |
| 90 if (a==NULL || r==NULL || f==NULL) { |
| 91 *status = U_ILLEGAL_ARGUMENT_ERROR; |
| 92 return; |
| 93 } |
| 94 if (gHeapInUse) { |
| 95 *status = U_INVALID_STATE_ERROR; |
| 96 return; |
| 97 } |
| 98 pContext = context; |
| 99 pAlloc = a; |
| 100 pRealloc = r; |
| 101 pFree = f; |
| 102 } |
| 103 |
| 104 |
| 105 U_CFUNC UBool cmemory_cleanup(void) { |
| 106 pContext = NULL; |
| 107 pAlloc = NULL; |
| 108 pRealloc = NULL; |
| 109 pFree = NULL; |
| 110 gHeapInUse = FALSE; |
| 111 return TRUE; |
| 112 } |
| 113 |
| 114 |
| 115 /* |
| 116 * gHeapInUse |
| 117 * Return True if ICU has allocated any memory. |
| 118 * Used by u_SetMutexFunctions() and similar to verify that ICU has not |
| 119 * been used, that it is in a pristine initial state. |
| 120 */ |
| 121 U_CFUNC UBool cmemory_inUse() { |
| 122 return gHeapInUse; |
| 123 } |
| 124 |
OLD | NEW |