/[public]/psiconv/trunk/lib/psiconv/parse_simple.c
ViewVC logotype

Annotation of /psiconv/trunk/lib/psiconv/parse_simple.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 188 - (hide annotations)
Mon Jan 26 12:59:54 2004 UTC (20 years, 2 months ago) by frodo
File MIME type: text/plain
File size: 12423 byte(s)
(Frodo) Oops, forgot about image.c

1 frodo 2 /*
2     parse_simple.c - Part of psiconv, a PSION 5 file formats converter
3 frodo 63 Copyright (c) 1999, 2000 Frodo Looijaard <frodol@dds.nl>
4 frodo 2
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9    
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     GNU General Public License for more details.
14    
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18     */
19    
20     #include "config.h"
21 frodo 71 #include "compat.h"
22    
23 frodo 2 #include <stdlib.h>
24 frodo 101 #include <math.h>
25 frodo 2
26     #include "parse_routines.h"
27 frodo 71 #include "error.h"
28 frodo 184 #include "unicode.h"
29 frodo 2
30 frodo 142 #ifdef DMALLOC
31     #include <dmalloc.h>
32     #endif
33    
34 frodo 171 static psiconv_float_t pow2(int n);
35 frodo 182 static psiconv_string_t psiconv_read_string_aux(const psiconv_config config,
36     const psiconv_buffer buf,int lev,
37     psiconv_u32 off,int *length, int *status,
38     int kind);
39 frodo 171
40 frodo 118 /* Very inefficient, but good enough for now. By implementing it ourselves,
41     we do not have to link with -lm */
42     psiconv_float_t pow2(int n)
43     {
44     psiconv_float_t res=1.0;
45     int i;
46    
47     for (i = 0; i < (n<0?-n:n); i++)
48     res *= 2.0;
49    
50     return n<0?1/res:res;
51     }
52 frodo 168 psiconv_u8 psiconv_read_u8(const psiconv_config config,const psiconv_buffer buf,int lev,psiconv_u32 off,
53 frodo 64 int *status)
54 frodo 2 {
55     psiconv_u8 *ptr;
56 frodo 79 ptr = psiconv_buffer_get(buf,off);
57 frodo 64 if (!ptr) {
58 frodo 184 psiconv_error(config,lev,off,"Trying byte read past the end of the file");
59 frodo 64 if (status)
60     *status = -PSICONV_E_PARSE;
61     return 0;
62     }
63     if (status)
64     *status = 0;
65 frodo 2 return *ptr;
66     }
67    
68 frodo 168 psiconv_u16 psiconv_read_u16(const psiconv_config config,const psiconv_buffer buf,int lev,psiconv_u32 off,
69 frodo 64 int *status)
70 frodo 2 {
71     psiconv_u8 *ptr0,*ptr1;
72 frodo 79 ptr0 = psiconv_buffer_get(buf,off);
73     ptr1 = psiconv_buffer_get(buf,off+1);
74 frodo 64 if (!ptr0 || !ptr1) {
75 frodo 184 psiconv_error(config,lev,off,"Trying word read past the end of the file");
76 frodo 64 if (status)
77     *status = -PSICONV_E_PARSE;
78     return 0;
79     }
80     if (status)
81     *status = 0;
82 frodo 2 return *ptr0 + (*ptr1 << 8);
83     }
84    
85 frodo 168 psiconv_u32 psiconv_read_u32(const psiconv_config config,const psiconv_buffer buf,int lev,psiconv_u32 off,
86 frodo 64 int *status)
87 frodo 2 {
88     psiconv_u8 *ptr0,*ptr1,*ptr2,*ptr3;
89 frodo 79 ptr0 = psiconv_buffer_get(buf,off);
90     ptr1 = psiconv_buffer_get(buf,off+1);
91     ptr2 = psiconv_buffer_get(buf,off+2);
92     ptr3 = psiconv_buffer_get(buf,off+3);
93 frodo 64 if (!ptr0 || !ptr1 || !ptr2 || !ptr3) {
94 frodo 184 psiconv_error(config,lev,off,"Trying long read past the end of the file");
95 frodo 64 if (status)
96     *status = -PSICONV_E_PARSE;
97     return 0;
98     }
99     if (status)
100     *status = 0;
101 frodo 2 return *ptr0 + (*ptr1 << 8) + (*ptr2 << 16) + (*ptr3 << 24);
102     }
103    
104 frodo 168 psiconv_s32 psiconv_read_sint(const psiconv_config config,const psiconv_buffer buf,int lev,psiconv_u32 off,
105 frodo 129 int *length,int *status)
106     {
107     int localstatus;
108     psiconv_u32 temp;
109    
110 frodo 168 temp=psiconv_read_u32(config,buf,lev,off,&localstatus);
111 frodo 129 if (status)
112     *status = localstatus;
113     if (length)
114     *length = localstatus?0:4;
115    
116     return localstatus?0:(temp & 0x7fffffff)*(temp&0x80000000?-1:1);
117     }
118    
119 frodo 188 psiconv_u32 psiconv_read_S(const psiconv_config config,const psiconv_buffer buf, int lev, psiconv_u32 off,
120 frodo 64 int *length,int *status)
121 frodo 2 {
122     psiconv_u8 temp;
123 frodo 188 psiconv_u32 res;
124 frodo 64 int len,localstatus;
125 frodo 2
126 frodo 168 psiconv_progress(config,lev+1,off,"Going to read a S length indicator");
127     temp = psiconv_read_u8(config,buf,lev+2,off,&localstatus);
128 frodo 64 if (localstatus)
129     goto ERROR;
130 frodo 2 if ((temp & 0x03) == 0x02) {
131 frodo 168 res = psiconv_read_u8(config,buf,lev+2,off,&localstatus) >> 2;
132 frodo 64 if (localstatus)
133     goto ERROR;
134 frodo 2 len = 1;
135 frodo 168 psiconv_debug(config,lev+2,off,"Indicator (1 byte): %02x",res);
136 frodo 132 } else if ((temp & 0x07) == 0x05) {
137 frodo 168 res = psiconv_read_u16(config,buf,lev+2,off,&localstatus) >> 3;
138 frodo 64 if (localstatus)
139     goto ERROR;
140 frodo 2 len = 2;
141 frodo 168 psiconv_debug(config,lev+2,off,"Indicator (2 bytes): %04x",res);
142 frodo 2 } else {
143 frodo 184 psiconv_error(config,lev+2,off,"S indicator: unknown encoding!");
144 frodo 168 psiconv_debug(config,lev+2,off,"Raw data first byte: %02x",temp);
145 frodo 64 goto ERROR;
146 frodo 2 }
147    
148     if (length)
149     *length = len;
150 frodo 64 if (status)
151     *status = 0;
152 frodo 2
153 frodo 168 psiconv_progress(config,lev+1,off+len-1,
154 frodo 2 "End of S length indicator (total length: %08x)", len);
155    
156     return res;
157 frodo 64
158     ERROR:
159 frodo 184 psiconv_error(config,lev+1,off,"Reading of S indicator failed");
160 frodo 64 if (status)
161     *status = localstatus;
162     if (length)
163     *length = 0;
164     return 0;
165 frodo 2 }
166    
167 frodo 188 psiconv_u32 psiconv_read_X(const psiconv_config config,const psiconv_buffer buf, int lev, psiconv_u32 off,
168 frodo 64 int *length, int *status)
169 frodo 2 {
170     psiconv_u8 temp;
171 frodo 188 psiconv_u32 res;
172 frodo 64 int len,localstatus;
173 frodo 2
174 frodo 168 psiconv_progress(config,lev+1,off,"Going to read a X length indicator");
175     temp = psiconv_read_u8(config,buf,lev+2,off,&localstatus);
176 frodo 64 if (localstatus)
177     goto ERROR;
178 frodo 2 if ((temp & 0x01) == 0x00) {
179 frodo 168 res = psiconv_read_u8(config,buf,lev+2,off,&localstatus) >> 1;
180 frodo 64 if (localstatus)
181     goto ERROR;
182 frodo 2 len = 1;
183 frodo 168 psiconv_debug(config,lev+2,off,"Indicator (1 byte): %02x",res);
184 frodo 2 } else if ((temp & 0x03) == 0x01) {
185 frodo 168 res = psiconv_read_u16(config,buf,lev+2,off,&localstatus) >> 2;
186 frodo 64 if (localstatus)
187     goto ERROR;
188 frodo 2 len = 2;
189 frodo 168 psiconv_debug(config,lev+2,off,"Indicator (2 bytes): %04x",res);
190 frodo 2 } else if ((temp & 0x07) == 0x03) {
191 frodo 168 res = psiconv_read_u32(config,buf,lev+2,off,&localstatus) >> 3;
192 frodo 64 if (localstatus)
193     goto ERROR;
194 frodo 2 len = 4;
195 frodo 168 psiconv_debug(config,lev+2,off,"Indicator (4 bytes): %08x",res);
196 frodo 2 } else {
197 frodo 184 psiconv_error(config,lev+2,off,"X indicator: unknown encoding!");
198 frodo 168 psiconv_debug(config,lev+2,off,"Raw data first byte: %02x",temp);
199 frodo 64 goto ERROR;
200 frodo 2 }
201    
202     if (length)
203     *length = len;
204 frodo 64 if (status)
205     *status = 0;
206 frodo 2
207 frodo 168 psiconv_progress(config,lev+1,off+len-1,
208 frodo 2 "End of X length indicator (total length: %08x)", len);
209    
210     return res;
211 frodo 64
212     ERROR:
213 frodo 184 psiconv_error(config,lev+1,off,"Reading of X indicator failed");
214 frodo 64 if (status)
215     *status = localstatus;
216     if (length)
217     *length = 0;
218     return 0;
219 frodo 2 }
220    
221 frodo 168 psiconv_length_t psiconv_read_length(const psiconv_config config,const psiconv_buffer buf, int lev,
222 frodo 64 psiconv_u32 off, int *length, int *status)
223 frodo 2 {
224     psiconv_length_t res;
225 frodo 64 int localstatus;
226    
227 frodo 168 res = (2.54/1440.0) * ((psiconv_s32) psiconv_read_u32(config,buf,lev,off,
228 frodo 64 &localstatus));
229     if (localstatus) {
230 frodo 184 psiconv_error(config,lev+1,off,"Reading of length failed");
231 frodo 64 if (length)
232     *length = 0;
233     if (status)
234     *status = localstatus;
235     return 0;
236     }
237 frodo 168 psiconv_debug(config,lev+1,off,"Length: %f",res);
238 frodo 2 if (length)
239     *length = 4;
240 frodo 64 if (status)
241     *status = 0;
242 frodo 2 return res;
243     }
244    
245 frodo 168 psiconv_size_t psiconv_read_size(const psiconv_config config,const psiconv_buffer buf, int lev,
246 frodo 64 psiconv_u32 off, int *length, int *status)
247 frodo 2 {
248     psiconv_size_t res;
249 frodo 64 int localstatus;
250 frodo 168 res = ((psiconv_s32) psiconv_read_u32(config,buf,lev,off,&localstatus)) / 20.0;
251 frodo 64 if (localstatus) {
252 frodo 184 psiconv_error(config,lev+1,off,"Reading of size failed");
253 frodo 64 if (length)
254     *length = 0;
255     if (status)
256     *status = localstatus;
257     return 0;
258     }
259 frodo 168 psiconv_debug(config,lev+1,off,"Size: %f",res);
260 frodo 64 if (status)
261     *status = 0;
262 frodo 2 if (length)
263     *length = 4;
264     return res;
265     }
266    
267 frodo 168 int psiconv_parse_bool(const psiconv_config config,const psiconv_buffer buf, int lev, psiconv_u32 off,
268 frodo 2 int *length, psiconv_bool_t *result)
269     {
270     psiconv_u8 temp;
271 frodo 64 int localstatus;
272 frodo 168 temp = psiconv_read_u8(config,buf,lev,off,&localstatus);
273 frodo 64 if (localstatus) {
274 frodo 184 psiconv_error(config,lev+1,off,"Reading of bool failed");
275 frodo 64 if (length)
276     *length = 0;
277     return localstatus;
278     }
279 frodo 2 if (length)
280     *length = 1;
281     if (temp == 0) {
282     *result = psiconv_bool_false;
283     return 0;
284     } else if (temp == 1) {
285     *result = psiconv_bool_true;
286     return 0;
287     }
288 frodo 168 psiconv_warn(config,lev+1,off,"Unknown value for boolean");
289     psiconv_debug(config,lev+1,off,"Boolean value: %02x",temp);
290 frodo 2 *result = psiconv_bool_true;
291 frodo 64 return 0;
292 frodo 2 }
293    
294 frodo 182 psiconv_string_t psiconv_read_string(const psiconv_config config,
295     const psiconv_buffer buf,int lev,
296 frodo 64 psiconv_u32 off,int *length, int *status)
297 frodo 2 {
298 frodo 184 return psiconv_read_string_aux(config,buf,lev,off,length,status,-1);
299 frodo 182 }
300    
301     psiconv_string_t psiconv_read_short_string(const psiconv_config config,
302     const psiconv_buffer buf,int lev,
303     psiconv_u32 off,int *length, int *status)
304     {
305 frodo 184 return psiconv_read_string_aux(config,buf,lev,off,length,status,-2);
306 frodo 182 }
307    
308 frodo 184 psiconv_string_t psiconv_read_charlist(const psiconv_config config,
309     const psiconv_buffer buf, int lev,
310     psiconv_u32 off, int nrofchars,
311     int *status)
312     {
313     int length;
314     if (nrofchars <= 0) {
315     psiconv_error(config,lev,off,
316     "psiconv_read_charlist called with non-positive nrofchars");
317     if (status)
318     *status = -PSICONV_E_OTHER;
319     return NULL;
320     }
321     return psiconv_read_string_aux(config,buf,lev,off,&length,status,nrofchars);
322     }
323    
324    
325 frodo 182 psiconv_string_t psiconv_read_string_aux(const psiconv_config config,
326     const psiconv_buffer buf,int lev,
327     psiconv_u32 off,int *length, int *status,
328     int kind)
329     {
330 frodo 64 int stringlen,i,leng,len,localstatus;
331 frodo 2 psiconv_string_t result;
332     char *res_copy;
333 frodo 184 psiconv_u8 temp;
334 frodo 2
335 frodo 168 psiconv_progress(config,lev+1,off,"Going to read a string");
336 frodo 2
337 frodo 184 if (kind == -1)
338 frodo 182 stringlen = psiconv_read_S(config,buf,lev+2,off,&leng,&localstatus);
339 frodo 184 else if (kind == -2) {
340 frodo 182 stringlen = psiconv_read_u8(config,buf,lev+2,off,&localstatus);
341     leng = 1;
342 frodo 184 } else {
343     stringlen = kind;
344     leng = 0;
345     localstatus = 0;
346 frodo 182 }
347 frodo 64 if (localstatus)
348     goto ERROR1;
349 frodo 168 psiconv_debug(config,lev+2,off,"Length: %i",stringlen);
350 frodo 2 len = leng;
351    
352 frodo 184 result = malloc(sizeof(*result) * (stringlen + 1));
353 frodo 64 if (!result)
354     goto ERROR1;
355 frodo 184 for (i = 0; i < stringlen; i++) {
356     temp = psiconv_read_u8(config,buf,lev,off+i+len,&localstatus);
357     if (localstatus)
358     goto ERROR2;
359     result[i] = psiconv_unicode_from_char(config,temp);
360     }
361 frodo 2 result[stringlen] = 0;
362     len += stringlen;
363    
364 frodo 184 res_copy = psiconv_make_printable(config,result);
365 frodo 64 if (!res_copy)
366     goto ERROR2;
367 frodo 168 psiconv_debug(config,lev+2,off,"Contents: `%s'",res_copy);
368 frodo 2 free(res_copy);
369    
370     if (length)
371     *length = len;
372    
373 frodo 64 if (status)
374     *status = 0;
375    
376 frodo 168 psiconv_progress(config,lev+1,off+len-1,"End of string (total length: %08x)",len);
377 frodo 2
378     return result;
379 frodo 64
380     ERROR2:
381     free(result);
382     ERROR1:
383 frodo 184 psiconv_error(config,lev+1,off,"Reading of string failed");
384 frodo 64 if (status)
385     *status = localstatus;
386     if (length)
387     *length = 0;
388     return NULL;
389 frodo 2 }
390 frodo 101
391 frodo 168 psiconv_float_t psiconv_read_float(const psiconv_config config,const psiconv_buffer buf, int lev,
392 frodo 101 psiconv_u32 off, int *length, int *status)
393     {
394     psiconv_float_t result,bitvalue;
395     int res,bit;
396     psiconv_u32 temp=0;
397    
398 frodo 168 psiconv_progress(config,lev+1,off,"Going to read a float");
399 frodo 101
400     bitvalue = 0.5;
401     result = 1.0;
402     for (bit = 0x33; bit > 0; bit--) {
403     if ((bit == 0x33) || ((bit & 0x07) == 0x07))
404 frodo 168 temp = psiconv_read_u8(config,buf,lev+2,off+ (bit >> 3),&res);
405 frodo 101 if (res)
406     goto ERROR;
407     if (temp & (0x01 << (bit & 0x07)))
408     result += bitvalue;
409     bitvalue /= 2.0;
410     }
411 frodo 168 temp = psiconv_read_u16(config,buf,lev+2,off+6,&res);
412 frodo 101 if (res)
413     goto ERROR;
414     if (temp & 0x8000)
415     result = -result;
416     temp = (temp & 0x7ff0) >> 4;
417 frodo 118 result *= pow2(((int) temp)-0x3ff);
418 frodo 168 psiconv_debug(config,lev+1,off,"Float value: %f",result);
419 frodo 101 if (length)
420     *length = 8;
421     if (*status)
422     *status = res;
423     return result;
424     ERROR:
425 frodo 184 psiconv_error(config,lev+1,off,"Reading of float failed");
426 frodo 101 if (length)
427     *length = 0;
428     if (*status)
429     *status = res;
430     return 0.0;
431     }
432 frodo 118

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26