]> git.sur5r.net Git - openldap/blob - libraries/liblber/memory.c
4be2072b6181b3bac113f11eb5d539dc9f1d7e5b
[openldap] / libraries / liblber / memory.c
1 /*
2  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5 #include "portable.h"
6
7 #include <ac/stdlib.h>
8 #include <ac/string.h>
9
10 #undef LDAP_F_PRE
11 #define LDAP_F_PRE LDAP_F_EXPORT
12
13 #include "lber-int.h"
14
15 #if LDAP_MEMORY_DEBUG
16 struct ber_mem_hdr {
17         union bmu_align_u {
18                 size_t  bmu_size_t;
19                 void *  bmu_voidp;
20                 double  bmu_double;
21                 long    bmu_long;
22                 char    bmu_char[4];
23         } ber_align;
24 #define bm_junk ber_align.bmu_size_t
25 #define bm_data ber_align.bmu_char[1]
26 };
27 #define BER_MEM_JUNK 0xddeeddeeU
28 static const struct ber_mem_hdr ber_int_mem_hdr = { BER_MEM_JUNK };
29 #define BER_MEM_BADADDR ((void *) &ber_int_mem_hdr.bm_data)
30 #define BER_MEM_VALID(p)        do { \
31                 assert( (p) != BER_MEM_BADADDR );       \
32                 assert( (p) != (void *) &ber_int_mem_hdr );     \
33         } while(1)
34 #else
35 #define BER_MEM_VALID(p)        /* no-op */
36 #endif
37
38 BerMemoryFunctions *ber_int_memory_fns = NULL;
39
40 #if 0 && defined( LDAP_MEMORY_DEBUG )
41 void
42 ber_int_memfree( void **p )
43 {
44         assert( p != NULL );
45         BER_MEM_VALID( *p )
46
47         ber_memfree( p );
48
49         *p = BER_MEM_BADADDR;
50 }
51 #endif
52
53 void
54 ber_memfree( void *p )
55 {
56     ber_int_options.lbo_valid = LBER_INITIALIZED;
57
58         /* ignore p == NULL when not debugging */
59         if( p == NULL ) {
60                 return;
61         }
62
63         BER_MEM_VALID( p )
64
65         if( ber_int_memory_fns == NULL ) {
66 #ifdef LDAP_MEMORY_DEBUG
67                 struct ber_mem_hdr *mh = (struct ber_mem_hdr *)
68                         ((char *)p - sizeof(struct ber_mem_hdr));
69
70                 assert( mh->bm_junk == BER_MEM_JUNK );                          
71                 mh->bm_junk = ~BER_MEM_JUNK;
72                 free( mh );
73 #else
74                 free( p );
75 #endif
76                 return;
77         }
78
79         assert( ber_int_memory_fns->bmf_free );
80
81                 
82         (*ber_int_memory_fns->bmf_free)( p );
83 }
84
85
86 void
87 ber_memvfree( void **vec )
88 {
89         int     i;
90
91     ber_int_options.lbo_valid = LBER_INITIALIZED;
92
93         if( vec == NULL ) {
94                 return;
95         }
96
97         BER_MEM_VALID( vec )
98
99         for ( i = 0; vec[i] != NULL; i++ ) {
100                 LBER_FREE( vec[i] );
101         }
102
103         LBER_FREE( vec );
104 }
105
106
107 void *
108 ber_memalloc( size_t s )
109 {
110     ber_int_options.lbo_valid = LBER_INITIALIZED;
111
112 #ifdef LDAP_MEMORY_DEBUG
113         /* catch s == 0 when debugging */
114         assert( s );
115 #endif
116
117         /* ignore s == 0 when not debugging */
118         if( s == 0 ) {
119                 return NULL;
120         }
121
122         if( ber_int_memory_fns == NULL ) {
123 #ifdef LDAP_MEMORY_DEBUG
124                 struct ber_mem_hdr *mh = malloc(s + sizeof(struct ber_mem_hdr));
125
126                 if( mh == NULL ) return NULL;
127
128                 mh->bm_junk = BER_MEM_JUNK;
129
130                 BER_MEM_VALID( &mh[1] )
131                 return &mh[1];
132 #else
133                 return malloc( s );
134 #endif
135         }
136
137         assert( ber_int_memory_fns->bmf_malloc );
138
139         return (*ber_int_memory_fns->bmf_malloc)( s );
140 }
141
142
143 void *
144 ber_memcalloc( size_t n, size_t s )
145 {
146     ber_int_options.lbo_valid = LBER_INITIALIZED;
147
148 #ifdef LDAP_MEMORY_DEBUG
149         /* catch s,n == 0 when debugging */
150         assert( n && s );
151 #endif
152
153         /* ignore s,n == 0 when not debugging */
154         if( n == 0 || s == 0 ) {
155                 return NULL;
156         }
157
158         if( ber_int_memory_fns == NULL ) {
159 #ifdef LDAP_MEMORY_DEBUG
160                 struct ber_mem_hdr *mh = calloc(1,
161                         (n * s) + sizeof(struct ber_mem_hdr) );
162
163                 mh->bm_junk = BER_MEM_JUNK;
164
165                 BER_MEM_VALID( &mh[1] )
166                 return &mh[1];
167 #else
168                 return calloc( n, s );
169 #endif
170         }
171
172         assert( ber_int_memory_fns->bmf_calloc );
173
174         return (*ber_int_memory_fns->bmf_calloc)( n, s );
175 }
176
177
178 void *
179 ber_memrealloc( void* p, size_t s )
180 {
181     ber_int_options.lbo_valid = LBER_INITIALIZED;
182
183         /* realloc(NULL,s) -> malloc(s) */
184         if( p == NULL ) {
185                 return ber_memalloc( s );
186         }
187         
188         /* realloc(p,0) -> free(p) */
189         if( s == 0 ) {
190                 ber_memfree( p );
191                 return NULL;
192         }
193
194         BER_MEM_VALID( p )
195
196         if( ber_int_memory_fns == NULL ) {
197 #ifdef LDAP_MEMORY_DEBUG
198                 struct ber_mem_hdr *mh = (struct ber_mem_hdr *)
199                         ((char *)p - sizeof(struct ber_mem_hdr));
200                 assert( mh->bm_junk == BER_MEM_JUNK );
201
202                 p = realloc( mh, s );
203
204                 if( p == NULL ) return NULL;
205
206                 mh = p;
207
208                 assert( mh->bm_junk == BER_MEM_JUNK );
209
210                 BER_MEM_VALID( &mh[1] )
211                 return &mh[1];
212 #else
213                 return realloc( p, s );
214 #endif
215         }
216
217         assert( ber_int_memory_fns->bmf_realloc );
218
219         return (*ber_int_memory_fns->bmf_realloc)( p, s );
220 }
221
222
223 void
224 ber_bvfree( struct berval *bv )
225 {
226         ber_int_options.lbo_valid = LBER_INITIALIZED;
227
228         if( bv == NULL ) {
229                 return;
230         }
231
232         BER_MEM_VALID( bv )
233
234         if ( bv->bv_val != NULL )
235                 LBER_FREE( bv->bv_val );
236
237         LBER_FREE( (char *) bv );
238 }
239
240
241 void
242 ber_bvecfree( struct berval **bv )
243 {
244         int     i;
245
246         ber_int_options.lbo_valid = LBER_INITIALIZED;
247
248         if( bv == NULL ) {
249                 return;
250         }
251
252         BER_MEM_VALID( bv )
253
254         for ( i = 0; bv[i] != NULL; i++ )
255                 ber_bvfree( bv[i] );
256
257         LBER_FREE( (char *) bv );
258 }
259
260
261 struct berval *
262 ber_bvdup(
263         LDAP_CONST struct berval *bv )
264 {
265         struct berval *new;
266
267         ber_int_options.lbo_valid = LBER_INITIALIZED;
268
269         if( bv == NULL ) {
270                 return NULL;
271         }
272
273         if(( new = LBER_MALLOC( sizeof(struct berval) )) == NULL ) {
274                 return NULL;
275         }
276
277         if ( bv->bv_val == NULL ) {
278                 new->bv_val = NULL;
279                 new->bv_len = 0;
280                 return new;
281         }
282
283         if(( new->bv_val = LBER_MALLOC( bv->bv_len + 1 )) == NULL ) {
284                 LBER_FREE( new );
285                 return NULL;
286         }
287
288         SAFEMEMCPY( new->bv_val, bv->bv_val, (size_t) bv->bv_len );
289         new->bv_val[bv->bv_len] = '\0';
290         new->bv_len = bv->bv_len;
291
292         return( new );
293 }
294
295 char *
296 ber_strdup( LDAP_CONST char *s )
297 {
298         char    *p;
299         size_t  len;
300         
301         ber_int_options.lbo_valid = LBER_INITIALIZED;
302
303 #ifdef LDAP_MEMORY_DEBUG
304         assert(s != NULL);                      /* bv damn better point to something */
305 #endif
306
307         if( s == NULL ) {
308                 return( NULL );
309         }
310
311         len = strlen( s ) + 1;
312
313         if ( (p = (char *) LBER_MALLOC( len )) == NULL ) {
314                 return( NULL );
315         }
316
317         SAFEMEMCPY( p, s, len );
318         return( p );
319 }