~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to gd/gd_io_dp.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
   * io_dp.c
 
4
   *
 
5
   * Implements the dynamic pointer interface.
 
6
   *
 
7
   * Based on GD.pm code by Lincoln Stein for interfacing to libgd.
 
8
   * Added support for reading as well as support for 'tell' and 'seek'.
 
9
   *
 
10
   * As will all I/O modules, most functions are for local use only (called
 
11
   * via function pointers in the I/O context).
 
12
   *
 
13
   * gdDPExtractData is the exception to this: it will return the pointer to
 
14
   * the internal data, and reset the internal storage.
 
15
   *
 
16
   * Written/Modified 1999, Philip Warner.
 
17
   *
 
18
 */
 
19
 
 
20
#include <math.h>
 
21
#include <string.h>
 
22
#include <stdlib.h>
 
23
#include "gd.h"
 
24
#include "gdhelpers.h"
 
25
 
 
26
#define TRUE 1
 
27
#define FALSE 0
 
28
 
 
29
/* this is used for creating images in main memory */
 
30
typedef struct dpStruct
 
31
  {
 
32
    void *data;
 
33
    int logicalSize;
 
34
    int realSize;
 
35
    int dataGood;
 
36
    int pos;
 
37
  }
 
38
dynamicPtr;
 
39
 
 
40
typedef struct dpIOCtx
 
41
  {
 
42
    gdIOCtx ctx;
 
43
    dynamicPtr *dp;
 
44
  }
 
45
dpIOCtx;
 
46
 
 
47
typedef struct dpIOCtx *dpIOCtxPtr;
 
48
 
 
49
 
 
50
/* these functions operate on in-memory dynamic pointers */
 
51
static int allocDynamic (dynamicPtr * dp, int initialSize, void *data);
 
52
static int appendDynamic (dynamicPtr * dp, const void *src, int size);
 
53
static int gdReallocDynamic (dynamicPtr * dp, int required);
 
54
static int trimDynamic (dynamicPtr * dp);
 
55
static void gdFreeDynamicCtx (struct gdIOCtx *ctx);
 
56
static dynamicPtr *newDynamic (int initialSize, void *data);
 
57
 
 
58
static int dynamicPutbuf (struct gdIOCtx *, const void *, int);
 
59
static void dynamicPutchar (struct gdIOCtx *, int a);
 
60
 
 
61
static int dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len);
 
62
static int dynamicGetchar (gdIOCtxPtr ctx);
 
63
 
 
64
static int dynamicSeek (struct gdIOCtx *, const int);
 
65
static long dynamicTell (struct gdIOCtx *);
 
66
 
 
67
/* return data as a dynamic pointer */
 
68
gdIOCtx *
 
69
gdNewDynamicCtx (int initialSize, void *data)
 
70
{
 
71
  dpIOCtx *ctx;
 
72
  dynamicPtr *dp;
 
73
 
 
74
  ctx = (dpIOCtx *) gdMalloc (sizeof (dpIOCtx));
 
75
  if (ctx == NULL)
 
76
    {
 
77
      return NULL;
 
78
    }
 
79
 
 
80
  dp = newDynamic (initialSize, data);
 
81
  if (!dp)
 
82
    {
 
83
      gdFree (ctx);
 
84
      return NULL;
 
85
    };
 
86
 
 
87
  ctx->dp = dp;
 
88
 
 
89
  ctx->ctx.getC = dynamicGetchar;
 
90
  ctx->ctx.putC = dynamicPutchar;
 
91
 
 
92
  ctx->ctx.getBuf = dynamicGetbuf;
 
93
  ctx->ctx.putBuf = dynamicPutbuf;
 
94
 
 
95
  ctx->ctx.seek = dynamicSeek;
 
96
  ctx->ctx.tell = dynamicTell;
 
97
 
 
98
  ctx->ctx.free = gdFreeDynamicCtx;
 
99
 
 
100
  return (gdIOCtx *) ctx;
 
101
}
 
102
 
 
103
void *
 
104
gdDPExtractData (struct gdIOCtx *ctx, int *size)
 
105
{
 
106
  dynamicPtr *dp;
 
107
  dpIOCtx *dctx;
 
108
  void *data;
 
109
 
 
110
  dctx = (dpIOCtx *) ctx;
 
111
  dp = dctx->dp;
 
112
 
 
113
  /* clean up the data block and return it */
 
114
  if (dp->dataGood)
 
115
    {
 
116
      trimDynamic (dp);
 
117
      *size = dp->logicalSize;
 
118
      data = dp->data;
 
119
    }
 
120
  else
 
121
    {
 
122
      *size = 0;
 
123
      data = NULL;
 
124
      if (dp->data != NULL)
 
125
        {
 
126
          gdFree (dp->data);
 
127
        }
 
128
    }
 
129
 
 
130
  dp->data = NULL;
 
131
  dp->realSize = 0;
 
132
  dp->logicalSize = 0;
 
133
 
 
134
  return data;
 
135
}
 
