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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 182 - (show annotations)
Sun Jan 4 22:07:02 2004 UTC (20 years, 3 months ago) by frodo
File MIME type: text/plain
File size: 11706 byte(s)
(Frodo) Move fontnames to psiconv_string type

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

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