1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdint.h>
4 #include <stdarg.h>
5 #include <stdio.h>
6 #include <errno.h>
7
8 #include "shadowdive/internal/reader.h"
9
10 struct sd_reader_t {
11 FILE *handle;
12 long filesize;
13 int sd_errno;
14 };
15
sd_reader_open(const char * file)16 sd_reader* sd_reader_open(const char *file) {
17 sd_reader *reader = malloc(sizeof(const sd_reader));
18
19 reader->sd_errno = 0;
20
21 // Attempt to open file (note: Binary mode!)
22 reader->handle = fopen(file, "rb");
23 if(!reader->handle) {
24 free(reader);
25 return 0;
26 }
27
28 // Find file size
29 if (fseek(reader->handle, 0, SEEK_END) == -1) {
30 goto error;
31 }
32 reader->filesize = ftell(reader->handle);
33 if (reader->filesize == -1) {
34 goto error;
35 }
36 if (fseek(reader->handle, 0, SEEK_SET) == -1) {
37 goto error;
38 }
39
40 // All done.
41 return reader;
42
43 error:
44 fclose(reader->handle);
45 free(reader);
46 return 0;
47 }
48
sd_reader_filesize(const sd_reader * reader)49 long sd_reader_filesize(const sd_reader *reader) {
50 return reader->filesize;
51 }
52
sd_reader_errno(const sd_reader * reader)53 int sd_reader_errno(const sd_reader *reader) {
54 return reader->sd_errno;
55 }
56
sd_reader_close(sd_reader * reader)57 void sd_reader_close(sd_reader *reader) {
58 fclose(reader->handle);
59 free(reader);
60 }
61
sd_reader_set(sd_reader * reader,long offset)62 int sd_reader_set(sd_reader *reader, long offset) {
63 if (fseek(reader->handle, offset, SEEK_SET) != 0) {
64 reader->sd_errno = errno;
65 return 0;
66 }
67 return 1;
68 }
69
sd_reader_ok(const sd_reader * reader)70 int sd_reader_ok(const sd_reader *reader) {
71 if(feof(reader->handle)) {
72 return 0;
73 }
74 return 1;
75 }
76
sd_reader_pos(sd_reader * reader)77 long sd_reader_pos(sd_reader *reader) {
78 long res = ftell(reader->handle);
79 if (res == -1) {
80 reader->sd_errno = errno;
81 }
82 return res;
83 }
84
sd_read_buf(sd_reader * reader,char * buf,int len)85 int sd_read_buf(sd_reader *reader, char *buf, int len) {
86 if(fread(buf, 1, len, reader->handle) != len) {
87 reader->sd_errno = ferror(reader->handle);
88 return 0;
89 }
90 return 1;
91 }
92
sd_peek_buf(sd_reader * reader,char * buf,int len)93 int sd_peek_buf(sd_reader *reader, char *buf, int len) {
94 if(sd_read_buf(reader, buf, len)) {
95 return 0;
96 }
97 if (fseek(reader->handle, ftell(reader->handle) - len, SEEK_SET) == -1) {
98 reader->sd_errno = errno;
99 }
100 return 1;
101 }
102
sd_read_ubyte(sd_reader * reader)103 uint8_t sd_read_ubyte(sd_reader *reader) {
104 uint8_t d;
105 sd_read_buf(reader, (char*)&d, 1);
106 return d;
107 }
108
sd_read_uword(sd_reader * reader)109 uint16_t sd_read_uword(sd_reader *reader) {
110 uint16_t d;
111 sd_read_buf(reader, (char*)&d, 2);
112 return d;
113 }
114
sd_read_udword(sd_reader * reader)115 uint32_t sd_read_udword(sd_reader *reader) {
116 uint32_t d;
117 sd_read_buf(reader, (char*)&d, 4);
118 return d;
119 }
120
sd_read_byte(sd_reader * reader)121 int8_t sd_read_byte(sd_reader *reader) {
122 int8_t d;
123 sd_read_buf(reader, (char*)&d, 1);
124 return d;
125 }
126
sd_read_word(sd_reader * reader)127 int16_t sd_read_word(sd_reader *reader) {
128 int16_t d;
129 sd_read_buf(reader, (char*)&d, 2);
130 return d;
131 }
132
sd_read_dword(sd_reader * reader)133 int32_t sd_read_dword(sd_reader *reader) {
134 int32_t d;
135 sd_read_buf(reader, (char*)&d, 4);
136 return d;
137 }
138
sd_read_float(sd_reader * reader)139 float sd_read_float(sd_reader *reader) {
140 float f;
141 sd_read_buf(reader, (char*)&f, 4);
142 return f;
143 }
144
sd_peek_ubyte(sd_reader * reader)145 uint8_t sd_peek_ubyte(sd_reader *reader) {
146 uint8_t d;
147 sd_peek_buf(reader, (char*)&d, 1);
148 return d;
149 }
150
sd_peek_uword(sd_reader * reader)151 uint16_t sd_peek_uword(sd_reader *reader) {
152 uint16_t d;
153 sd_peek_buf(reader, (char*)&d, 2);
154 return d;
155 }
156
sd_peek_udword(sd_reader * reader)157 uint32_t sd_peek_udword(sd_reader *reader) {
158 uint32_t d;
159 sd_peek_buf(reader, (char*)&d, 4);
160 return d;
161 }
162
sd_peek_byte(sd_reader * reader)163 int8_t sd_peek_byte(sd_reader *reader) {
164 int8_t d;
165 sd_peek_buf(reader, (char*)&d, 1);
166 return d;
167 }
168
sd_peek_word(sd_reader * reader)169 int16_t sd_peek_word(sd_reader *reader) {
170 int16_t d;
171 sd_peek_buf(reader, (char*)&d, 2);
172 return d;
173 }
174
sd_peek_dword(sd_reader * reader)175 int32_t sd_peek_dword(sd_reader *reader) {
176 int32_t d;
177 sd_peek_buf(reader, (char*)&d, 4);
178 return d;
179 }
180
sd_peek_float(sd_reader * reader)181 float sd_peek_float(sd_reader *reader) {
182 float f;
183 sd_peek_buf(reader, (char*)&f, 4);
184 return f;
185 }
186
sd_match(sd_reader * reader,char * buf,unsigned int nbytes)187 int sd_match(sd_reader *reader, char *buf, unsigned int nbytes) {
188 char t[nbytes];
189 sd_peek_buf(reader, t, nbytes);
190 if(memcmp(t, buf, nbytes) == 0) {
191 return 1;
192 }
193 return 0;
194 }
195
sd_skip(sd_reader * reader,unsigned int nbytes)196 void sd_skip(sd_reader *reader, unsigned int nbytes) {
197 if (fseek(reader->handle, nbytes, SEEK_CUR) == -1) {
198 reader->sd_errno = errno;
199 }
200 }
201
sd_read_scan(const sd_reader * reader,const char * format,...)202 int sd_read_scan(const sd_reader *reader, const char* format, ...) {
203 va_list argp;
204 va_start(argp, format);
205 int ret = fscanf(reader->handle, format, argp);
206 va_end(argp);
207 return ret;
208 }
209
sd_read_line(const sd_reader * reader,char * buffer,int maxlen)210 int sd_read_line(const sd_reader *reader, char *buffer, int maxlen) {
211 if(fgets(buffer, maxlen, reader->handle) == NULL) {
212 return 1;
213 }
214 return 0;
215 }
216
sd_read_variable_str(sd_reader * r)217 char* sd_read_variable_str(sd_reader *r) {
218 uint16_t len = sd_read_uword(r);
219 char *str = NULL;
220 if(len > 0) {
221 str = (char*)malloc(len);
222 sd_read_buf(r, str, len);
223 }
224 return str;
225 }
226