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