root/ext/gd/libgd/gd_io_dp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gdNewDynamicCtx
  2. gdNewDynamicCtxEx
  3. gdDPExtractData
  4. gdFreeDynamicCtx
  5. dynamicTell
  6. dynamicSeek
  7. newDynamic
  8. dynamicPutbuf
  9. dynamicPutchar
  10. dynamicGetbuf
  11. dynamicGetchar
  12. allocDynamic
  13. appendDynamic
  14. gdReallocDynamic
  15. trimDynamic

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

/* [<][>][^][v][top][bottom][index][help] */