~ubuntu-branches/ubuntu/maverick/ntop/maverick

« back to all changes in this revision

Viewing changes to gdchart0.94c/gd-1.8.3/gd_io_dp.c

  • Committer: Bazaar Package Importer
  • Author(s): Dennis Schoen
  • Date: 2002-04-12 11:38:47 UTC
  • Revision ID: james.westby@ubuntu.com-20020412113847-4k4yydw0pzybc6g8
Tags: upstream-2.0.0
ImportĀ upstreamĀ versionĀ 2.0.0

Show diffs side-by-side

added added

removed removed

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