136
 
 
137
static
 
138
void
 
139
gdFreeDynamicCtx (struct gdIOCtx *ctx)
 
140
{
 
141
  dynamicPtr *dp;
 
142
  dpIOCtx *dctx;
 
143
 
 
144
  dctx = (dpIOCtx *) ctx;
 
145
  dp = dctx->dp;
 
146
 
 
147
  gdFree (ctx);
 
148
 
 
149
  /* clean up the data block and return it */
 
150
  if (dp->data != NULL)
 
151
    {
 
152
      gdFree (dp->data);
 
153
      dp->data = NULL;
 
154
    }
 
155
 
 
156
  dp->realSize = 0;
 
157
  dp->logicalSize = 0;
 
158
 
 
159
  gdFree (dp);
 
160
 
 
161
}
 
162
 
 
163
static long
 
164
dynamicTell (struct gdIOCtx *ctx)
 
165
{
 
166
  dpIOCtx *dctx;
 
167
 
 
168
  dctx = (dpIOCtx *) ctx;
 
169
  return (dctx->dp->pos);
 
170
}
 
171
 
 
172
static int
 
173
dynamicSeek (struct gdIOCtx *ctx, const int pos)
 
174
{
 
175
  int bytesNeeded;
 
176
  dynamicPtr *dp;
 
177
  dpIOCtx *dctx;
 
178
 
 
179
  dctx = (dpIOCtx *) ctx;
 
180
  dp = dctx->dp;
 
181
 
 
182
  if (!dp->dataGood)
 
183
    return FALSE;
 
184
 
 
185
  bytesNeeded = pos;
 
186
  if (bytesNeeded > dp->realSize)
 
187
    {
 
188
      if (!gdReallocDynamic (dp, dp->realSize * 2))
 
189
        {
 
190
          dp->dataGood = FALSE;
 
191
          return FALSE;
 
192
        }
 
193
    }
 
194
 
 
195
  /* if we get here, we can be sure that we have enough bytes
 
196
     to copy safely */
 
197
 
 
198
  /* Extend the logical size if we seek beyond EOF. */
 
199
  if (pos > dp->logicalSize)
 
200
    {
 
201
      dp->logicalSize = pos;
 
202
    };
 
203
 
 
204
  dp->pos = pos;
 
205
 
 
206
  return TRUE;
 
207
}
 
208
 
 
209
/* return data as a dynamic pointer */
 
210
static dynamicPtr *
 
211
newDynamic (int initialSize, void *data)
 
212
{
 
213
  dynamicPtr *dp;
 
214
  dp = (dynamicPtr *) gdMalloc (sizeof (dynamicPtr));
 
215
  if (dp == NULL)
 
216
    {
 
217
      return NULL;
 
218
    }
 
219
 
 
220
  if (!allocDynamic (dp, initialSize, data))
 
221
    return NULL;
 
222
 
 
223
  dp->pos = 0;
 
224
 
 
225
  return dp;
 
226
}
 
227
 
 
228
static int
 
229
dynamicPutbuf (struct gdIOCtx *ctx, const void *buf, int size)
 
230
{
 
231
  dpIOCtx *dctx;
 
232
  dctx = (dpIOCtx *) ctx;
 
233
 
 
234
  appendDynamic (dctx->dp, buf, size);
 
235
 
 
236
  if (dctx->dp->dataGood)
 
237
    {
 
238
      return size;
 
239
    }
 
240
  else
 
241
    {
 
242
      return -1;
 
243
    };
 
244
 
 
245
}
 
246
 
 
247
static void
 
248
dynamicPutchar (struct gdIOCtx *ctx, int a)
 
249
{
 
250
  unsigned char b;
 
251
  dpIOCtxPtr dctx;
 
252
 
 
253
  b = a;
 
254
  dctx = (dpIOCtxPtr) ctx;
 
255
 
 
256
  appendDynamic (dctx->dp, &b, 1);
 
257
}
 
258
 
 
259
static int
 
260
dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len)
 
261
{
 
262
  int rlen, remain;
 
263
  dpIOCtxPtr dctx;
 
264
  dynamicPtr *dp;
 
265
 
 
266
  dctx = (dpIOCtxPtr) ctx;
 
267
  dp = dctx->dp;
 
268
 
 
269
  remain = dp->logicalSize - dp->pos;
 
270
  if (remain >= len)
 
271
    {
 
272
      rlen = len;
 
273
    }
 
274
  else
 
275
    {
 
276
      if (remain == 0)
 
277
        {
 
278
          return EOF;
 
279
        }
 
280
      rlen = remain;
 
281
    }
 
282
 
 
283
  memcpy (buf, (void *) ((char *) dp->data + dp->pos), rlen);
 
284
  dp->pos += rlen;
 
285
 
 
286
  return rlen;
 
287
}
 
