]> git.sur5r.net Git - openldap/blob - libraries/liblber/memory.c
312ab796fdad850d79bbbb8eb82c56a8876bf268
[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                 ber_len_t       bmu_len_t;
19                 ber_tag_t       bmu_tag_t;
20                 ber_int_t       bmu_int_t;
21
22                 size_t  bmu_size_t;
23                 void *  bmu_voidp;
24                 double  bmu_double;
25                 long    bmu_long;
26                 long    (*bmu_funcp)( double );
27                 char    bmu_char[4];
28         } ber_align;
29 #define bm_junk ber_align.bmu_len_t
30 #define bm_data ber_align.bmu_char[1]
31 };
32 #define BER_MEM_JUNK 0xddeeddeeU
33 static const struct ber_mem_hdr ber_int_mem_hdr = { BER_MEM_JUNK };
34 #define BER_MEM_BADADDR ((void *) &ber_int_mem_hdr.bm_data)
35 #define BER_MEM_VALID(p)        do { \
36                 assert( (p) != BER_MEM_BADADDR );       \
37                 assert( (p) != (void *) &ber_int_mem_hdr );     \
38         } while(0)
39 #else
40 #define BER_MEM_VALID(p)        /* no-op */
41 #endif
42
43 BerMemoryFunctions *ber_int_memory_fns = NULL;
44
45 #if 0 && defined( LDAP_MEMORY_DEBUG )
46 void
47 ber_int_memfree( void **p )
48 {
49         assert( p != NULL );
50         BER_MEM_VALID( *p );
51
52         ber_memfree( p );
53
54         *p = BER_MEM_BADADDR;
55 }
56 #endif
57
58 void
59 ber_memfree( void *p )
60 {
61     ber_int_options.lbo_valid = LBER_INITIALIZED;
62
63         if( p == NULL ) {
64                 return;
65         }
66
67         BER_MEM_VALID( p );
68
69         if( ber_int_memory_fns == NULL ) {
70 #ifdef LDAP_MEMORY_DEBUG
71                 struct ber_mem_hdr *mh = (struct ber_mem_hdr *)
72                         ((char *)p - sizeof(struct ber_mem_hdr));
73
74                 assert( mh->bm_junk == BER_MEM_JUNK );                          
75                 mh->bm_junk = ~BER_MEM_JUNK;
76                 free( mh );
77 #else
78                 free( p );
79 #endif
80                 return;
81         }
82
83         assert( ber_int_memory_fns->bmf_free );
84
85                 
86         (*ber_int_memory_fns->bmf_free)( p );
87 }
88
89
90 void
91 ber_memvfree( void **vec )
92 {
93         int     i;
94
95     ber_int_options.lbo_valid = LBER_INITIALIZED;
96
97         if( vec == NULL ) {
98                 return;
99         }
100
101         BER_MEM_VALID( vec );
102
103         for ( i = 0; vec[i] != NULL; i++ ) {
104                 LBER_FREE( vec[i] );
105         }
106
107         LBER_FREE( vec );
108 }
109
110
111 void *
112 ber_memalloc( ber_len_t s )
113 {
114     ber_int_options.lbo_valid = LBER_INITIALIZED;
115
116 #ifdef LDAP_MEMORY_DEBUG
117         assert( s != 0 );
118 #endif
119
120         if( s == 0 ) {
121                 return NULL;
122         }
123
124         if( ber_int_memory_fns == NULL ) {
125 #ifdef LDAP_MEMORY_DEBUG
126                 struct ber_mem_hdr *mh = malloc(s + sizeof(struct ber_mem_hdr));
127
128                 if( mh == NULL ) return NULL;
129
130                 mh->bm_junk = BER_MEM_JUNK;
131
132                 BER_MEM_VALID( &mh[1] );
133                 return &mh[1];
134 #else
135                 return malloc( s );
136 #endif
137         }
138
139         assert( ber_int_memory_fns->bmf_malloc );
140
141         return (*ber_int_memory_fns->bmf_malloc)( s );
142 }
143
144
145 void *
146 ber_memcalloc( ber_len_t n, ber_len_t s )
147 {
148     ber_int_options.lbo_valid = LBER_INITIALIZED;
149
150 #ifdef LDAP_MEMORY_DEBUG
151         assert( n != 0 && s != 0);
152 #endif
153
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, ber_len_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 + sizeof(struct ber_mem_hdr) );
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, 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 = LBER_MALLOC( len )) == NULL ) {
314                 return( NULL );
315         }
316
317         SAFEMEMCPY( p, s, len );
318         return( p );
319 }