1
/* FakeNES - A free, portable, Open Source NES emulator.
3
Copyright (c) 2001-2006, FakeNES Team.
4
This is free software. See 'LICENSE' for details.
5
You must read and accept the license prior to use.
7
bufferfile.cpp: "Buffer file" I/O routines by randilyn. */
11
#include "../include/common.h"
12
#include "bufferfile.h"
16
std::vector<uint8> data;
20
#define CHUNK_SIZE 4096
22
static const PACKFILE_VTABLE *get_packfile_vtable (void);
24
PACKFILE *BufferFile_open (void)
26
BufferFile *bufferFile = new BufferFile;
29
WARN("Out of memory");
38
PACKFILE *pf = pack_fopen_vtable (get_packfile_vtable (), bufferFile);
41
WARN("Call to pack_fopen_vtable() failed");
49
void BufferFile_get_buffer (PACKFILE *pf, uint8 **buffer, long *size)
55
BufferFile *bufferFile = (BufferFile *)pf->userdata;
57
*buffer = &bufferFile->data[0];
58
*size = bufferFile->size;
61
// Internal functions follow.
63
static int BufferFile_fclose (void *userdata)
67
BufferFile *bufferFile = (BufferFile *)userdata;
70
bufferFile->data.clear ();
77
static int BufferFile_getc (void *userdata)
81
BufferFile *bufferFile = (BufferFile *)userdata;
83
if (bufferFile->pos >= bufferFile->size)
89
return (bufferFile->data[bufferFile->pos++]);
92
static int BufferFile_ungetc (int c, void *userdata)
100
static long BufferFile_fread (void *p, long n, void *userdata)
105
BufferFile *bufferFile = (BufferFile *)userdata;
107
if (bufferFile->pos >= bufferFile->size)
113
long size = (bufferFile->size - bufferFile->pos);
117
memcpy (p, (&bufferFile->data[0] + bufferFile->pos), n);
118
bufferFile->pos += n;
123
static int BufferFile_putc (int c, void *userdata)
127
BufferFile *bufferFile = (BufferFile *)userdata;
129
if (bufferFile->pos >= bufferFile->size)
133
if (bufferFile->pos >= (bufferFile->size + 1))
140
if (bufferFile->size > bufferFile->max)
142
bufferFile->max = (bufferFile->size + CHUNK_SIZE);
143
bufferFile->data.reserve (bufferFile->max);
146
bufferFile->data.resize (bufferFile->size);
149
bufferFile->data[bufferFile->pos++] = c;
154
static long BufferFile_fwrite (const void *p, long n, void *userdata)
159
BufferFile *bufferFile = (BufferFile *)userdata;
161
if (bufferFile->pos >= bufferFile->size)
163
if (bufferFile->pos >= (bufferFile->size + 1))
166
bufferFile->size += n;
167
if (bufferFile->size > bufferFile->max)
169
bufferFile->max = (bufferFile->size + CHUNK_SIZE);
170
bufferFile->data.reserve (bufferFile->max);
173
bufferFile->data.resize (bufferFile->size);
176
memcpy ((&bufferFile->data[0] + bufferFile->pos), p, n);
177
bufferFile->pos += n;
182
static int BufferFile_fseek (void *userdata, int offset)
186
BufferFile *bufferFile = (BufferFile *)userdata;
188
if ((offset < 0) || (offset > bufferFile->size))
194
bufferFile->pos = offset;
199
static int BufferFile_feof (void *userdata)
203
BufferFile *bufferFile = (BufferFile *)userdata;
205
if (bufferFile->pos >= bufferFile->size)
211
static int BufferFile_ferror (void *userdata)
219
static PACKFILE_VTABLE packfile_vtable;
221
static const PACKFILE_VTABLE *get_packfile_vtable (void)
223
PACKFILE_VTABLE *vtable = &packfile_vtable;
225
memset (vtable, 0, sizeof(PACKFILE_VTABLE));
227
vtable->pf_fclose = BufferFile_fclose;
228
vtable->pf_getc = BufferFile_getc;
229
vtable->pf_ungetc = BufferFile_ungetc;
230
vtable->pf_fread = BufferFile_fread;
231
vtable->pf_putc = BufferFile_putc;
232
vtable->pf_fwrite = BufferFile_fwrite;
233
vtable->pf_fseek = BufferFile_fseek;
234
vtable->pf_feof = BufferFile_feof;
235
vtable->pf_ferror = BufferFile_ferror;