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