… | |
… | |
24 | #include <math.h> |
24 | #include <math.h> |
25 | |
25 | |
26 | #include "parse_routines.h" |
26 | #include "parse_routines.h" |
27 | #include "error.h" |
27 | #include "error.h" |
28 | |
28 | |
|
|
29 | #ifdef DMALLOC |
|
|
30 | #include <dmalloc.h> |
|
|
31 | #endif |
|
|
32 | |
|
|
33 | /* Very inefficient, but good enough for now. By implementing it ourselves, |
|
|
34 | we do not have to link with -lm */ |
|
|
35 | psiconv_float_t pow2(int n) |
|
|
36 | { |
|
|
37 | psiconv_float_t res=1.0; |
|
|
38 | int i; |
|
|
39 | |
|
|
40 | for (i = 0; i < (n<0?-n:n); i++) |
|
|
41 | res *= 2.0; |
|
|
42 | |
|
|
43 | return n<0?1/res:res; |
|
|
44 | } |
29 | psiconv_u8 psiconv_read_u8(const psiconv_buffer buf,int lev,psiconv_u32 off, |
45 | psiconv_u8 psiconv_read_u8(const psiconv_buffer buf,int lev,psiconv_u32 off, |
30 | int *status) |
46 | int *status) |
31 | { |
47 | { |
32 | psiconv_u8 *ptr; |
48 | psiconv_u8 *ptr; |
33 | ptr = psiconv_buffer_get(buf,off); |
49 | ptr = psiconv_buffer_get(buf,off); |
… | |
… | |
76 | if (status) |
92 | if (status) |
77 | *status = 0; |
93 | *status = 0; |
78 | return *ptr0 + (*ptr1 << 8) + (*ptr2 << 16) + (*ptr3 << 24); |
94 | return *ptr0 + (*ptr1 << 8) + (*ptr2 << 16) + (*ptr3 << 24); |
79 | } |
95 | } |
80 | |
96 | |
|
|
97 | psiconv_s32 psiconv_read_sint(const psiconv_buffer buf,int lev,psiconv_u32 off, |
|
|
98 | int *length,int *status) |
|
|
99 | { |
|
|
100 | int localstatus; |
|
|
101 | psiconv_u32 temp; |
|
|
102 | |
|
|
103 | temp=psiconv_read_u32(buf,lev,off,&localstatus); |
|
|
104 | if (status) |
|
|
105 | *status = localstatus; |
|
|
106 | if (length) |
|
|
107 | *length = localstatus?0:4; |
|
|
108 | |
|
|
109 | return localstatus?0:(temp & 0x7fffffff)*(temp&0x80000000?-1:1); |
|
|
110 | } |
|
|
111 | |
81 | psiconv_S_t psiconv_read_S(const psiconv_buffer buf, int lev, psiconv_u32 off, |
112 | psiconv_S_t psiconv_read_S(const psiconv_buffer buf, int lev, psiconv_u32 off, |
82 | int *length,int *status) |
113 | int *length,int *status) |
83 | { |
114 | { |
84 | psiconv_u8 temp; |
115 | psiconv_u8 temp; |
85 | psiconv_S_t res; |
116 | psiconv_S_t res; |
… | |
… | |
93 | res = psiconv_read_u8(buf,lev+2,off,&localstatus) >> 2; |
124 | res = psiconv_read_u8(buf,lev+2,off,&localstatus) >> 2; |
94 | if (localstatus) |
125 | if (localstatus) |
95 | goto ERROR; |
126 | goto ERROR; |
96 | len = 1; |
127 | len = 1; |
97 | psiconv_debug(lev+2,off,"Indicator (1 byte): %02x",res); |
128 | psiconv_debug(lev+2,off,"Indicator (1 byte): %02x",res); |
98 | } else if ((temp & 0x07) == 0x03) { |
129 | } else if ((temp & 0x07) == 0x05) { |
99 | res = psiconv_read_u16(buf,lev+2,off,&localstatus) >> 3; |
130 | res = psiconv_read_u16(buf,lev+2,off,&localstatus) >> 3; |
100 | if (localstatus) |
131 | if (localstatus) |
101 | goto ERROR; |
132 | goto ERROR; |
102 | len = 2; |
133 | len = 2; |
103 | psiconv_debug(lev+2,off,"Indicator (2 bytes): %04x",res); |
134 | psiconv_debug(lev+2,off,"Indicator (2 bytes): %04x",res); |
… | |
… | |
303 | if (length) |
334 | if (length) |
304 | *length = 0; |
335 | *length = 0; |
305 | return NULL; |
336 | return NULL; |
306 | } |
337 | } |
307 | |
338 | |
|
|
339 | psiconv_string_t psiconv_read_short_string(const psiconv_buffer buf, |
|
|
340 | int lev, |
|
|
341 | psiconv_u32 off,int *length, int *status) |
|
|
342 | { |
|
|
343 | int stringlen,i,len,localstatus; |
|
|
344 | psiconv_string_t result; |
|
|
345 | char *res_copy; |
|
|
346 | |
|
|
347 | psiconv_progress(lev+1,off,"Going to read a short string"); |
|
|
348 | |
|
|
349 | stringlen = psiconv_read_u8(buf,lev+2,off,&localstatus); |
|
|
350 | if (localstatus) |
|
|
351 | goto ERROR1; |
|
|
352 | psiconv_debug(lev+2,off,"Length: %i",stringlen); |
|
|
353 | len = 1; |
|
|
354 | |
|
|
355 | result = malloc(stringlen + 1); |
|
|
356 | if (!result) |
|
|
357 | goto ERROR1; |
|
|
358 | for (i = 0; (i < stringlen) && !localstatus; i++) |
|
|
359 | result[i] = psiconv_read_u8(buf,lev,off+i+len,&localstatus); |
|
|
360 | if (localstatus) |
|
|
361 | goto ERROR2; |
|
|
362 | result[stringlen] = 0; |
|
|
363 | len += stringlen; |
|
|
364 | |
|
|
365 | res_copy = psiconv_make_printable(result); |
|
|
366 | if (!res_copy) |
|
|
367 | goto ERROR2; |
|
|
368 | psiconv_debug(lev+2,off,"Contents: `%s'",res_copy); |
|
|
369 | free(res_copy); |
|
|
370 | |
|
|
371 | if (length) |
|
|
372 | *length = len; |
|
|
373 | |
|
|
374 | if (status) |
|
|
375 | *status = 0; |
|
|
376 | |
|
|
377 | psiconv_progress(lev+1,off+len-1,"End of short string (total length: %08x)", |
|
|
378 | len); |
|
|
379 | |
|
|
380 | return result; |
|
|
381 | |
|
|
382 | |
|
|
383 | ERROR2: |
|
|
384 | free(result); |
|
|
385 | ERROR1: |
|
|
386 | psiconv_warn(lev+1,off,"Reading of short string failed"); |
|
|
387 | if (status) |
|
|
388 | *status = localstatus; |
|
|
389 | if (length) |
|
|
390 | *length = 0; |
|
|
391 | return NULL; |
|
|
392 | } |
|
|
393 | |
308 | psiconv_float_t psiconv_read_float(const psiconv_buffer buf, int lev, |
394 | psiconv_float_t psiconv_read_float(const psiconv_buffer buf, int lev, |
309 | psiconv_u32 off, int *length, int *status) |
395 | psiconv_u32 off, int *length, int *status) |
310 | { |
396 | { |
311 | psiconv_float_t result,bitvalue; |
397 | psiconv_float_t result,bitvalue; |
312 | int res,bit; |
398 | int res,bit; |
… | |
… | |
329 | if (res) |
415 | if (res) |
330 | goto ERROR; |
416 | goto ERROR; |
331 | if (temp & 0x8000) |
417 | if (temp & 0x8000) |
332 | result = -result; |
418 | result = -result; |
333 | temp = (temp & 0x7ff0) >> 4; |
419 | temp = (temp & 0x7ff0) >> 4; |
334 | result *= pow(2.0,((int) temp)-0x3ff); |
420 | result *= pow2(((int) temp)-0x3ff); |
335 | psiconv_debug(lev+1,off,"Float value: %f",result); |
421 | psiconv_debug(lev+1,off,"Float value: %f",result); |
336 | if (length) |
422 | if (length) |
337 | *length = 8; |
423 | *length = 8; |
338 | if (*status) |
424 | if (*status) |
339 | *status = res; |
425 | *status = res; |
… | |
… | |
344 | *length = 0; |
430 | *length = 0; |
345 | if (*status) |
431 | if (*status) |
346 | *status = res; |
432 | *status = res; |
347 | return 0.0; |
433 | return 0.0; |
348 | } |
434 | } |
|
|
435 | |