122
122
/* --------------------------------------------- */
123
123
/* Memory image cgatsFile compatible class */
124
/* Buffer is assumed to be a fixed size, and externally allocated */
125
/* Writes therefore don't expand the buffer. */
124
/* Buffer is assumed to have been allocated by the given allocator, */
125
/* and will be expanded on write. */
127
127
/* Get the size of the file (Only valid for memory file). */
128
128
static size_t cgatsFileMem_get_size(cgatsFile *pp) {
129
cgatsFileMem *p = (cgatsFileMem *)pp;
131
return p->end - p->start;
132
134
/* Set current position to offset. Return 0 on success, nz on failure. */
189
/* Expand the memory buffer file to hold up to pointer ep */
190
/* Don't expand if realloc fails */
191
static void cgatsFileMem_filemem_resize(cgatsFileMem *p, unsigned char *ep) {
193
unsigned char *nstart;
195
/* No need to realloc */
200
co = p->cur - p->start; /* Current offset */
201
ce = p->end - p->start; /* Current end */
202
na = ep - p->start; /* new allocatd size */
204
/* Round new allocation up */
210
if ((nstart = p->al->realloc(p->al, p->start, na)) != NULL) {
212
p->cur = nstart + co;
213
p->end = nstart + ce;
214
p->aend = nstart + na;
187
218
/* write count items of size length. Return number of items successfully written. */
188
219
static size_t cgatsFileMem_write(
197
228
len = ssat_mul(size, count);
198
if (len > (size_t)(p->end - p->cur)) { /* Too much */
229
if (len > (size_t)(p->end - p->cur)) /* Try and expand buffer */
230
cgatsFileMem_filemem_resize(p, p->start + len);
232
if (len > (size_t)(p->end - p->cur)) {
200
234
count = (p->end - p->cur)/size;
219
255
cgatsFileMem *p = (cgatsFileMem *)pp;
221
258
va_start(args, format);
223
#if ((defined(__IBMC__) || defined(__BORLANDC__)) && defined(_M_IX86))
224
rv = vsprintf((char *)p->cur, format, args); /* This could overwrite the buffer !!! */
226
rv = vsnprintf((char *)p->cur, (p->end - p->cur), format, args);
261
len = 100; /* Initial allocation for printf */
262
cgatsFileMem_filemem_resize(p, p->cur + len);
264
/* We have to use the available printf functions to resize the buffer if needed. */
266
/* vsnprintf() either returns -1 if it doesn't fit, or */
267
/* returns the size-1 needed in order to fit. */
268
len = vsnprintf((char *)p->cur, (p->aend - p->cur), format, args);
270
if (len > -1 && ((p->cur + len +1) <= p->aend)) /* Fitted in current allocation */
273
if (len > -1) /* vsnprintf returned needed size-1 */
274
len = len+2; /* (In case vsnprintf returned 1 less than it needs) */
276
len *= 2; /* We just have to guess */
278
/* Attempt to resize */
279
cgatsFileMem_filemem_resize(p, p->cur + len);
281
/* If resize failed */
282
if ((p->aend - p->cur) < len) {
288
/* Figure out where end of printf is */
289
len = strlen((char *)p->cur); /* Length excluding nul */
234
299
/* flush all write data out to secondary storage. Return nz on failure. */
235
300
static int cgatsFileMem_flush(
306
/* Return the memory buffer. Error if not cgatsFileMem */
307
static int cgatsFileMem_get_buf(
312
cgatsFileMem *p = (cgatsFileMem *)pp;
316
*len = p->end - p->start;
241
320
/* return the filename */
242
321
static char *cgatsFileMem_fname(
284
363
p->write = cgatsFileMem_write;
285
364
p->gprintf = cgatsFileMem_printf;
286
365
p->flush = cgatsFileMem_flush;
366
p->get_buf = cgatsFileMem_get_buf;
287
367
p->fname = cgatsFileMem_fname;
288
368
p->del = cgatsFileMem_delete;
290
370
p->start = (unsigned char *)base;
291
371
p->cur = p->start;
292
p->end = p->start + length;
372
p->aend = p->end = p->start + length;
296
374
return (cgatsFile *)p;