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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 161 - (hide annotations)
Thu Nov 20 23:45:47 2003 UTC (20 years, 5 months ago) by frodo
File MIME type: text/plain
File size: 37788 byte(s)
(Frodo) More embedded object work. Everytihng except the object data itself
        is now safely parsed.

1 frodo 2 /*
2     parse_common.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 20 #include "compat.h"
22 frodo 2 #include <stdlib.h>
23     #include <string.h>
24    
25     #include "parse_routines.h"
26 frodo 71 #include "error.h"
27 frodo 2
28 frodo 142 #ifdef DMALLOC
29     #include <dmalloc.h>
30     #endif
31    
32    
33 frodo 2 static int psiconv_parse_layout_section(const psiconv_buffer buf,
34     int lev,psiconv_u32 off,
35     int *length,
36     psiconv_text_and_layout result,
37     psiconv_word_styles_section styles,
38     int with_styles);
39    
40     int psiconv_parse_header_section(const psiconv_buffer buf,int lev,
41     psiconv_u32 off, int *length,
42     psiconv_header_section *result)
43     {
44     int res=0;
45     int len=0;
46     psiconv_u32 temp;
47    
48     psiconv_progress(lev+1,off+len,"Going to read the header section");
49 frodo 64 if (!((*result) = malloc(sizeof(**result))))
50     goto ERROR1;
51 frodo 2
52     psiconv_progress(lev+2,off+len,"Going to read UID1 to UID3");
53 frodo 64 (*result)->uid1 = psiconv_read_u32(buf,lev+2,off+len,&res);
54 frodo 65 if (res)
55 frodo 64 goto ERROR2;
56 frodo 2 psiconv_debug(lev+2,off+len,"UID1: %08x",(*result)->uid1);
57 frodo 41 if ((*result)->uid1 == PSICONV_ID_CLIPART) {
58     /* That's all folks... */
59     (*result)->file = psiconv_clipart_file;
60     (*result)->uid2 = 0;
61     (*result)->uid3 = 0;
62     (*result)->checksum = 0;
63     len += 4;
64 frodo 43 psiconv_debug(lev+2,off+len,"File is a Clipart file");
65 frodo 41 goto DONE;
66     }
67 frodo 2 if ((*result)->uid1 != PSICONV_ID_PSION5) {
68     psiconv_warn(lev+2,off+len,"UID1 has unknown value. This is probably "
69     "not a (parsable) Psion 5 file");
70 frodo 64 res = -PSICONV_E_PARSE;
71     goto ERROR2;
72 frodo 2 }
73     len += 4;
74 frodo 64 (*result)->uid2 = psiconv_read_u32(buf,lev+2,off+len,&res);
75     if (res)
76     goto ERROR2;
77 frodo 2 psiconv_debug(lev+2,off+len,"UID2: %08x",(*result)->uid2);
78     len += 4;
79 frodo 64 (*result)->uid3 = psiconv_read_u32(buf,lev+2,off+len,&res);
80     if (res)
81     goto ERROR2;
82 frodo 2 psiconv_debug(lev+2,off+len,"UID3: %08x",(*result)->uid3);
83     len += 4;
84    
85     (*result)->file = psiconv_unknown_file;
86     if ((*result)->uid1 == PSICONV_ID_PSION5) {
87     if ((*result)->uid2 == PSICONV_ID_DATA_FILE) {
88     if ((*result)->uid3 == PSICONV_ID_WORD) {
89     (*result)->file = psiconv_word_file;
90     psiconv_debug(lev+2,off+len,"File is a Word file");
91     } else if ((*result)->uid3 == PSICONV_ID_TEXTED) {
92     (*result)->file = psiconv_texted_file;
93     psiconv_debug(lev+2,off+len,"File is a TextEd file");
94 frodo 24 } else if ((*result)->uid3 == PSICONV_ID_SKETCH) {
95     (*result)->file = psiconv_sketch_file;
96     psiconv_debug(lev+2,off+len,"File is a Sketch file");
97 frodo 94 } else if ((*result)->uid3 == PSICONV_ID_SHEET) {
98     (*result)->file = psiconv_sheet_file;
99     psiconv_debug(lev+2,off+len,"File is a Sheet file");
100     }
101 frodo 12 } else if ((*result)->uid2 == PSICONV_ID_MBM_FILE) {
102     (*result)->file = psiconv_mbm_file;
103     if ((*result)->uid3 != 0x00)
104     psiconv_warn(lev+2,off+len,"UID3 set in MBM file?!?");
105     psiconv_debug(lev+2,off+len,"File is a MBM file");
106     }
107 frodo 2 }
108     if ((*result)->file == psiconv_unknown_file) {
109     psiconv_warn(lev+2,off+len,"Unknown file type");
110     (*result)->file = psiconv_unknown_file;
111     }
112    
113     psiconv_progress(lev+2,off+len,"Checking UID4");
114 frodo 64 temp = psiconv_read_u32(buf,lev+2,off+len,&res);
115     if (res)
116     goto ERROR2;
117 frodo 2 if (temp == psiconv_checkuid((*result)->uid1,(*result)->uid2,
118     (*result)->uid3))
119     psiconv_debug(lev+2,off+len,"Checksum %08x is correct",temp);
120     else {
121     psiconv_warn(lev+2,off+len,"Checksum failed, file corrupted!");
122     psiconv_debug(lev+2,off+len,"Expected checksum %08x, found %08x",
123     psiconv_checkuid((*result)->uid1,(*result)->uid2,
124     (*result)->uid3),temp);
125 frodo 64 res = -PSICONV_E_PARSE;
126     goto ERROR2;
127 frodo 2 }
128     len += 4;
129 frodo 41
130     DONE:
131 frodo 2 if (length)
132     *length = len;
133    
134     psiconv_progress(lev+1,off+len-1,
135     "End of Header Section (total length: %08x)",len);
136    
137     return res;
138 frodo 64
139     ERROR2:
140     free(*result);
141     ERROR1:
142     psiconv_warn(lev+1,off,"Reading of Header Section failed");
143     if (length)
144     *length = 0;
145     if (res == 0)
146     return -PSICONV_E_NOMEM;
147     else
148     return res;
149 frodo 2 }
150    
151     int psiconv_parse_section_table_section(const psiconv_buffer buf, int lev,
152     psiconv_u32 off, int *length,
153     psiconv_section_table_section *result)
154     {
155     int res=0;
156     int len=0;
157     psiconv_section_table_entry entry;
158    
159     int i;
160     psiconv_u8 nr;
161    
162     psiconv_progress(lev+1,off+len,"Going to read the section table section");
163 frodo 64 if (!(*result = psiconv_list_new(sizeof(*entry))))
164     goto ERROR1;
165 frodo 2
166     psiconv_progress(lev+2,off+len,"Going to read the section table length");
167 frodo 64 nr = psiconv_read_u8(buf,lev+2,off+len,&res);
168     if (res)
169     goto ERROR2;
170 frodo 2 psiconv_debug(lev+2,off+len,"Length: %08x",nr);
171     if (nr & 0x01) {
172     psiconv_warn(lev+2,off+len,
173     "Section table length odd - ignoring last entry");
174     }
175     len ++;
176    
177     psiconv_progress(lev+2,off+len,"Going to read the section table entries");
178     entry = malloc(sizeof(*entry));
179     for (i = 0; i < nr / 2; i++) {
180 frodo 64 entry->id = psiconv_read_u32(buf,lev+2,off + len,&res);
181     if (res)
182     goto ERROR3;
183 frodo 2 psiconv_debug(lev+2,off + len,"Entry %d: ID = %08x",i,entry->id);
184     len += 0x04;
185 frodo 64 entry->offset = psiconv_read_u32(buf,lev+2,off + len,&res);
186     if (res)
187     goto ERROR3;
188 frodo 2 psiconv_debug(lev+2,off +len,"Entry %d: Offset = %08x",i,entry->offset);
189     len += 0x04;
190 frodo 64 if ((res=psiconv_list_add(*result,entry)))
191     goto ERROR3;
192 frodo 2 }
193    
194     free(entry);
195    
196     if (length)
197     *length = len;
198    
199     psiconv_progress(lev+1,off+len-1,"End of section table section "
200 frodo 25 "(total length: %08x)", len);
201 frodo 2
202 frodo 64 return 0;
203     ERROR3:
204     free(entry);
205     ERROR2:
206     psiconv_list_free(*result);
207     ERROR1:
208     psiconv_warn(lev+1,off,"Reading of Section Table Section failed");
209     if (length)
210     *length = 0;
211     if (res == 0)
212     return -PSICONV_E_NOMEM;
213     else
214     return res;
215 frodo 2 }
216    
217     int psiconv_parse_application_id_section(const psiconv_buffer buf, int lev,
218     psiconv_u32 off, int *length,
219     psiconv_application_id_section *result)
220     {
221     int res=0;
222     int len=0;
223     int leng;
224    
225     psiconv_progress(lev+1,off,"Going to read the application id section");
226 frodo 64 if (!(*result = malloc(sizeof(**result))))
227     goto ERROR1;
228 frodo 2
229     psiconv_progress(lev+2,off+len,"Going to read the type identifier");
230 frodo 64 (*result)->id = psiconv_read_u32(buf,lev+2,off+len,&res);
231     if (res)
232     goto ERROR2;
233 frodo 2 psiconv_debug(lev+2,off+len,"Identifier: %08x",(*result)->id);
234     len += 4;
235    
236     psiconv_progress(lev+2,off+len,"Going to read the application id string");
237 frodo 64 (*result)->name = psiconv_read_string(buf,lev+2,off+len,&leng,&res);
238     if (res)
239     goto ERROR2;
240 frodo 2 len += leng;
241    
242     if (length)
243     *length = len;
244    
245     psiconv_progress(lev+1,off+len-1,"End of application id section "
246     "(total length: %08x", len);
247    
248     return res;
249 frodo 64 ERROR2:
250     free(*result);
251     ERROR1:
252     psiconv_warn(lev+1,off,"Reading of Application ID Section failed");
253     if (length)
254     *length = 0;
255     if (res == 0)
256     return -PSICONV_E_NOMEM;
257     else
258     return res;
259 frodo 2 }
260    
261     int psiconv_parse_text_section(const psiconv_buffer buf,int lev,psiconv_u32 off,
262     int *length,psiconv_text_and_layout *result)
263     {
264    
265     int res = 0;
266     int len=0;
267    
268     psiconv_u32 text_len;
269     psiconv_paragraph para;
270    
271     int nr;
272 frodo 64 int i,j,start,leng,temp;
273 frodo 2 char *str_copy;
274    
275     psiconv_progress(lev+1,off,"Going to parse the text section");
276     psiconv_progress(lev+2,off,"Reading the text length");
277 frodo 64
278     if(!(*result = psiconv_list_new(sizeof(*para))))
279     goto ERROR1;
280     if (!(para = malloc(sizeof(*para))))
281     goto ERROR2;
282    
283     text_len = psiconv_read_X(buf,lev+2,off,&leng,&res);
284 frodo 65 if (res)
285 frodo 64 goto ERROR3;
286 frodo 2 psiconv_debug(lev+2,off,"Length: %08x",text_len);
287     len += leng;
288    
289     psiconv_progress(lev+2,off+len,"Going to read all paragraph text");
290     nr = 0;
291     start = 0;
292 frodo 64 for (i = 0; i < text_len; i++) {
293     temp = psiconv_read_u8(buf,lev+2,off+len+i,&res);
294     if (res)
295     goto ERROR3;
296     if (temp == 0x06) {
297     if (!(para->text = malloc(i - start + 1)))
298     goto ERROR3;
299     for (j = 0; j < i - start; j++) {
300     temp = psiconv_read_u8(buf,lev+1,off + len + start + j,&res);
301     if (res)
302     goto ERROR4;
303     para->text[j] = temp;
304     }
305 frodo 2 para->text[j] = 0;
306    
307 frodo 64 if ((res = psiconv_list_add(*result,para)))
308     goto ERROR4;
309 frodo 2
310 frodo 64 if (!(str_copy = psiconv_make_printable(para->text)))
311     goto ERROR3;
312 frodo 2 psiconv_debug(lev+2,off+i+len,"Line %d: %d characters",nr,
313     strlen(str_copy) +1);
314     psiconv_debug(lev+2,off+i+len,"Line %d: `%s'",nr,str_copy);
315     free(str_copy);
316    
317     start = i + 1;
318     nr ++;
319     }
320 frodo 64 }
321 frodo 2
322     if (start != text_len) {
323     psiconv_warn(lev+2,off+start+len,
324     "Last line does not end on EOL (%d characters left)", len - start);
325 frodo 64 if (!(para->text = malloc(text_len - start + 1)))
326     goto ERROR3;
327     for (j = 0; j < text_len - start; j++) {
328     temp = psiconv_read_u8(buf,lev+2,off + start + j + len, &res);
329     if (res)
330     goto ERROR4;
331     para->text[j] = temp;
332     }
333 frodo 2 para->text[text_len - start] = 0;
334 frodo 64 if ((res = psiconv_list_add(*result,para)))
335     goto ERROR4;
336     if (!(str_copy = psiconv_make_printable(para->text)))
337     goto ERROR3;
338 frodo 2 psiconv_debug(lev+2,off+start+len,"Last line: %d characters",nr,
339     strlen(str_copy)+1);
340     psiconv_debug(lev+2,off+start+len,"Last line: `%s'",str_copy);
341     free(str_copy);
342     }
343    
344     free(para);
345    
346     /* Initialize the remaining parts of each paragraph */
347     for (i = 0; i < psiconv_list_length(*result); i ++) {
348 frodo 64 if (!(para = psiconv_list_get(*result,i))) {
349     psiconv_warn(lev+2,off+len,"Massive memory corruption");
350     goto ERROR2_0;
351     }
352     if (!(para->in_lines = psiconv_list_new(sizeof(
353     struct psiconv_in_line_layout_s))))
354     goto ERROR2_0;
355     if (!(para->replacements = psiconv_list_new(sizeof(
356     struct psiconv_replacement_s))))
357     goto ERROR2_1;
358     if (!(para->base_character = psiconv_basic_character_layout()))
359     goto ERROR2_2;
360     if (!(para->base_paragraph = psiconv_basic_paragraph_layout()))
361     goto ERROR2_3;
362 frodo 2 para->base_style = 0;
363     }
364    
365    
366     len += text_len;
367    
368     if (length)
369     *length = len;
370    
371     psiconv_progress(lev+1,off+len-1,"End of text section (total length: %08x",
372     len);
373    
374     return res;
375 frodo 64
376     ERROR2_3:
377     psiconv_free_character_layout(para->base_character);
378     ERROR2_2:
379     psiconv_list_free(para->replacements);
380     ERROR2_1:
381     psiconv_list_free(para->in_lines);
382     ERROR2_0:
383     for (j = 0; j < i; j++) {
384     if (!(para = psiconv_list_get(*result,j))) {
385     psiconv_warn(lev+1,off,"Massive memory corruption...");
386     break;
387     }
388     psiconv_list_free(para->in_lines);
389     psiconv_list_free(para->replacements);
390     psiconv_free_character_layout(para->base_character);
391     psiconv_free_paragraph_layout(para->base_paragraph);
392     }
393     goto ERROR2;
394    
395     ERROR4:
396     free(para->text);
397     ERROR3:
398     free(para);
399     ERROR2:
400     for (i = 0; i < psiconv_list_length(*result);i++) {
401     if (!(para = psiconv_list_get(*result,i))) {
402     psiconv_warn(lev+1,off,"Massive memory corruption...");
403     break;
404     }
405     free(para->text);
406     }
407     psiconv_list_free(*result);
408     ERROR1:
409     psiconv_warn(lev+1,off,"Reading of Text Section failed");
410     if (length)
411     *length = 0;
412     if (!res)
413     return -PSICONV_E_NOMEM;
414     else
415     return res;
416 frodo 2 }
417    
418     /* First do a parse_text_section, or you will get into trouble here */
419     int psiconv_parse_layout_section(const psiconv_buffer buf,
420     int lev,psiconv_u32 off,
421     int *length,
422     psiconv_text_and_layout result,
423     psiconv_word_styles_section styles,
424     int with_styles)
425     {
426     int res = 0;
427     int len = 0;
428     psiconv_u32 temp;
429     int parse_styles,nr,i,j,total,leng,line_length;
430    
431 frodo 56 typedef struct anon_style_s
432 frodo 2 {
433     int nr;
434     psiconv_s16 base_style;
435     psiconv_character_layout character;
436     psiconv_paragraph_layout paragraph;
437     } *anon_style;
438    
439     typedef psiconv_list anon_style_list; /* of struct anon_style */
440    
441     anon_style_list anon_styles;
442 frodo 56 struct anon_style_s anon;
443 frodo 2 anon_style anon_ptr=NULL;
444    
445 frodo 64 psiconv_character_layout temp_char;
446     psiconv_paragraph_layout temp_para;
447     psiconv_word_style temp_style;
448 frodo 2 psiconv_paragraph para;
449 frodo 56 struct psiconv_in_line_layout_s in_line;
450 frodo 2
451     int *inline_count;
452    
453    
454     psiconv_progress(lev+1,off,"Going to read the layout section");
455    
456     psiconv_progress(lev+2,off,"Going to read the section type");
457 frodo 64 temp = psiconv_read_u16(buf,lev+2,off+len,&res);
458     if (res)
459     goto ERROR1;
460 frodo 2 psiconv_debug(lev+2,off+len,"Type: %02x",temp);
461     parse_styles = with_styles;
462     if ((temp == 0x0001) && !with_styles) {
463     psiconv_warn(lev+2,off+len,"Styleless layout section expected, "
464     "but styled section found!");
465     parse_styles = 1;
466     } else if ((temp == 0x0000) && (with_styles)) {
467     psiconv_warn(lev+2,off+len,"Styled layout section expected, "
468     "but styleless section found!");
469     parse_styles = 0;
470     } else if ((temp != 0x0000) && (temp != 0x0001)) {
471     psiconv_warn(lev+2,off+len,
472     "Layout section type indicator has unknown value!");
473     }
474     len += 0x02;
475    
476     psiconv_progress(lev+2,off+len,"Going to read paragraph type list");
477 frodo 64 if (!(anon_styles = psiconv_list_new(sizeof(anon))))
478     goto ERROR1;
479 frodo 2 psiconv_progress(lev+3,off+len,"Going to read paragraph type list length");
480 frodo 64 nr = psiconv_read_u8(buf,lev+3,off+len,&res);
481     if (res)
482     goto ERROR2;
483 frodo 2 psiconv_debug(lev+3,off+len,"Length: %02x",nr);
484     len ++;
485    
486     psiconv_progress(lev+3,off+len,
487     "Going to read the paragraph type list elements");
488     for (i = 0; i < nr; i ++) {
489     psiconv_progress(lev+3,off+len,"Element %d",i);
490 frodo 64 anon.nr = psiconv_read_u32(buf,lev+4,off+len,&res);
491     if (res)
492     goto ERROR3;
493 frodo 2 psiconv_debug(lev+4,off+len,"Number: %08x",anon.nr);
494     len += 0x04;
495    
496     psiconv_progress(lev+4,off,"Going to determine the base style");
497     if (parse_styles) {
498 frodo 64 temp = psiconv_read_u32(buf,lev+4, off+len,&res);
499     if (res)
500     goto ERROR3;
501     anon.base_style = psiconv_read_u8(buf,lev+3, off+len+4+temp,&res);
502     if (res)
503     goto ERROR3;
504     psiconv_debug(lev+4,off+len+temp,
505 frodo 2 "Style indicator: %02x",anon.base_style);
506     } else
507     anon.base_style = 0;
508 frodo 64 if (!(temp_style = psiconv_get_style(styles,anon.base_style))) {
509     psiconv_warn(lev+4,off,"Unknown Style referenced");
510     if (!(temp_style = psiconv_get_style(styles,anon.base_style))) {
511     psiconv_warn(lev+4,off,"Base style unknown");
512     goto ERROR3;
513     }
514     }
515     if (!(anon.paragraph = psiconv_clone_paragraph_layout
516     (temp_style->paragraph)))
517     goto ERROR3;
518     if (!(anon.character = psiconv_clone_character_layout
519     (temp_style->character)))
520     goto ERROR3_1;
521 frodo 2
522     psiconv_progress(lev+4,off+len,"Going to read the paragraph layout");
523 frodo 64 if ((res = psiconv_parse_paragraph_layout_list(buf,lev+4,off+len,&leng,
524     anon.paragraph)))
525     goto ERROR3_2;
526 frodo 2 len += leng;
527     if (parse_styles)
528     len ++;
529    
530     psiconv_progress(lev+4,off+len,"Going to read the character layout");
531 frodo 64 if ((res = psiconv_parse_character_layout_list(buf,lev+4,off+len,&leng,
532     anon.character)))
533     goto ERROR3_2;
534 frodo 2 len += leng;
535 frodo 64 if ((res = psiconv_list_add(anon_styles,&anon)))
536     goto ERROR3_2;
537 frodo 2 }
538    
539     psiconv_progress(lev+2,off+len,"Going to parse the paragraph element list");
540     psiconv_progress(lev+3,off+len,"Going to read the number of paragraphs");
541 frodo 64 nr = psiconv_read_u32(buf,lev+3,off+len,&res);
542     if (res)
543     goto ERROR3;
544 frodo 2 if (nr != psiconv_list_length(result)) {
545     psiconv_warn(lev+3,off+len,
546     "Number of text paragraphs and paragraph elements does not match");
547     psiconv_debug(lev+3,off+len,
548     "%d text paragraphs, %d paragraph elements",
549     psiconv_list_length(result),nr);
550     }
551     psiconv_debug(lev+3,off+len,"Number of paragraphs: %d",nr);
552     len += 4;
553 frodo 64 if (!(inline_count = malloc(nr * sizeof(*inline_count))))
554     goto ERROR3;
555 frodo 2
556     psiconv_progress(lev+3,off+len,"Going to read the paragraph elements");
557     for (i = 0; i < nr; i ++) {
558     psiconv_progress(lev+3,off+len,"Element %d",i);
559     if (i >= psiconv_list_length(result)) {
560     psiconv_debug(lev+4,off+len,"Going to allocate a new element");
561 frodo 64 if (!(para = malloc(sizeof(*para))))
562     goto ERROR4;
563     if (!(para->in_lines = psiconv_list_new(sizeof(
564     struct psiconv_in_line_layout_s))))
565     goto ERROR4_1;
566 frodo 2 para->base_style = 0;
567 frodo 64 if (!(para->base_character = psiconv_basic_character_layout()))
568     goto ERROR4_2;
569     if (!(para->base_paragraph = psiconv_basic_paragraph_layout()))
570     goto ERROR4_3;
571     if ((res = psiconv_list_add(result,para)))
572     goto ERROR4_4;
573 frodo 2 free(para);
574     }
575 frodo 64 if (!(para = psiconv_list_get(result,i)))
576     goto ERROR4;
577 frodo 2
578     psiconv_progress(lev+4,off+len,"Going to read the paragraph length");
579 frodo 64 temp = psiconv_read_u32(buf,lev+4,off+len,&res);
580 frodo 65 if (res)
581 frodo 64 goto ERROR4;
582 frodo 2 if (temp != strlen(para->text)+1) {
583     psiconv_warn(lev+4,off+len,
584     "Disagreement of the length of paragraph in layout section");
585     psiconv_debug(lev+4,off+len,
586     "Paragraph length: layout section says %d, counted %d",
587     temp,strlen(para->text)+1);
588     } else
589     psiconv_debug(lev+4,off+len,"Paragraph length: %d",temp);
590     len += 4;
591    
592     psiconv_progress(lev+4,off+len,"Going to read the paragraph type");
593 frodo 64 temp = psiconv_read_u8(buf,lev+4,off+len,&res);
594 frodo 65 if (res)
595 frodo 64 goto ERROR4;
596 frodo 2 if (temp != 0x00) {
597     psiconv_debug(lev+4,off+len,"Type: %02x",temp);
598     for (j = 0; j < psiconv_list_length(anon_styles); j++) {
599 frodo 64 if (!(anon_ptr = psiconv_list_get(anon_styles,j))) {
600     psiconv_warn(lev+4,off+len,"Massive memory curruption");
601     goto ERROR4;
602     }
603 frodo 2 if (temp == anon_ptr->nr)
604     break;
605     }
606     if (j == psiconv_list_length(anon_styles)) {
607     psiconv_warn(lev+4,off+len,"Layout section paragraph type unknown");
608     psiconv_debug(lev+4,off+len,"Unknown type - using base styles instead");
609     para->base_style = 0;
610 frodo 64 if (!(temp_style = psiconv_get_style(styles,0))) {
611     psiconv_warn(lev+4,off,"Base style unknown");
612     goto ERROR4;
613     }
614     if (!(temp_para = psiconv_clone_paragraph_layout
615     (temp_style->paragraph)))
616     goto ERROR4;
617 frodo 2 psiconv_free_paragraph_layout(para->base_paragraph);
618 frodo 64 para->base_paragraph = temp_para;
619    
620     if (!(temp_char = psiconv_clone_character_layout
621     (temp_style->character)))
622     goto ERROR4;
623 frodo 2 psiconv_free_character_layout(para->base_character);
624 frodo 64 para->base_character = temp_char;
625 frodo 2 } else {
626     para->base_style = anon_ptr->base_style;
627 frodo 64 if (!(temp_para = psiconv_clone_paragraph_layout (anon_ptr->paragraph)))
628     goto ERROR4;
629 frodo 2 psiconv_free_paragraph_layout(para->base_paragraph);
630 frodo 64 para->base_paragraph = temp_para;
631    
632     if (!(temp_char = psiconv_clone_character_layout (anon_ptr->character)))
633     goto ERROR4;
634 frodo 2 psiconv_free_character_layout(para->base_character);
635 frodo 64 para->base_character = temp_char;
636 frodo 2 }
637     inline_count[i] = 0;
638     len += 0x01;
639     } else {
640     psiconv_debug(lev+4,off+len,"Type: %02x (not based on a paragraph type)"
641     ,temp);
642     len += 0x01;
643     if (parse_styles) {
644 frodo 64 temp = psiconv_read_u32(buf,lev+4,off+len,&res);
645     if (res)
646     goto ERROR4;
647     psiconv_progress(lev+4,off+len+temp+4,
648 frodo 2 "Going to read the paragraph element base style");
649 frodo 64 temp = psiconv_read_u8(buf,lev+4, off+len+temp+4,&res);
650     if (res)
651     goto ERROR4;
652     psiconv_debug(lev+4,off+len+temp+4, "Style: %02x",temp);
653 frodo 2 } else
654     temp = 0x00;
655 frodo 64
656     if (!(temp_style = psiconv_get_style (styles,temp))) {
657     psiconv_warn(lev+4,off,"Unknown Style referenced");
658     if (!(temp_style = psiconv_get_style(styles,0))) {
659     psiconv_warn(lev+4,off,"Base style unknown");
660     goto ERROR4;
661     }
662     }
663    
664     if (!(temp_para = psiconv_clone_paragraph_layout(temp_style->paragraph)))
665     goto ERROR4;
666 frodo 2 psiconv_free_paragraph_layout(para->base_paragraph);
667 frodo 64 para->base_paragraph = temp_para;
668    
669     if (!(temp_char = psiconv_clone_character_layout(temp_style->character)))
670     goto ERROR4;
671 frodo 2 psiconv_free_character_layout(para->base_character);
672 frodo 64 para->base_character = temp_char;
673    
674 frodo 2 para->base_style = temp;
675     psiconv_progress(lev+4,off+len,"Going to read paragraph layout");
676 frodo 65 if ((res = psiconv_parse_paragraph_layout_list(buf,lev+4,off+len,&leng,
677 frodo 64 para->base_paragraph)))
678     goto ERROR4;
679 frodo 2 len += leng;
680     if (parse_styles)
681     len += 1;
682     psiconv_progress(lev+4,off+len,"Going to read number of in-line "
683     "layout elements");
684 frodo 64 inline_count[i] = psiconv_read_u32(buf,lev+4,off+len,&res);
685     if (res)
686     goto ERROR4;
687 frodo 2 psiconv_debug(lev+4,off+len,"Nr: %08x",inline_count[i]);
688     len += 4;
689     }
690     }
691    
692     psiconv_progress(lev+2,off+len,"Going to read the text layout inline list");
693    
694     psiconv_progress(lev+3,off+len,"Going to read the number of elements");
695 frodo 64 nr = psiconv_read_u32(buf,lev+3,off+len,&res);
696     if (res)
697     goto ERROR4;
698 frodo 65 psiconv_debug(lev+3,off+len,"Elements: %08x",nr);
699 frodo 2 len += 0x04;
700    
701     psiconv_progress(lev+3,off+len,
702     "Going to read the text layout inline elements");
703     total = 0;
704     for (i = 0; i < psiconv_list_length(result); i++) {
705 frodo 64 if (!(para = psiconv_list_get(result,i))) {
706     psiconv_warn(lev+3,off+len,"Massive memory corruption");
707     goto ERROR4;
708     }
709 frodo 2 line_length = -1;
710     for (j = 0; j < inline_count[i]; j++) {
711     psiconv_progress(lev+3,off+len,"Element %d: Paragraph %d, element %d",
712     total,i,j);
713     if (total >= nr) {
714     psiconv_warn(lev+3,off+len,
715     "Layout section inlines: not enough element");
716     psiconv_debug(lev+3,off+len,"Can't read element!");
717     } else {
718     total ++;
719 frodo 159 in_line.object = NULL;
720 frodo 160 in_line.layout = NULL;
721 frodo 64 if (!(in_line.layout = psiconv_clone_character_layout
722     (para->base_character)))
723     goto ERROR4;
724 frodo 2 psiconv_progress(lev+4,off+len,"Going to read the element type");
725 frodo 64 temp = psiconv_read_u8(buf,lev+4,len+off,&res);
726     if (res)
727 frodo 160 goto ERROR5;
728 frodo 2 len += 1;
729 frodo 70 psiconv_debug(lev+4,off+len,"Type: %02x",temp);
730     psiconv_progress(lev+4,off+len,
731 frodo 64 "Going to read the number of characters it applies to");
732     in_line.length = psiconv_read_u32(buf,lev+4,len+off,&res);
733     if (res)
734 frodo 160 goto ERROR5;
735 frodo 2 psiconv_debug(lev+4,off+len,"Length: %02x",in_line.length);
736     len += 4;
737     psiconv_progress(lev+4,off+len,"Going to read the character layout");
738 frodo 64 if ((res = psiconv_parse_character_layout_list(buf,lev+4,off+len,&leng,
739     in_line.layout)))
740 frodo 160 goto ERROR5;
741 frodo 2 len += leng;
742    
743     if (temp == 0x01) {
744 frodo 160 psiconv_debug(lev+4,off+len,"Found an embedded object");
745     psiconv_progress(lev+4,off+len,"Going to read the object marker "
746     "(0x%08x expected)",PSICONV_ID_OBJECT);
747     temp = psiconv_read_u32(buf,lev+4,off+len,&res);
748     if (res)
749     goto ERROR5;
750     if (temp != PSICONV_ID_OBJECT) {
751     psiconv_warn(lev+4,off+len,"Unknown id marks embedded object");
752     psiconv_debug(lev+4,off+len,"Marker: read %08x, expected %08x",
753     temp,PSICONV_ID_OBJECT);
754     }
755     len += 4;
756     psiconv_progress(lev+4,off+len,
757     "Going to read the Embedded Object Section offset");
758     temp = psiconv_read_u32(buf,lev+4,off+len,&res);
759     if (res)
760     goto ERROR5;
761     psiconv_debug(lev+4,off+len, "Offset: %08x",temp);
762     len += 4;
763     psiconv_progress(lev+4,off+len,
764     "Going to parse the Embedded Object");
765     if ((res = psiconv_parse_embedded_object(buf,lev+4,temp,
766     NULL,&(in_line.object))))
767     goto ERROR5;
768     psiconv_progress(lev+4,off+len,
769     "Going to read the object width");
770     in_line.object_width = psiconv_read_length(buf,lev+4,off+len,
771     &leng,&res);
772     if (res)
773     goto ERROR5;
774     psiconv_debug(lev+4,off+len,"Object width: %f cm",
775     in_line.object_width);
776     len += leng;
777     psiconv_progress(lev+4,off+len,
778     "Going to read the object height");
779     in_line.object_height = psiconv_read_length(buf,lev+4,off+len,&leng,
780     &res);
781     if (res)
782     goto ERROR5;
783     psiconv_debug(lev+4,off+len,"Object height: %f cm",
784     in_line.object_height);
785     len += leng;
786 frodo 2 } else if (temp != 0x00) {
787     psiconv_warn(lev+4,off+len,"Layout section unknown inline type");
788     }
789     if (line_length + in_line.length > strlen(para->text)) {
790     psiconv_warn(lev+4,off+len,
791     "Layout section inlines: line length mismatch");
792     res = -1;
793     in_line.length = strlen(para->text) - line_length;
794     }
795     line_length += in_line.length;
796 frodo 64 if ((res = psiconv_list_add(para->in_lines,&in_line)))
797 frodo 160 goto ERROR5;
798 frodo 2 }
799     }
800     }
801    
802     if (total != nr) {
803     psiconv_warn(lev+4,off+len,
804     "Layout section too many inlines, skipping remaining");
805     }
806    
807     free(inline_count);
808    
809     for (i = 0 ; i < psiconv_list_length(anon_styles); i ++) {
810 frodo 64 if (!(anon_ptr = psiconv_list_get(anon_styles,i))) {
811     psiconv_warn(lev+4,off+len,"Massive memory corruption");
812     goto ERROR2;
813     }
814 frodo 2 psiconv_free_character_layout(anon_ptr->character);
815     psiconv_free_paragraph_layout(anon_ptr->paragraph);
816     }
817     psiconv_list_free(anon_styles);
818    
819     if (length)
820     *length = len;
821    
822 frodo 70 psiconv_progress(lev+1,off+len-1,"End of layout section (total length: %08x)",
823 frodo 2 len);
824    
825 frodo 64 return 0;
826    
827     ERROR4_4:
828     psiconv_free_paragraph_layout(para->base_paragraph);
829     ERROR4_3:
830     psiconv_free_character_layout(para->base_character);
831     ERROR4_2:
832     psiconv_list_free(para->in_lines);
833     ERROR4_1:
834     free(para);
835     goto ERROR4;
836    
837     ERROR3_2:
838     psiconv_free_character_layout(anon.character);
839     ERROR3_1:
840     psiconv_free_paragraph_layout(anon.paragraph);
841     goto ERROR3;
842    
843 frodo 160 ERROR5:
844     if (in_line.layout)
845     psiconv_free_character_layout(in_line.layout);
846     if (in_line.object)
847     psiconv_free_object(in_line.object);
848 frodo 64 ERROR4:
849     free(inline_count);
850     ERROR3:
851     for (i = 0; i < psiconv_list_length(anon_styles); i++) {
852     if (!(anon_ptr = psiconv_list_get(anon_styles,i))) {
853     psiconv_warn(lev+1,off,"Massive memory corruption");
854     break;
855     }
856     psiconv_free_paragraph_layout(anon_ptr->paragraph);
857     psiconv_free_character_layout(anon_ptr->character);
858     }
859    
860     ERROR2:
861     psiconv_list_free(anon_styles);
862     ERROR1:
863     psiconv_warn(lev+1,off,"Reading of Layout Section failed");
864     if (length)
865     *length = 0;
866     if (!res)
867     return -PSICONV_E_NOMEM;
868     else
869     return res;
870 frodo 2 }
871    
872     int psiconv_parse_styled_layout_section(const psiconv_buffer buf,
873     int lev,psiconv_u32 off,
874     int *length,
875     psiconv_text_and_layout result,
876     psiconv_word_styles_section styles)
877     {
878     return psiconv_parse_layout_section(buf,lev,off,length,result,styles,1);
879     }
880    
881     int psiconv_parse_styleless_layout_section(const psiconv_buffer buf,
882 frodo 79 int lev,psiconv_u32 off,
883     int *length,
884     psiconv_text_and_layout result,
885     const psiconv_character_layout base_char,
886     const psiconv_paragraph_layout base_para)
887 frodo 2 {
888 frodo 64 int res = 0;
889 frodo 2 psiconv_word_styles_section styles_section;
890    
891 frodo 64 if (!(styles_section = malloc(sizeof(*styles_section))))
892     goto ERROR1;
893     if (!(styles_section->normal = malloc(sizeof(*styles_section->normal))))
894     goto ERROR2;
895     if (!(styles_section->normal->character =
896     psiconv_clone_character_layout(base_char)))
897     goto ERROR3;
898     if (!(styles_section->normal->paragraph =
899     psiconv_clone_paragraph_layout(base_para)))
900     goto ERROR4;
901 frodo 2 styles_section->normal->hotkey = 0;
902 frodo 64 if (!(styles_section->normal->name = strdup("")))
903     goto ERROR5;
904     if (!(styles_section->styles = psiconv_list_new(sizeof(
905     struct psiconv_word_style_s))))
906     goto ERROR6;
907 frodo 2
908     res = psiconv_parse_layout_section(buf,lev,off,length,result,
909     styles_section,0);
910    
911     psiconv_free_word_styles_section(styles_section);
912     return res;
913 frodo 64
914     ERROR6:
915     free(styles_section->normal->name);
916     ERROR5:
917     psiconv_free_paragraph_layout(styles_section->normal->paragraph);
918     ERROR4:
919     psiconv_free_character_layout(styles_section->normal->character);
920     ERROR3:
921     free(styles_section->normal);
922     ERROR2:
923     free(styles_section);
924     ERROR1:
925     psiconv_warn(lev+1,off,"Reading of Styleless Layout Section failed");
926     if (length)
927     *length = 0;
928     if (!res)
929     return -PSICONV_E_NOMEM;
930     else
931     return res;
932 frodo 2 }
933    
934 frodo 160 int psiconv_parse_embedded_object(const psiconv_buffer buf, int lev,
935     psiconv_u32 off, int *length,
936     psiconv_object *result)
937     {
938     int res=0;
939     int len=0;
940     int leng,i;
941     psiconv_section_table_section table;
942     psiconv_section_table_entry entry;
943 frodo 161 psiconv_u32 icon_sec=0,display_sec=0,table_sec=0;
944 frodo 160
945     psiconv_progress(lev+1,off+len,"Going to read an Embedded Object");
946     if (!(*result = malloc(sizeof(**result))))
947     goto ERROR1;
948    
949     psiconv_progress(lev+2,off+len,"Going to read the Embedded Object Section");
950     psiconv_parse_section_table_section(buf,lev+2,off+len,&leng,&table);
951     len += leng;
952    
953     for (i = 0; i < psiconv_list_length(table); i++) {
954     psiconv_progress(lev+2,off+len,"Going to read entry %d",i);
955     if (!(entry = psiconv_list_get(table,i)))
956     goto ERROR2;
957     if (entry->id == PSICONV_ID_OBJECT_DISPLAY_SECTION) {
958     display_sec = entry->offset;
959     psiconv_debug(lev+3,off+len,"Found the Object Display Section at %08x",
960     display_sec);
961     } else if (entry->id == PSICONV_ID_OBJECT_ICON_SECTION) {
962     icon_sec = entry->offset;
963     psiconv_debug(lev+3,off+len,"Found the Object Icon Section at %08x",
964     icon_sec);
965     } else if (entry->id == PSICONV_ID_OBJECT_SECTION_TABLE_SECTION) {
966     table_sec = entry->offset;
967     psiconv_debug(lev+3,off+len,"Found the Object Section Table Section at %08x",
968     table_sec);
969     } else {
970     psiconv_warn(lev+3,off+len,
971     "Found unknown section in the Object Display Section "
972     "(ignoring)");
973     psiconv_debug(lev+3,off+len,"Section ID %08x, offset %08x",
974     entry->id, entry->offset);
975     }
976     }
977    
978 frodo 161 psiconv_progress(lev+2,off+len,"Looking for the Object Display Section");
979     if (!icon_sec) {
980     psiconv_warn(lev+2,off+len,"Object Display Section not found");
981     (*result)->display = NULL;
982     } else {
983     psiconv_debug(lev+2,off+len,"Object Display Section at offset %08x",
984     display_sec);
985     if ((res = psiconv_parse_object_display_section(buf,lev+2,display_sec,NULL,
986     &(*result)->display)))
987     goto ERROR2;
988     }
989    
990     psiconv_progress(lev+2,off+len,"Looking for the Object Icon Section");
991     if (!icon_sec) {
992     psiconv_warn(lev+2,off+len,"Object Icon Section not found");
993     (*result)->icon = NULL;
994     } else {
995     psiconv_debug(lev+2,off+len,"Object Icon Section at offset %08x",icon_sec);
996     if ((res = psiconv_parse_object_icon_section(buf,lev+2,icon_sec,NULL,
997     &(*result)->icon)))
998     goto ERROR2;
999     }
1000    
1001     if (length)
1002     *length = len;
1003    
1004 frodo 160 psiconv_progress(lev+1,off+len-1,"End of Embedded Object Section "
1005     "(total length: %08x)",len);
1006 frodo 161
1007 frodo 160 return res;
1008    
1009    
1010     ERROR2:
1011     psiconv_free_section_table_section(table);
1012     ERROR1:
1013     psiconv_warn(lev+1,off,"Reading Embedded Object failed");
1014 frodo 161
1015 frodo 160 if (length)
1016     *length = 0;
1017 frodo 161
1018 frodo 160 if (res == 0)
1019     return -PSICONV_E_NOMEM;
1020     else
1021     return res;
1022     }
1023 frodo 161
1024     int psiconv_parse_object_display_section(const psiconv_buffer buf,int lev,
1025     psiconv_u32 off, int *length,
1026     psiconv_object_display_section *result)
1027     {
1028     int res = 0;
1029     int len = 0;
1030     int leng;
1031     psiconv_u32 temp;
1032    
1033     psiconv_progress(lev+1,off,"Going to read the Object Display Section");
1034     if (!(*result = malloc(sizeof(**result))))
1035     goto ERROR1;
1036    
1037     psiconv_progress(lev+2,off+len,"Going to read the display as icon flag "
1038     "(expecting 0x00 or 0x01)");
1039     temp = psiconv_read_u8(buf,lev+2,off+len,&res);
1040     if (res)
1041     goto ERROR2;
1042     if (temp == 0x00) {
1043     (*result)->show_icon = psiconv_bool_true;
1044     psiconv_debug(lev+2,off+len,"Displayed as full document");
1045     } else if (temp == 0x01) {
1046     (*result)->show_icon = psiconv_bool_false;
1047     psiconv_debug(lev+2,off+len,"Displayed as icon");
1048     } else {
1049     psiconv_warn(lev+2,off+len,"Unknown Object Display Section Icon Flag");
1050     psiconv_debug(lev+2,off+len,"Icon flag found: %02x",temp);
1051     /* Improvise */
1052     (*result)->show_icon = (temp & 0x01?psiconv_bool_false:psiconv_bool_true);
1053     }
1054     len ++;
1055    
1056     psiconv_progress(lev+2,off+len,"Going to read the icon width");
1057     (*result)->width = psiconv_read_length(buf,lev+2,off+len,&leng,&res);
1058     if (res)
1059     goto ERROR2;
1060     psiconv_debug(lev+2,off+len,"Icon width: %f cm",(*result)->width);
1061     len += leng;
1062    
1063     psiconv_progress(lev+2,off+len,"Going to read the icon height");
1064     (*result)->height = psiconv_read_length(buf,lev+2,off+len,&leng,&res);
1065     if (res)
1066     goto ERROR2;
1067     psiconv_debug(lev+2,off+len,"Icon length: %f cm",(*result)->height);
1068     len += leng;
1069    
1070     psiconv_progress(lev+2,off+len,"Going to read unknown long (%08x expected)",
1071     0);
1072     temp = psiconv_read_u32(buf,lev+2,off+len,&res);
1073     if (temp != 0) {
1074     psiconv_warn(lev+2,off+len,"Unknown Object Display Section final long");
1075     psiconv_debug(lev+2,off+len,"Long read: %08x",temp);
1076     }
1077     len += 4;
1078    
1079     if (length)
1080     *length = len;
1081    
1082     psiconv_progress(lev+1,off+len-1,"End of Object Display Section"
1083     "(total length: %08x",len);
1084     return res;
1085    
1086     ERROR2:
1087     free(*result);
1088     ERROR1:
1089     psiconv_warn(lev+1,off+len,"Reading of Object Display Section failed");
1090     if (length)
1091     *length=0;
1092     if (!res)
1093     return -PSICONV_E_NOMEM;
1094     else
1095     return res;
1096     }
1097    
1098     int psiconv_parse_object_icon_section(const psiconv_buffer buf,int lev,
1099     psiconv_u32 off, int *length,
1100     psiconv_object_icon_section *result)
1101     {
1102     int res = 0;
1103     int len = 0;
1104     int leng;
1105    
1106     psiconv_progress(lev+1,off,"Going to read the Object Icon Section");
1107     if (!(*result = malloc(sizeof(**result))))
1108     goto ERROR1;
1109    
1110     psiconv_progress(lev+2,off+len,"Going to read the icon name");
1111     (*result)->icon_name = psiconv_read_string(buf,lev+2,off+len,&leng,&res);
1112     if (res)
1113     goto ERROR2;
1114     psiconv_debug(lev+2,off+len,"Icon name: %s",(*result)->icon_name);
1115     len += leng;
1116    
1117     psiconv_progress(lev+2,off+len,"Going to read the icon width");
1118     (*result)->icon_width = psiconv_read_length(buf,lev+2,off+len,&leng,&res);
1119     if (res)
1120     goto ERROR3;
1121     psiconv_debug(lev+2,off+len,"Icon width: %f cm",(*result)->icon_width);
1122     len += leng;
1123    
1124     psiconv_progress(lev+2,off+len,"Going to read the icon height");
1125     (*result)->icon_height = psiconv_read_length(buf,lev+2,off+len,&leng,&res);
1126     if (res)
1127     goto ERROR3;
1128     psiconv_debug(lev+2,off+len,"Icon length: %f cm",(*result)->icon_height);
1129     len += leng;
1130    
1131     if (length)
1132     *length = len;
1133    
1134     psiconv_progress(lev+1,off+len-1,"End of Object Icon Section"
1135     "(total length: %08x",len);
1136     return res;
1137    
1138     ERROR3:
1139     free((*result)->icon_name);
1140     ERROR2:
1141     free(*result);
1142     ERROR1:
1143     psiconv_warn(lev+1,off+len,"Reading of Object Icon Section failed");
1144     if (length)
1145     *length=0;
1146     if (!res)
1147     return -PSICONV_E_NOMEM;
1148     else
1149     return res;
1150     }

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