288
 
 
289
static int
 
290
dynamicGetchar (gdIOCtxPtr ctx)
 
291
{
 
292
  unsigned char b;
 
293
  int rv;
 
294
 
 
295
  rv = dynamicGetbuf (ctx, &b, 1);
 
296
 
 
297
  if (rv != 1)
 
298
    {
 
299
      return EOF;
 
300
    }
 
301
  else
 
302
    {
 
303
      return b;                 /* (b & 0xff); */
 
304
    }
 
305
}
 
306
 
 
307
/* *********************************************************************
 
308
 
 
309
 * InitDynamic - Return a dynamically resizable void*
 
310
 *
 
311
 * *********************************************************************
 
312
 */
 
313
static int
 
314
allocDynamic (dynamicPtr * dp, int initialSize, void *data)
 
315
{
 
316
 
 
317
  if (data == NULL)
 
318
    {
 
319
      dp->logicalSize = 0;
 
320
      dp->dataGood = FALSE;
 
321
      dp->data = gdMalloc (initialSize);
 
322
    }
 
323
  else
 
324
    {
 
325
      dp->logicalSize = initialSize;
 
326
      dp->dataGood = TRUE;
 
327
      dp->data = data;
 
328
    }
 
329
 
 
330
  if (dp->data != NULL)
 
331
    {
 
332
      dp->realSize = initialSize;
 
333
      dp->dataGood = TRUE;
 
334
      dp->pos = 0;
 
335
      return TRUE;
 
336
    }
 
337
  else
 
338
    {
 
339
      dp->realSize = 0;
 
340
      return FALSE;
 
341
    }
 
342
}
 
343
 
 
344
/* append bytes to the end of a dynamic pointer */
 
345
static int
 
346
appendDynamic (dynamicPtr * dp, const void *src, int size)
 
347
{
 
348
  int bytesNeeded;
 
349
  char *tmp;
 
350
 
 
351
  if (!dp->dataGood)
 
352
    return FALSE;
 
353
 
 
354
/*  bytesNeeded = dp->logicalSize + size; */
 
355
  bytesNeeded = dp->pos + size;
 
356
 
 
357
  if (bytesNeeded > dp->realSize)
 
358
    {
 
359
      if (!gdReallocDynamic (dp, bytesNeeded * 2))
 
360
        {
 
361
          dp->dataGood = FALSE;
 
362
          return FALSE;
 
363
        }
 
364
    }
 
365
 
 
366
  /* if we get here, we can be sure that we have enough bytes
 
367
     to copy safely */
 
368
  /*printf("Mem OK Size: %d, Pos: %d\n", dp->realSize, dp->pos); */
 
369
 
 
370
  tmp = (char *) dp->data;
 
371
  memcpy ((void *) (tmp + (dp->pos)), src, size);
 
372
  dp->pos += size;
 
373
 
 
374
  if (dp->pos > dp->logicalSize)
 
375
    {
 
376
      dp->logicalSize = dp->pos;
 
377
    };
 
378
 
 
379
  return TRUE;
 
380
}
 
381
 
 
382
/* grow (or shrink) dynamic pointer */
 
383
static int
 
384
gdReallocDynamic (dynamicPtr * dp, int required)
 
385
{
 
386
  void *newPtr;
 
387
 
 
388
  /* First try gdRealloc().  If that doesn't work, make a new
 
389
     memory block and copy. */
 
390
  if ((newPtr = gdRealloc (dp->data, required)))
 
391
    {
 
392
      dp->realSize = required;
 
393
      dp->data = newPtr;
 
394
      return TRUE;
 
395
    }
 
396
 
 
397
  /* create a new pointer */
 
398
  newPtr = gdMalloc (required);
 
399
  if (!newPtr)
 
400
    {
 
401
      dp->dataGood = FALSE;
 
402
      return FALSE;
 
403
    }
 
404
 
 
405
  /* copy the old data into it */
 
406
  memcpy (newPtr, dp->data, dp->logicalSize);
 
407
  gdFree (dp->data);
 
408
  dp->data = newPtr;
 
409
 
 
410
  dp->realSize = required;
 
411
  return TRUE;
 
412
}
 
413
 
 
414
/* trim pointer so that its real and logical sizes match */
 
415
static int
 
416
trimDynamic (dynamicPtr * dp)
 
417
{
 
418
  return gdReallocDynamic (dp, dp->logicalSize);
 
419
}