summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/lib/formats/ioprocs.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/lib/formats/ioprocs.c')
-rw-r--r--trunk/src/lib/formats/ioprocs.c166
1 files changed, 166 insertions, 0 deletions
diff --git a/trunk/src/lib/formats/ioprocs.c b/trunk/src/lib/formats/ioprocs.c
new file mode 100644
index 00000000000..b4c1213c322
--- /dev/null
+++ b/trunk/src/lib/formats/ioprocs.c
@@ -0,0 +1,166 @@
+#include <stdio.h>
+#include <string.h>
+#include "osdcore.h"
+#include "ioprocs.h"
+
+
+/*********************************************************************
+ ioprocs implementation on stdio
+*********************************************************************/
+
+static void stdio_closeproc(void *file)
+{
+ fclose((FILE*)file);
+}
+
+static int stdio_seekproc(void *file, INT64 offset, int whence)
+{
+ return fseek((FILE*)file, (long) offset, whence);
+}
+
+static size_t stdio_readproc(void *file, void *buffer, size_t length)
+{
+ return fread(buffer, 1, length, (FILE*)file);
+}
+
+static size_t stdio_writeproc(void *file, const void *buffer, size_t length)
+{
+ return fwrite(buffer, 1, length, (FILE*)file);
+}
+
+static UINT64 stdio_filesizeproc(void *file)
+{
+ long l, sz;
+ l = ftell((FILE*)file);
+ if (fseek((FILE*)file, 0, SEEK_END))
+ return (size_t) -1;
+ sz = ftell((FILE*)file);
+ if (fseek((FILE*)file, l, SEEK_SET))
+ return (size_t) -1;
+ return (size_t) sz;
+}
+
+const struct io_procs stdio_ioprocs =
+{
+ stdio_closeproc,
+ stdio_seekproc,
+ stdio_readproc,
+ stdio_writeproc,
+ stdio_filesizeproc
+};
+
+const struct io_procs stdio_ioprocs_noclose =
+{
+ NULL,
+ stdio_seekproc,
+ stdio_readproc,
+ stdio_writeproc,
+ stdio_filesizeproc
+};
+
+
+
+/*********************************************************************
+ calls for accessing generic IO
+*********************************************************************/
+
+static void io_generic_seek(struct io_generic *generic, UINT64 offset)
+{
+ generic->procs->seekproc(generic->file, offset, SEEK_SET);
+}
+
+
+
+void io_generic_close(struct io_generic *generic)
+{
+ if (generic->procs->closeproc)
+ generic->procs->closeproc(generic->file);
+}
+
+
+
+void io_generic_read(struct io_generic *generic, void *buffer, UINT64 offset, size_t length)
+{
+ UINT64 size;
+ size_t bytes_read;
+
+ size = io_generic_size(generic);
+ if (size <= offset)
+ {
+ bytes_read = 0;
+ }
+ else
+ {
+ io_generic_seek(generic, offset);
+ bytes_read = generic->procs->readproc(generic->file, buffer, length);
+ }
+ memset(((UINT8 *) buffer) + bytes_read, generic->filler, length - bytes_read);
+}
+
+
+
+void io_generic_write(struct io_generic *generic, const void *buffer, UINT64 offset, size_t length)
+{
+ UINT64 filler_size = 0;
+ char filler_buffer[1024];
+ size_t bytes_to_write;
+ UINT64 size;
+
+ if (offset > 0x29c50)
+ {
+ offset = offset;
+ }
+
+ size = io_generic_size(generic);
+
+ if (size < offset)
+ {
+ filler_size = offset - size;
+ offset = size;
+ }
+
+ io_generic_seek(generic, offset);
+
+ if (filler_size)
+ {
+ memset(filler_buffer, generic->filler, sizeof(buffer));
+ do
+ {
+ bytes_to_write = (filler_size > sizeof(filler_buffer)) ? sizeof(filler_buffer) : (size_t) filler_size;
+ generic->procs->writeproc(generic->file, filler_buffer, bytes_to_write);
+ filler_size -= bytes_to_write;
+ }
+ while(filler_size > 0);
+ }
+
+ if (length > 0)
+ generic->procs->writeproc(generic->file, buffer, length);
+}
+
+
+
+void io_generic_write_filler(struct io_generic *generic, UINT8 filler, UINT64 offset, size_t length)
+{
+ UINT8 buffer[512];
+ size_t this_length;
+
+ memset(buffer, filler, MIN(length, sizeof(buffer)));
+
+ while(length > 0)
+ {
+ this_length = MIN(length, sizeof(buffer));
+ io_generic_write(generic, buffer, offset, this_length);
+ offset += this_length;
+ length -= this_length;
+ }
+}
+
+
+
+UINT64 io_generic_size(struct io_generic *generic)
+{
+ return generic->procs->filesizeproc(generic->file);
+}
+
+
+