]> git.draconx.ca Git - liblbx.git/blob - src/fops.c
liblbx: Parameterise I/O functions to allow custom streams.
[liblbx.git] / src / fops.c
1 /*
2  *  2ooM: The Master of Orion II Reverse Engineering Project
3  *  Default file operations structures for liblbx.
4  *  Copyright (C) 2010 Nick Bowler
5  *
6  *  This program is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 #include <stdio.h>
20
21 #include "misc.h"
22 #include "lbx.h"
23
24 /* Default I/O operations for ordinary files. */
25 static size_t file_read(void *buf, size_t size, void *handle)
26 {
27         return fread(buf, 1, size, (FILE *)handle);
28 }
29
30 static int file_seek(void *handle, long offset, int whence)
31 {
32         return fseek((FILE *)handle, offset, whence);
33 }
34
35 static long file_tell(void *handle)
36 {
37         return ftell((FILE *)handle);
38 }
39
40 static int file_eof(void *handle)
41 {
42         return feof((FILE *)handle);
43 }
44
45 const struct lbx_file_ops lbx_default_fops = {
46         .read = file_read,
47         .seek = file_seek,
48         .tell = file_tell,
49         .eof  = file_eof,
50 };
51
52 /* Read function for pipes that tracks the number of bytes read. */
53 static size_t pipe_read(void *buf, size_t size, void *handle)
54 {
55         struct lbx_pipe_state *state = handle;
56         size_t rc;
57
58         rc = fread(buf, 1, size, state->f);
59         state->offset += rc;
60         return rc;
61 }
62
63 /* Seek function for pipes that reads data into the void. */
64 static int pipe_seek(void *handle, long offset, int whence)
65 {
66         struct lbx_pipe_state *state = handle;
67         long distance;
68
69         distance = offset - state->offset;
70         if (distance < 0)
71                 return -1;
72
73         while (distance > 0) {
74                 static unsigned char oblivion[1024];
75                 size_t rc, amount = MIN(sizeof oblivion, distance);
76
77                 rc = pipe_read(oblivion, amount, handle);
78                 distance -= rc;
79
80                 if (rc < amount)
81                         return -1;
82         }
83
84         return 0;
85 }
86
87 static long pipe_tell(void *handle)
88 {
89         struct lbx_pipe_state *state = handle;
90
91         return state->offset;
92 }
93
94 static int pipe_eof(void *handle)
95 {
96         struct lbx_pipe_state *state = handle;
97
98         return feof(state->f);
99 }
100
101 const struct lbx_file_ops lbx_pipe_fops = {
102         .read = pipe_read,
103         .seek = pipe_seek,
104         .tell = pipe_tell,
105         .eof  = pipe_eof,
106 };