VirtualBox

source: vbox/trunk/src/libs/libxml2-2.13.2/xmlmemory.c@ 105770

Last change on this file since 105770 was 105421, checked in by vboxsync, 4 months ago

libxml2-2.13.2: Fixes to make it build. bugref:10730

  • Property svn:eol-style set to native
File size: 12.8 KB
Line 
1/*
2 * xmlmemory.c: libxml memory allocator wrapper.
3 *
4 * daniel@veillard.com
5 */
6
7#define IN_LIBXML
8#include "libxml.h"
9
10#include <string.h>
11#include <stdlib.h>
12#include <ctype.h>
13#include <time.h>
14
15#include <libxml/xmlmemory.h>
16#include <libxml/xmlerror.h>
17#include <libxml/parser.h>
18#include <libxml/threads.h>
19
20#include "private/memory.h"
21#include "private/threads.h"
22
23static unsigned long debugMemSize = 0;
24static unsigned long debugMemBlocks = 0;
25static xmlMutex xmlMemMutex;
26
27/************************************************************************
28 * *
29 * Macros, variables and associated types *
30 * *
31 ************************************************************************/
32
33/*
34 * Each of the blocks allocated begin with a header containing information
35 */
36
37#define MEMTAG 0x5aa5U
38
39typedef struct memnod {
40 unsigned int mh_tag;
41 size_t mh_size;
42} MEMHDR;
43
44#ifdef SUN4
45#define ALIGN_SIZE 16
46#else
47#define ALIGN_SIZE sizeof(double)
48#endif
49#define RESERVE_SIZE (((sizeof(MEMHDR) + ALIGN_SIZE - 1) \
50 / ALIGN_SIZE ) * ALIGN_SIZE)
51
52#define MAX_SIZE_T ((size_t)-1)
53
54#define CLIENT_2_HDR(a) ((void *) (((char *) (a)) - RESERVE_SIZE))
55#define HDR_2_CLIENT(a) ((void *) (((char *) (a)) + RESERVE_SIZE))
56
57/**
58 * xmlMallocLoc:
59 * @size: an int specifying the size in byte to allocate.
60 * @file: the file name or NULL
61 * @line: the line number
62 *
63 * DEPRECATED: don't use
64 *
65 * Returns a pointer to the allocated area or NULL in case of lack of memory.
66 */
67void *
68xmlMallocLoc(size_t size, const char *file ATTRIBUTE_UNUSED,
69 int line ATTRIBUTE_UNUSED)
70{
71 return(xmlMemMalloc(size));
72}
73
74/**
75 * xmlMallocAtomicLoc:
76 * @size: an unsigned int specifying the size in byte to allocate.
77 * @file: the file name or NULL
78 * @line: the line number
79 *
80 * DEPRECATED: don't use
81 *
82 * Returns a pointer to the allocated area or NULL in case of lack of memory.
83 */
84void *
85xmlMallocAtomicLoc(size_t size, const char *file ATTRIBUTE_UNUSED,
86 int line ATTRIBUTE_UNUSED)
87{
88 return(xmlMemMalloc(size));
89}
90
91/**
92 * xmlMemMalloc:
93 * @size: an int specifying the size in byte to allocate.
94 *
95 * a malloc() equivalent, with logging of the allocation info.
96 *
97 * Returns a pointer to the allocated area or NULL in case of lack of memory.
98 */
99void *
100xmlMemMalloc(size_t size)
101{
102 MEMHDR *p;
103
104 xmlInitParser();
105
106 if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
107 fprintf(stderr, "xmlMemMalloc: Unsigned overflow\n");
108 return(NULL);
109 }
110
111 p = (MEMHDR *) malloc(RESERVE_SIZE + size);
112 if (!p) {
113 fprintf(stderr, "xmlMemMalloc: Out of memory\n");
114 return(NULL);
115 }
116 p->mh_tag = MEMTAG;
117 p->mh_size = size;
118
119 xmlMutexLock(&xmlMemMutex);
120 debugMemSize += size;
121 debugMemBlocks++;
122 xmlMutexUnlock(&xmlMemMutex);
123
124 return(HDR_2_CLIENT(p));
125}
126
127/**
128 * xmlReallocLoc:
129 * @ptr: the initial memory block pointer
130 * @size: an int specifying the size in byte to allocate.
131 * @file: the file name or NULL
132 * @line: the line number
133 *
134 * DEPRECATED: don't use
135 *
136 * Returns a pointer to the allocated area or NULL in case of lack of memory.
137 */
138void *
139xmlReallocLoc(void *ptr, size_t size, const char *file ATTRIBUTE_UNUSED,
140 int line ATTRIBUTE_UNUSED)
141{
142 return(xmlMemRealloc(ptr, size));
143}
144
145/**
146 * xmlMemRealloc:
147 * @ptr: the initial memory block pointer
148 * @size: an int specifying the size in byte to allocate.
149 *
150 * a realloc() equivalent, with logging of the allocation info.
151 *
152 * Returns a pointer to the allocated area or NULL in case of lack of memory.
153 */
154void *
155xmlMemRealloc(void *ptr, size_t size) {
156 MEMHDR *p, *tmp;
157 size_t oldSize;
158
159 if (ptr == NULL)
160 return(xmlMemMalloc(size));
161
162 xmlInitParser();
163
164 if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
165 fprintf(stderr, "xmlMemRealloc: Unsigned overflow\n");
166 return(NULL);
167 }
168
169 p = CLIENT_2_HDR(ptr);
170 if (p->mh_tag != MEMTAG) {
171 fprintf(stderr, "xmlMemRealloc: Tag error\n");
172 return(NULL);
173 }
174 oldSize = p->mh_size;
175 p->mh_tag = ~MEMTAG;
176
177 tmp = (MEMHDR *) realloc(p, RESERVE_SIZE + size);
178 if (!tmp) {
179 p->mh_tag = MEMTAG;
180 fprintf(stderr, "xmlMemRealloc: Out of memory\n");
181 return(NULL);
182 }
183 p = tmp;
184 p->mh_tag = MEMTAG;
185 p->mh_size = size;
186
187 xmlMutexLock(&xmlMemMutex);
188 debugMemSize -= oldSize;
189 debugMemSize += size;
190 xmlMutexUnlock(&xmlMemMutex);
191
192 return(HDR_2_CLIENT(p));
193}
194
195/**
196 * xmlMemFree:
197 * @ptr: the memory block pointer
198 *
199 * a free() equivalent, with error checking.
200 */
201void
202xmlMemFree(void *ptr)
203{
204 MEMHDR *p;
205
206 if (ptr == NULL)
207 return;
208
209 if (ptr == (void *) -1) {
210 fprintf(stderr, "xmlMemFree: Pointer from freed area\n");
211 return;
212 }
213
214 p = CLIENT_2_HDR(ptr);
215 if (p->mh_tag != MEMTAG) {
216 fprintf(stderr, "xmlMemFree: Tag error\n");
217 return;
218 }
219 p->mh_tag = ~MEMTAG;
220 memset(ptr, -1, p->mh_size);
221
222 xmlMutexLock(&xmlMemMutex);
223 debugMemSize -= p->mh_size;
224 debugMemBlocks--;
225 xmlMutexUnlock(&xmlMemMutex);
226
227 free(p);
228
229 return;
230}
231
232/**
233 * xmlMemStrdupLoc:
234 * @str: the initial string pointer
235 * @file: the file name or NULL
236 * @line: the line number
237 *
238 * DEPRECATED: don't use
239 *
240 * Returns a pointer to the new string or NULL if allocation error occurred.
241 */
242char *
243xmlMemStrdupLoc(const char *str, const char *file ATTRIBUTE_UNUSED,
244 int line ATTRIBUTE_UNUSED)
245{
246 return(xmlMemoryStrdup(str));
247}
248
249/**
250 * xmlMemoryStrdup:
251 * @str: the initial string pointer
252 *
253 * a strdup() equivalent, with logging of the allocation info.
254 *
255 * Returns a pointer to the new string or NULL if allocation error occurred.
256 */
257char *
258xmlMemoryStrdup(const char *str) {
259 char *s;
260 size_t size = strlen(str) + 1;
261 MEMHDR *p;
262
263 xmlInitParser();
264
265 if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
266 fprintf(stderr, "xmlMemoryStrdup: Unsigned overflow\n");
267 return(NULL);
268 }
269
270 p = (MEMHDR *) malloc(RESERVE_SIZE + size);
271 if (!p) {
272 fprintf(stderr, "xmlMemoryStrdup: Out of memory\n");
273 return(NULL);
274 }
275 p->mh_tag = MEMTAG;
276 p->mh_size = size;
277
278 xmlMutexLock(&xmlMemMutex);
279 debugMemSize += size;
280 debugMemBlocks++;
281 xmlMutexUnlock(&xmlMemMutex);
282
283 s = (char *) HDR_2_CLIENT(p);
284
285 memcpy(s, str, size);
286
287 return(s);
288}
289
290/**
291 * xmlMemSize:
292 * @ptr: pointer to the memory allocation
293 *
294 * Returns the size of a memory allocation.
295 */
296
297size_t
298xmlMemSize(void *ptr) {
299 MEMHDR *p;
300
301 if (ptr == NULL)
302 return(0);
303
304 p = CLIENT_2_HDR(ptr);
305 if (p->mh_tag != MEMTAG)
306 return(0);
307
308 return(p->mh_size);
309}
310
311/**
312 * xmlMemUsed:
313 *
314 * Provides the amount of memory currently allocated
315 *
316 * Returns an int representing the amount of memory allocated.
317 */
318
319int
320xmlMemUsed(void) {
321 return(debugMemSize);
322}
323
324/**
325 * xmlMemBlocks:
326 *
327 * Provides the number of memory areas currently allocated
328 *
329 * Returns an int representing the number of blocks
330 */
331
332int
333xmlMemBlocks(void) {
334 int res;
335
336 xmlMutexLock(&xmlMemMutex);
337 res = debugMemBlocks;
338 xmlMutexUnlock(&xmlMemMutex);
339 return(res);
340}
341
342/**
343 * xmlMemDisplayLast:
344 * @fp: a FILE descriptor
345 * @nbBytes: the amount of memory to dump
346 *
347 * DEPRECATED: This feature was removed.
348 */
349void
350xmlMemDisplayLast(FILE *fp ATTRIBUTE_UNUSED, long nbBytes ATTRIBUTE_UNUSED)
351{
352}
353
354/**
355 * xmlMemDisplay:
356 * @fp: a FILE descriptor
357 *
358 * DEPRECATED: This feature was removed.
359 */
360void
361xmlMemDisplay(FILE *fp ATTRIBUTE_UNUSED)
362{
363}
364
365/**
366 * xmlMemShow:
367 * @fp: a FILE descriptor
368 * @nr: number of entries to dump
369 *
370 * DEPRECATED: This feature was removed.
371 */
372void
373xmlMemShow(FILE *fp ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED)
374{
375}
376
377/**
378 * xmlMemoryDump:
379 *
380 * DEPRECATED: This feature was removed.
381 */
382void
383xmlMemoryDump(void)
384{
385}
386
387
388/****************************************************************
389 * *
390 * Initialization Routines *
391 * *
392 ****************************************************************/
393
394/**
395 * xmlInitMemory:
396 *
397 * DEPRECATED: Alias for xmlInitParser.
398 *
399 * Returns 0.
400 */
401int
402xmlInitMemory(void) {
403 xmlInitParser();
404 return(0);
405}
406
407/**
408 * xmlInitMemoryInternal:
409 *
410 * Initialize the memory layer.
411 */
412void
413xmlInitMemoryInternal(void) {
414 xmlInitMutex(&xmlMemMutex);
415}
416
417/**
418 * xmlCleanupMemory:
419 *
420 * DEPRECATED: This function is a no-op. Call xmlCleanupParser
421 * to free global state but see the warnings there. xmlCleanupParser
422 * should be only called once at program exit. In most cases, you don't
423 * have call cleanup functions at all.
424 */
425void
426xmlCleanupMemory(void) {
427}
428
429/**
430 * xmlCleanupMemoryInternal:
431 *
432 * Free up all the memory allocated by the library for its own
433 * use. This should not be called by user level code.
434 */
435void
436xmlCleanupMemoryInternal(void) {
437 /*
438 * Don't clean up mutex on Windows. Global state destructors can call
439 * malloc functions after xmlCleanupParser was called. If memory
440 * debugging is enabled, xmlMemMutex can be used after cleanup.
441 *
442 * See python/tests/thread2.py
443 */
444#if !defined(LIBXML_THREAD_ENABLED) || !defined(_WIN32)
445 xmlCleanupMutex(&xmlMemMutex);
446#endif
447}
448
449/**
450 * xmlMemSetup:
451 * @freeFunc: the free() function to use
452 * @mallocFunc: the malloc() function to use
453 * @reallocFunc: the realloc() function to use
454 * @strdupFunc: the strdup() function to use
455 *
456 * Override the default memory access functions with a new set
457 * This has to be called before any other libxml routines !
458 *
459 * Should this be blocked if there was already some allocations
460 * done ?
461 *
462 * Returns 0 on success
463 */
464int
465xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
466 xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) {
467 if (freeFunc == NULL)
468 return(-1);
469 if (mallocFunc == NULL)
470 return(-1);
471 if (reallocFunc == NULL)
472 return(-1);
473 if (strdupFunc == NULL)
474 return(-1);
475 xmlFree = freeFunc;
476 xmlMalloc = mallocFunc;
477 xmlMallocAtomic = mallocFunc;
478 xmlRealloc = reallocFunc;
479 xmlMemStrdup = strdupFunc;
480 return(0);
481}
482
483/**
484 * xmlMemGet:
485 * @freeFunc: place to save the free() function in use
486 * @mallocFunc: place to save the malloc() function in use
487 * @reallocFunc: place to save the realloc() function in use
488 * @strdupFunc: place to save the strdup() function in use
489 *
490 * Provides the memory access functions set currently in use
491 *
492 * Returns 0 on success
493 */
494int
495xmlMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc,
496 xmlReallocFunc *reallocFunc, xmlStrdupFunc *strdupFunc) {
497 if (freeFunc != NULL) *freeFunc = xmlFree;
498 if (mallocFunc != NULL) *mallocFunc = xmlMalloc;
499 if (reallocFunc != NULL) *reallocFunc = xmlRealloc;
500 if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup;
501 return(0);
502}
503
504/**
505 * xmlGcMemSetup:
506 * @freeFunc: the free() function to use
507 * @mallocFunc: the malloc() function to use
508 * @mallocAtomicFunc: the malloc() function to use for atomic allocations
509 * @reallocFunc: the realloc() function to use
510 * @strdupFunc: the strdup() function to use
511 *
512 * Override the default memory access functions with a new set
513 * This has to be called before any other libxml routines !
514 * The mallocAtomicFunc is specialized for atomic block
515 * allocations (i.e. of areas useful for garbage collected memory allocators
516 *
517 * Should this be blocked if there was already some allocations
518 * done ?
519 *
520 * Returns 0 on success
521 */
522int
523xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
524 xmlMallocFunc mallocAtomicFunc, xmlReallocFunc reallocFunc,
525 xmlStrdupFunc strdupFunc) {
526 if (freeFunc == NULL)
527 return(-1);
528 if (mallocFunc == NULL)
529 return(-1);
530 if (mallocAtomicFunc == NULL)
531 return(-1);
532 if (reallocFunc == NULL)
533 return(-1);
534 if (strdupFunc == NULL)
535 return(-1);
536 xmlFree = freeFunc;
537 xmlMalloc = mallocFunc;
538 xmlMallocAtomic = mallocAtomicFunc;
539 xmlRealloc = reallocFunc;
540 xmlMemStrdup = strdupFunc;
541 return(0);
542}
543
544/**
545 * xmlGcMemGet:
546 * @freeFunc: place to save the free() function in use
547 * @mallocFunc: place to save the malloc() function in use
548 * @mallocAtomicFunc: place to save the atomic malloc() function in use
549 * @reallocFunc: place to save the realloc() function in use
550 * @strdupFunc: place to save the strdup() function in use
551 *
552 * Provides the memory access functions set currently in use
553 * The mallocAtomicFunc is specialized for atomic block
554 * allocations (i.e. of areas useful for garbage collected memory allocators
555 *
556 * Returns 0 on success
557 */
558int
559xmlGcMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc,
560 xmlMallocFunc *mallocAtomicFunc, xmlReallocFunc *reallocFunc,
561 xmlStrdupFunc *strdupFunc) {
562 if (freeFunc != NULL) *freeFunc = xmlFree;
563 if (mallocFunc != NULL) *mallocFunc = xmlMalloc;
564 if (mallocAtomicFunc != NULL) *mallocAtomicFunc = xmlMallocAtomic;
565 if (reallocFunc != NULL) *reallocFunc = xmlRealloc;
566 if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup;
567 return(0);
568}
569
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette