]> git.draconx.ca Git - liblbx.git/blob - src/fops.c
Trivial manual fixes.
[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 © 2010, 2014 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 <config.h>
20 #include <stdio.h>
21 #include <errno.h>
22 #include <assert.h>
23
24 #include "misc.h"
25 #include "error.h"
26 #include "lbx.h"
27
28 /* Default I/O operations for ordinary files. */
29 static size_t file_read(void *buf, size_t size, void *handle)
30 {
31         size_t rc = fread(buf, 1, size, (FILE *)handle);
32
33         if (rc < size && ferror((FILE *)handle))
34                 lbx_error_raise(-errno);
35         return rc;
36 }
37
38 static int file_seek(void *handle, long offset, int whence)
39 {
40         if (fseek((FILE *)handle, offset, whence) == -1) {
41                 lbx_error_raise(-errno);
42                 return -1;
43         }
44
45         return 0;
46 }
47
48 static int file_eof(void *handle)
49 {
50         return feof((FILE *)handle);
51 }
52
53 const struct lbx_file_ops lbx_default_fops = {
54         .read = file_read,
55         .seek = file_seek,
56         .eof  = file_eof,
57 };
58
59 /* Read function for pipes that tracks the number of bytes read. */
60 static size_t pipe_read(void *buf, size_t size, void *handle)
61 {
62         struct lbx_pipe_state *state = handle;
63         size_t rc;
64
65         rc = file_read(buf, size, state->f);
66         state->offset += rc;
67         return rc;
68 }
69
70 /* Seek function for pipes that reads data into the void. */
71 static int pipe_seek(void *handle, long offset, int whence)
72 {
73         struct lbx_pipe_state *state = handle;
74         long distance;
75
76         switch (whence) {
77         case SEEK_SET:
78                 distance = offset - state->offset;
79                 break;
80         case SEEK_CUR:
81                 distance = offset;
82                 break;
83         case SEEK_END:
84                 distance = -1;
85                 break;
86         default:
87                 assert(0);
88         }
89
90         if (distance < 0)
91                 return -1;
92
93         while (distance > 0) {
94                 static unsigned char oblivion[1024];
95                 size_t rc, amount = MIN(sizeof oblivion, distance);
96
97                 rc = pipe_read(oblivion, amount, handle);
98                 distance -= rc;
99
100                 if (rc < amount)
101                         return -1;
102         }
103
104         clearerr(state->f);
105         return 0;
106 }
107
108 static int pipe_eof(void *handle)
109 {
110         struct lbx_pipe_state *state = handle;
111
112         return feof(state->f);
113 }
114
115 const struct lbx_file_ops lbx_pipe_fops = {
116         .read = pipe_read,
117         .seek = pipe_seek,
118         .eof  = pipe_eof,
119 };
120
121 static size_t lbx_read(void *buf, size_t size, void *handle)
122 {
123         return lbx_file_read(handle, buf, size);
124 }
125
126 static int lbx_seek(void *handle, long offset, int whence)
127 {
128         return lbx_file_seek(handle, offset, whence);
129 }
130
131 static int lbx_eof(void *handle)
132 {
133         return lbx_file_eof(handle);
134 }
135
136 const struct lbx_file_ops lbx_arch_fops = {
137         .read = lbx_read,
138         .seek = lbx_seek,
139         .eof  = lbx_eof,
140 };