source: trunk/poppler/mypoppler/goo/gmem.cc @ 250

Last change on this file since 250 was 250, checked in by Eugene Romanenko, 13 years ago

PDF plugin: poppler library updated to version 0.8.3

File size: 5.5 KB
Line 
1/*
2 * gmem.c
3 *
4 * Memory routines with out-of-memory checking.
5 *
6 * Copyright 1996-2003 Glyph & Cog, LLC
7 */
8
9#include <config.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <stddef.h>
13#include <string.h>
14#include <limits.h>
15#include "gmem.h"
16
17#ifdef DEBUG_MEM
18
19typedef struct _GMemHdr {
20  unsigned int magic;
21  int size;
22  int index;
23  struct _GMemHdr *next, *prev;
24} GMemHdr;
25
26#define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
27#define gMemTrlSize (sizeof(long))
28
29#define gMemMagic 0xabcd9999
30
31#if gmemTrlSize==8
32#define gMemDeadVal 0xdeadbeefdeadbeefUL
33#else
34#define gMemDeadVal 0xdeadbeefUL
35#endif
36
37/* round data size so trailer will be aligned */
38#define gMemDataSize(size) \
39  ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
40
41static GMemHdr *gMemHead = NULL;
42static GMemHdr *gMemTail = NULL;
43
44static int gMemIndex = 0;
45static int gMemAlloc = 0;
46static int gMemInUse = 0;
47
48#endif /* DEBUG_MEM */
49
50void *gmalloc(size_t size) GMEM_EXCEP {
51#ifdef DEBUG_MEM
52  int size1;
53  char *mem;
54  GMemHdr *hdr;
55  void *data;
56  unsigned long *trl, *p;
57
58  if (size <= 0) {
59    return NULL;
60  }
61  size1 = gMemDataSize(size);
62  if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
63#if USE_EXCEPTIONS
64    throw GMemException();
65#else
66    fprintf(stderr, "Out of memory\n");
67    exit(1);
68#endif
69  }
70  hdr = (GMemHdr *)mem;
71  data = (void *)(mem + gMemHdrSize);
72  trl = (unsigned long *)(mem + gMemHdrSize + size1);
73  hdr->magic = gMemMagic;
74  hdr->size = size;
75  hdr->index = gMemIndex++;
76  if (gMemTail) {
77    gMemTail->next = hdr;
78    hdr->prev = gMemTail;
79    gMemTail = hdr;
80  } else {
81    hdr->prev = NULL;
82    gMemHead = gMemTail = hdr;
83  }
84  hdr->next = NULL;
85  ++gMemAlloc;
86  gMemInUse += size;
87  for (p = (unsigned long *)data; p <= trl; ++p) {
88    *p = gMemDeadVal;
89  }
90  return data;
91#else
92  void *p;
93
94  if (size <= 0) {
95    return NULL;
96  }
97  if (!(p = malloc(size))) {
98#if USE_EXCEPTIONS
99    throw GMemException();
100#else
101    fprintf(stderr, "Out of memory\n");
102    exit(1);
103#endif
104  }
105  return p;
106#endif
107}
108
109void *grealloc(void *p, size_t size) GMEM_EXCEP {
110#ifdef DEBUG_MEM
111  GMemHdr *hdr;
112  void *q;
113  int oldSize;
114
115  if (size <= 0) {
116    if (p) {
117      gfree(p);
118    }
119    return NULL;
120  }
121  if (p) {
122    hdr = (GMemHdr *)((char *)p - gMemHdrSize);
123    oldSize = hdr->size;
124    q = gmalloc(size);
125    memcpy(q, p, size < oldSize ? size : oldSize);
126    gfree(p);
127  } else {
128    q = gmalloc(size);
129  }
130  return q;
131#else
132  void *q;
133
134  if (size <= 0) {
135    if (p) {
136      free(p);
137    }
138    return NULL;
139  }
140  if (p) {
141    q = realloc(p, size);
142  } else {
143    q = malloc(size);
144  }
145  if (!q) {
146#if USE_EXCEPTIONS
147    throw GMemException();
148#else
149    fprintf(stderr, "Out of memory\n");
150    exit(1);
151#endif
152  }
153  return q;
154#endif
155}
156
157void *gmallocn(int nObjs, int objSize) GMEM_EXCEP {
158  int n;
159
160  if (nObjs == 0) {
161    return NULL;
162  }
163  n = nObjs * objSize;
164  if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
165#if USE_EXCEPTIONS
166    throw GMemException();
167#else
168    fprintf(stderr, "Bogus memory allocation size\n");
169    exit(1);
170#endif
171  }
172  return gmalloc(n);
173}
174
175void *gmallocn_checkoverflow(int nObjs, int objSize) GMEM_EXCEP {
176  int n;
177
178  if (nObjs == 0) {
179    return NULL;
180  }
181  n = nObjs * objSize;
182  if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
183#if USE_EXCEPTIONS
184    throw GMemException();
185#else
186    fprintf(stderr, "Bogus memory allocation size\n");
187    return NULL;
188#endif
189  }
190  return gmalloc(n);
191}
192
193void *greallocn(void *p, int nObjs, int objSize) GMEM_EXCEP {
194  int n;
195
196  if (nObjs == 0) {
197    if (p) {
198      gfree(p);
199    }
200    return NULL;
201  }
202  n = nObjs * objSize;
203  if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
204#if USE_EXCEPTIONS
205    throw GMemException();
206#else
207    fprintf(stderr, "Bogus memory allocation size\n");
208    exit(1);
209#endif
210  }
211  return grealloc(p, n);
212}
213
214void gfree(void *p) {
215#ifdef DEBUG_MEM
216  int size;
217  GMemHdr *hdr;
218  unsigned long *trl, *clr;
219
220  if (p) {
221    hdr = (GMemHdr *)((char *)p - gMemHdrSize);
222    if (hdr->magic == gMemMagic &&
223        ((hdr->prev == NULL) == (hdr == gMemHead)) &&
224        ((hdr->next == NULL) == (hdr == gMemTail))) {
225      if (hdr->prev) {
226        hdr->prev->next = hdr->next;
227      } else {
228        gMemHead = hdr->next;
229      }
230      if (hdr->next) {
231        hdr->next->prev = hdr->prev;
232      } else {
233        gMemTail = hdr->prev;
234      }
235      --gMemAlloc;
236      gMemInUse -= hdr->size;
237      size = gMemDataSize(hdr->size);
238      trl = (unsigned long *)((char *)hdr + gMemHdrSize + size);
239      if (*trl != gMemDeadVal) {
240        fprintf(stderr, "Overwrite past end of block %d at address %p\n",
241                hdr->index, p);
242      }
243      for (clr = (unsigned long *)hdr; clr <= trl; ++clr) {
244        *clr = gMemDeadVal;
245      }
246      free(hdr);
247    } else {
248      fprintf(stderr, "Attempted to free bad address %p\n", p);
249    }
250  }
251#else
252  if (p) {
253    free(p);
254  }
255#endif
256}
257
258#ifdef DEBUG_MEM
259void gMemReport(FILE *f) {
260  GMemHdr *p;
261
262  fprintf(f, "%d memory allocations in all\n", gMemIndex);
263  if (gMemAlloc > 0) {
264    fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
265    fprintf(f, " index     size\n");
266    fprintf(f, "-------- --------\n");
267    for (p = gMemHead; p; p = p->next) {
268      fprintf(f, "%8d %8d\n", p->index, p->size);
269    }
270  } else {
271    fprintf(f, "No memory blocks left allocated\n");
272  }
273}
274#endif
275
276char *copyString(char *s) {
277  char *s1;
278
279  s1 = (char *)gmalloc(strlen(s) + 1);
280  strcpy(s1, s);
281  return s1;
282}
283
284char *gstrndup(const char *s, size_t n) {
285  char *s1 = (char*)gmalloc(n + 1); /* cannot return NULL for size > 0 */
286  s1[n] = '\0';
287  memcpy(s1, s, n);
288  return s1;
289}
Note: See TracBrowser for help on using the repository browser.