]> git.saurik.com Git - apple/icu.git/blame - icuSources/common/cmemory.c
ICU-400.42.tar.gz
[apple/icu.git] / icuSources / common / cmemory.c
CommitLineData
b75a7d8f
A
1/*
2******************************************************************************
3*
374ca955 4* Copyright (C) 2002-2003, International Business Machines
b75a7d8f
A
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*/
374ca955 21#include "unicode/uclean.h"
73c04bcf
A
22#include "cmemory.h"
23#include <stdlib.h>
b75a7d8f
A
24
25/* uprv_malloc(0) returns a pointer to this read-only data. */
26static const int32_t zeroMem[] = {0, 0, 0, 0, 0, 0};
27
374ca955
A
28/* Function Pointers for user-supplied heap functions */
29static const void *pContext;
30static UMemAllocFn *pAlloc;
31static UMemReallocFn *pRealloc;
32static 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 */
36static UBool gHeapInUse;
37
b75a7d8f
A
38U_CAPI void * U_EXPORT2
39uprv_malloc(size_t s) {
40 if (s > 0) {
374ca955
A
41 gHeapInUse = TRUE;
42 if (pAlloc) {
43 return (*pAlloc)(pContext, s);
44 } else {
45 return malloc(s);
46 }
b75a7d8f
A
47 } else {
48 return (void *)zeroMem;
49 }
50}
51
52U_CAPI void * U_EXPORT2
53uprv_realloc(void * buffer, size_t size) {
54 if (buffer == zeroMem) {
55 return uprv_malloc(size);
56 } else if (size == 0) {
374ca955
A
57 if (pFree) {
58 (*pFree)(pContext, buffer);
59 } else {
60 free(buffer);
61 }
b75a7d8f
A
62 return (void *)zeroMem;
63 } else {
374ca955
A
64 gHeapInUse = TRUE;
65 if (pRealloc) {
66 return (*pRealloc)(pContext, buffer, size);
67 } else {
68 return realloc(buffer, size);
69 }
b75a7d8f
A
70 }
71}
72
73U_CAPI void U_EXPORT2
74uprv_free(void *buffer) {
75 if (buffer != zeroMem) {
374ca955
A
76 if (pFree) {
77 (*pFree)(pContext, buffer);
78 } else {
79 free(buffer);
80 }
81 }
82}
83
84U_CAPI void U_EXPORT2
85u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *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;
b75a7d8f 97 }
374ca955
A
98 pContext = context;
99 pAlloc = a;
100 pRealloc = r;
101 pFree = f;
102}
103
104
105U_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 */
121U_CFUNC UBool cmemory_inUse() {
122 return gHeapInUse;
b75a7d8f
A
123}
124