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