1
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <assert.h>
6
7 int fileOffset = 0;
8
9 int gIndent = 0;
10 char indentBuf[256];
11 int lastIndent = 0;
12
error(char * s,...)13 void error(char *s, ...)
14 {
15 va_list ap;
16 va_start(ap, s);
17 vprintf(s, ap);
18 va_end(ap);
19 putchar('\n');
20 exit(-1);
21 }
22
warning(char * s,...)23 void warning(char *s, ...)
24 {
25 va_list ap;
26 va_start(ap, s);
27 vprintf(s, ap);
28 va_end(ap);
29 putchar('\n');
30 }
31
indent()32 char *indent()
33 {
34 int i;
35
36 if(gIndent>63)
37 error("indent level > 63!");
38
39 if(lastIndent != gIndent)
40 {
41 for(i=0; i<3*gIndent; ++i)
42 indentBuf[i] = ' ';
43
44 indentBuf[i] = '\0';
45
46 lastIndent = gIndent;
47 }
48
49 return indentBuf;
50 }
51
52 int buffer;
53 int bufbits = 0; /* # of bits in buffer */
54
byteAlign()55 void byteAlign()
56 {
57 if(bufbits > 0)
58 {
59 bufbits = 0;
60 buffer = 0;
61 }
62 }
63
readBits(FILE * f,int number)64 int readBits(FILE *f, int number)
65 {
66 int ret = buffer;
67 int tmp_char;
68
69 if(number == bufbits)
70 {
71 bufbits = 0;
72 buffer = 0;
73 return ret;
74 }
75
76 if(number > bufbits)
77 {
78 number -= bufbits;
79
80 while(number>8)
81 {
82 ret <<= 8;
83 tmp_char = fgetc(f);
84 if (tmp_char == EOF)
85 {
86 // exit here instead of crashing elswhere
87 fprintf(stderr, "truncated file\n");
88 exit(-1);
89 }
90
91 ret += tmp_char;
92 ++fileOffset;
93 number -= 8;
94 }
95
96 ++fileOffset;
97 tmp_char = fgetc(f);
98 if (tmp_char == EOF)
99 {
100 // exit here instead of crashing elswhere
101 fprintf(stderr, "truncated file\n");
102 exit(-1);
103 }
104
105 buffer = tmp_char;
106
107 if(number>0)
108 {
109 ret <<= number;
110 bufbits = 8-number;
111 ret += buffer >> (8-number);
112 buffer &= (1<<bufbits)-1;
113 }
114
115 return ret;
116 }
117
118 ret = buffer >> (bufbits-number);
119 bufbits -= number;
120 buffer &= (1<<bufbits)-1;
121
122 return ret;
123 }
124
readSBits(FILE * f,int number)125 int readSBits(FILE *f, int number)
126 {
127 int num = readBits(f, number);
128
129 if(num & (1<<(number-1)))
130 return num - (1<<number);
131 else
132 return num;
133 }
134
readUInt8(FILE * f)135 int readUInt8(FILE *f)
136 {
137 int tmp_char = fgetc(f);
138 // the rest of the code does not handle errors and use EOF as a valid unsigned char value
139 if (tmp_char == EOF)
140 {
141 // exit here instead of crashing elswhere
142 fprintf(stderr, "truncated file\n");
143 exit(-1);
144 }
145
146 bufbits = 0;
147 ++fileOffset;
148 return tmp_char;
149 }
150
readSInt8(FILE * f)151 int readSInt8(FILE *f)
152 {
153 return (signed char)readUInt8(f);
154 }
155
readSInt16(FILE * f)156 int readSInt16(FILE *f)
157 {
158 return readUInt8(f) + readSInt8(f)*256;
159 }
160
readUInt16(FILE * f)161 int readUInt16(FILE *f)
162 {
163 return readUInt8(f) + (readUInt8(f)<<8);
164 }
165
readSInt32(FILE * f)166 long readSInt32(FILE *f)
167 {
168 return (long)readUInt8(f) + (readUInt8(f)<<8) + (readUInt8(f)<<16) + (readUInt8(f)<<24);
169 }
170
readUInt32(FILE * f)171 unsigned long readUInt32(FILE *f)
172 {
173 return (unsigned long)(readUInt8(f) + (readUInt8(f)<<8) + (readUInt8(f)<<16) + (readUInt8(f)<<24));
174 }
175
readDouble(FILE * f)176 double readDouble(FILE *f)
177 {
178 char data[8];
179
180 data[4] = readUInt8(f);
181 data[5] = readUInt8(f);
182 data[6] = readUInt8(f);
183 data[7] = readUInt8(f);
184 data[0] = readUInt8(f);
185 data[1] = readUInt8(f);
186 data[2] = readUInt8(f);
187 data[3] = readUInt8(f);
188
189 return *((double *)data);
190 }
191
readString(FILE * f)192 char *readString(FILE *f)
193 {
194 int len = 0, buflen = 256;
195 char c, *buf, *p;
196
197 buf = (char *)malloc(sizeof(char)*256);
198 p = buf;
199
200 while((c=(char)readUInt8(f)) != '\0')
201 {
202 if(len >= buflen-2)
203 {
204 buf = (char *)realloc(buf, sizeof(char)*(buflen+256));
205 buflen += 256;
206 p = buf+len;
207 }
208
209 switch(c)
210 {
211 case '\n':
212 *(p++) = '\\'; *(p++) = 'n'; ++len; break;
213 case '\t':
214 *(p++) = '\\'; *(p++) = 't'; ++len; break;
215 case '\r':
216 *(p++) = '\\'; *(p++) = 'r'; ++len; break;
217 default:
218 *(p++) = c;
219 }
220
221 ++len;
222 }
223
224 *p = 0;
225
226 return buf;
227 }
228
dumpBytes(FILE * f,int length)229 void dumpBytes(FILE *f, int length)
230 {
231 int j=0, i, k, l=0;
232 unsigned char buf[16];
233
234 if(length<=0)
235 return;
236
237 putchar('\n');
238
239 for(;; ++l)
240 {
241 printf("%03x0: ", l);
242 for(i=0; i<16; ++i)
243 {
244 if(i==8) putchar(' ');
245
246 printf("%02x ", buf[i] = readUInt8(f));
247 ++j;
248
249 if(j==length)
250 break;
251 }
252
253 if(j==length)
254 {
255 for(k=i+1; k<16; ++k)
256 printf(" ");
257
258 if(k==8) putchar(' ');
259
260 ++i;
261 }
262
263 printf(" ");
264
265 for(k=0; k<i; ++k)
266 {
267 if(k==8) putchar(' ');
268
269 if((buf[k] > 31) && (buf[k] < 128))
270 putchar(buf[k]);
271 else
272 putchar('.');
273 }
274
275 putchar('\n');
276
277 if(j==length)
278 break;
279 }
280 putchar('\n');
281 putchar('\n');
282 }
283
dumpBuffer(unsigned char * buf,int length)284 void dumpBuffer(unsigned char *buf, int length)
285 {
286 int j=0, i, k, l=0;
287
288 if(length<=0)
289 return;
290
291 putchar('\n');
292
293 for(;; ++l)
294 {
295 printf("%03x0: ", l);
296
297 for(i=0; i<16; ++i)
298 {
299 if(i==8) putchar(' ');
300
301 printf("%02x ", buf[16*l+i]);
302 ++j;
303
304 if(j==length)
305 break;
306 }
307
308 if(j==length)
309 {
310 for(k=i+1; k<16; ++k)
311 printf(" ");
312
313 if(k==8) putchar(' ');
314
315 ++i;
316 }
317
318 printf(" ");
319
320 for(k=0; k<i; ++k)
321 {
322 if(k==8) putchar(' ');
323
324 if((buf[16*l+k] > 31) && (buf[16*l+k] < 128))
325 putchar(buf[16*l+k]);
326 else
327 putchar('.');
328 }
329
330 putchar('\n');
331
332 if(j==length)
333 break;
334 }
335
336 putchar('\n');
337 putchar('\n');
338 }
339