php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
gd_io_dp.c
Go to the documentation of this file.
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 */
29typedef struct dpStruct
30{
31 void *data;
35 int pos;
36 int freeOK;
38
44
45typedef struct dpIOCtx *dpIOCtxPtr;
46
47/* these functions operate on in-memory dynamic pointers */
48static int allocDynamic (dynamicPtr * dp, int initialSize, void *data);
49static int appendDynamic (dynamicPtr * dp, const void *src, int size);
50static int gdReallocDynamic (dynamicPtr * dp, int required);
51static int trimDynamic (dynamicPtr * dp);
52static void gdFreeDynamicCtx (struct gdIOCtx *ctx);
53static dynamicPtr *newDynamic (int initialSize, void *data, int freeOKFlag);
54
55static int dynamicPutbuf (struct gdIOCtx *, const void *, int);
56static void dynamicPutchar (struct gdIOCtx *, int a);
57
58static int dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len);
59static int dynamicGetchar (gdIOCtxPtr ctx);
60
61static int dynamicSeek (struct gdIOCtx *, const int);
62static long dynamicTell (struct gdIOCtx *);
63
64/* return data as a dynamic pointer */
65gdIOCtx * gdNewDynamicCtx (int initialSize, void *data)
66{
67 return gdNewDynamicCtxEx(initialSize, data, 1);
68}
69
70gdIOCtx * gdNewDynamicCtxEx (int initialSize, void *data, int freeOKFlag)
71{
72 dpIOCtx *ctx;
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
95void * gdDPExtractData (struct gdIOCtx *ctx, int *size)
96{
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
124static 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
140static long dynamicTell (struct gdIOCtx *ctx)
141{
142 dpIOCtx *dctx;
143
144 dctx = (dpIOCtx *) ctx;
145
146 return (dctx->dp->pos);
147}
148
149static int dynamicSeek (struct gdIOCtx *ctx, const int pos)
150{
151 int bytesNeeded;
152 dynamicPtr *dp;
153 dpIOCtx *dctx;
154
155 if (pos < 0) {
156 return FALSE;
157 }
158 dctx = (dpIOCtx *) ctx;
159 dp = dctx->dp;
160
161 if (!dp->dataGood) {
162 return FALSE;
163 }
164
165 bytesNeeded = pos;
166 if (bytesNeeded > dp->realSize) {
167 /* 2.0.21 */
168 if (!dp->freeOK) {
169 return FALSE;
170 }
171 gdReallocDynamic (dp, dp->realSize * 2);
172 }
173
174 /* if we get here, we can be sure that we have enough bytes 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 */
187static dynamicPtr * newDynamic (int initialSize, void *data, int freeOKFlag)
188{
189 dynamicPtr *dp;
190 dp = (dynamicPtr *) gdMalloc (sizeof (dynamicPtr));
191
192 allocDynamic (dp, initialSize, data);
193
194 dp->pos = 0;
195 dp->freeOK = freeOKFlag;
196
197 return dp;
198}
199
200static int
201dynamicPutbuf (struct gdIOCtx *ctx, const void *buf, int size)
202{
203 dpIOCtx *dctx;
204 dctx = (dpIOCtx *) ctx;
205
206 appendDynamic (dctx->dp, buf, size);
207
208 if (dctx->dp->dataGood)
209 {
210 return size;
211 }
212 else
213 {
214 return -1;
215 };
216
217}
218
219static void 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
230static int dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len)
231{
232 int rlen, remain;
233 dpIOCtxPtr dctx;
234 dynamicPtr *dp;
235
236 dctx = (dpIOCtxPtr) ctx;
237 dp = dctx->dp;
238
239 remain = dp->logicalSize - dp->pos;
240 if (remain >= len) {
241 rlen = len;
242 } else {
243 if (remain <= 0) {
244 return EOF;
245 }
246 rlen = remain;
247 }
248
249 memcpy(buf, (void *) ((char *) dp->data + dp->pos), rlen);
250 dp->pos += rlen;
251
252 return rlen;
253}
254
255static int dynamicGetchar (gdIOCtxPtr ctx)
256{
257 unsigned char b;
258 int rv;
259
260 rv = dynamicGetbuf (ctx, &b, 1);
261 if (rv != 1) {
262 return EOF;
263 } else {
264 return b; /* (b & 0xff); */
265 }
266}
267
268/* *********************************************************************
269
270 * InitDynamic - Return a dynamically resizable void*
271 *
272 * *********************************************************************
273 */
274static int
275allocDynamic (dynamicPtr * dp, int initialSize, void *data)
276{
277
278 if (data == NULL) {
279 dp->logicalSize = 0;
280 dp->dataGood = FALSE;
281 dp->data = gdMalloc(initialSize);
282 } else {
283 dp->logicalSize = initialSize;
284 dp->dataGood = TRUE;
285 dp->data = data;
286 }
287
288 dp->realSize = initialSize;
289 dp->dataGood = TRUE;
290 dp->pos = 0;
291
292 return TRUE;
293}
294
295/* append bytes to the end of a dynamic pointer */
296static int appendDynamic (dynamicPtr * dp, const void *src, int size)
297{
298 int bytesNeeded;
299 char *tmp;
300
301 if (!dp->dataGood) {
302 return FALSE;
303 }
304
305 /* bytesNeeded = dp->logicalSize + size; */
306 bytesNeeded = dp->pos + size;
307
308 if (bytesNeeded > dp->realSize) {
309 /* 2.0.21 */
310 if (!dp->freeOK) {
311 return FALSE;
312 }
313 gdReallocDynamic(dp, bytesNeeded * 2);
314 }
315
316 /* if we get here, we can be sure that we have enough bytes to copy safely */
317 /*printf("Mem OK Size: %d, Pos: %d\n", dp->realSize, dp->pos); */
318
319 tmp = (char *) dp->data;
320 memcpy((void *) (tmp + (dp->pos)), src, size);
321 dp->pos += size;
322
323 if (dp->pos > dp->logicalSize) {
324 dp->logicalSize = dp->pos;
325 }
326
327 return TRUE;
328}
329
330/* grow (or shrink) dynamic pointer */
331static int gdReallocDynamic (dynamicPtr * dp, int required)
332{
333 void *newPtr;
334
335 /* First try gdRealloc(). If that doesn't work, make a new memory block and copy. */
336 if ((newPtr = gdRealloc(dp->data, required))) {
337 dp->realSize = required;
338 dp->data = newPtr;
339 return TRUE;
340 }
341
342 /* create a new pointer */
343 newPtr = gdMalloc(required);
344
345 /* copy the old data into it */
346 memcpy(newPtr, dp->data, dp->logicalSize);
347 gdFree(dp->data);
348 dp->data = newPtr;
349
350 dp->realSize = required;
351
352 return TRUE;
353}
354
355/* trim pointer so that its real and logical sizes match */
356static int trimDynamic (dynamicPtr * dp)
357{
358 /* 2.0.21: we don't reallocate memory we don't own */
359 if (!dp->freeOK) {
360 return FALSE;
361 }
362 return gdReallocDynamic(dp, dp->logicalSize);
363}
size_t len
Definition apprentice.c:174
new_type size
Definition ffi.c:4365
memcpy(ptr1, ptr2, size)
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
#define TRUE
Definition gd_gd.c:7
#define FALSE
Definition gd_gd.c:8
struct gdIOCtx * gdIOCtxPtr
Definition gd_io.h:25
void * gdDPExtractData(struct gdIOCtx *ctx, int *size)
Definition gd_io_dp.c:95
struct dpIOCtx * dpIOCtxPtr
Definition gd_io_dp.c:45
struct dpStruct dynamicPtr
gdIOCtx * gdNewDynamicCtx(int initialSize, void *data)
Definition gd_io_dp.c:65
gdIOCtx * gdNewDynamicCtxEx(int initialSize, void *data, int freeOKFlag)
Definition gd_io_dp.c:70
#define NULL
Definition gdcache.h:45
#define gdRealloc(ptr, size)
Definition gdhelpers.h:17
#define gdFree(ptr)
Definition gdhelpers.h:19
#define gdMalloc(size)
Definition gdhelpers.h:16
unsigned const char * pos
Definition php_ffi.h:52
zend_constant * data
zval rv
Definition session.c:1024
gdIOCtx ctx
Definition gd_io_dp.c:41
dynamicPtr * dp
Definition gd_io_dp.c:42
void * data
Definition gd_io_dp.c:31
int realSize
Definition gd_io_dp.c:33
int freeOK
Definition gd_io_dp.c:36
int pos
Definition gd_io_dp.c:35
int logicalSize
Definition gd_io_dp.c:32
int dataGood
Definition gd_io_dp.c:34
int(* seek)(struct gdIOCtx *, const int)
Definition gd_io.h:17
void(* putC)(struct gdIOCtx *, int)
Definition gd_io.h:14
long(* tell)(struct gdIOCtx *)
Definition gd_io.h:18
int(* getC)(struct gdIOCtx *)
Definition gd_io.h:11
int(* putBuf)(struct gdIOCtx *, const void *, int)
Definition gd_io.h:15
void(* gd_free)(struct gdIOCtx *)
Definition gd_io.h:20
int(* getBuf)(struct gdIOCtx *, void *, int)
Definition gd_io.h:12
$obj a
Definition test.php:84