]> git.draconx.ca Git - liblbx.git/blobdiff - src/fops.c
liblbx: Parameterise I/O functions to allow custom streams.
[liblbx.git] / src / fops.c
diff --git a/src/fops.c b/src/fops.c
new file mode 100644 (file)
index 0000000..2ae6c61
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ *  2ooM: The Master of Orion II Reverse Engineering Project
+ *  Default file operations structures for liblbx.
+ *  Copyright (C) 2010 Nick Bowler
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdio.h>
+
+#include "misc.h"
+#include "lbx.h"
+
+/* Default I/O operations for ordinary files. */
+static size_t file_read(void *buf, size_t size, void *handle)
+{
+       return fread(buf, 1, size, (FILE *)handle);
+}
+
+static int file_seek(void *handle, long offset, int whence)
+{
+       return fseek((FILE *)handle, offset, whence);
+}
+
+static long file_tell(void *handle)
+{
+       return ftell((FILE *)handle);
+}
+
+static int file_eof(void *handle)
+{
+       return feof((FILE *)handle);
+}
+
+const struct lbx_file_ops lbx_default_fops = {
+       .read = file_read,
+       .seek = file_seek,
+       .tell = file_tell,
+       .eof  = file_eof,
+};
+
+/* Read function for pipes that tracks the number of bytes read. */
+static size_t pipe_read(void *buf, size_t size, void *handle)
+{
+       struct lbx_pipe_state *state = handle;
+       size_t rc;
+
+       rc = fread(buf, 1, size, state->f);
+       state->offset += rc;
+       return rc;
+}
+
+/* Seek function for pipes that reads data into the void. */
+static int pipe_seek(void *handle, long offset, int whence)
+{
+       struct lbx_pipe_state *state = handle;
+       long distance;
+
+       distance = offset - state->offset;
+       if (distance < 0)
+               return -1;
+
+       while (distance > 0) {
+               static unsigned char oblivion[1024];
+               size_t rc, amount = MIN(sizeof oblivion, distance);
+
+               rc = pipe_read(oblivion, amount, handle);
+               distance -= rc;
+
+               if (rc < amount)
+                       return -1;
+       }
+
+       return 0;
+}
+
+static long pipe_tell(void *handle)
+{
+       struct lbx_pipe_state *state = handle;
+
+       return state->offset;
+}
+
+static int pipe_eof(void *handle)
+{
+       struct lbx_pipe_state *state = handle;
+
+       return feof(state->f);
+}
+
+const struct lbx_file_ops lbx_pipe_fops = {
+       .read = pipe_read,
+       .seek = pipe_seek,
+       .tell = pipe_tell,
+       .eof  = pipe_eof,
+};