/[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 65 - (hide annotations)
Fri Dec 15 01:16:43 2000 UTC (23 years, 3 months ago) by frodo
File MIME type: text/plain
File size: 28817 byte(s)
(Frodo) First typos eliminated. Word files seem to work now. Need to test
        other types.

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 "data.h"
26     #include "parse_routines.h"
27    
28     static int psiconv_parse_layout_section(const psiconv_buffer buf,
29     int lev,psiconv_u32 off,
30     int *length,
31     psiconv_text_and_layout result,
32     psiconv_word_styles_section styles,
33     int with_styles);
34    
35     int psiconv_parse_header_section(const psiconv_buffer buf,int lev,
36     psiconv_u32 off, int *length,
37     psiconv_header_section *result)
38     {
39     int res=0;
40     int len=0;
41     psiconv_u32 temp;
42    
43     psiconv_progress(lev+1,off+len,"Going to read the header section");
44 frodo 64 if (!((*result) = malloc(sizeof(**result))))
45     goto ERROR1;
46 frodo 2
47     psiconv_progress(lev+2,off+len,"Going to read UID1 to UID3");
48 frodo 64 (*result)->uid1 = psiconv_read_u32(buf,lev+2,off+len,&res);
49 frodo 65 if (res)
50 frodo 64 goto ERROR2;
51 frodo 2 psiconv_debug(lev+2,off+len,"UID1: %08x",(*result)->uid1);
52 frodo 41 if ((*result)->uid1 == PSICONV_ID_CLIPART) {
53     /* That's all folks... */
54     (*result)->file = psiconv_clipart_file;
55     (*result)->uid2 = 0;
56     (*result)->uid3 = 0;
57     (*result)->checksum = 0;
58     len += 4;
59 frodo 43 psiconv_debug(lev+2,off+len,"File is a Clipart file");
60 frodo 41 goto DONE;
61     }
62 frodo 2 if ((*result)->uid1 != PSICONV_ID_PSION5) {
63     psiconv_warn(lev+2,off+len,"UID1 has unknown value. This is probably "
64     "not a (parsable) Psion 5 file");
65 frodo 64 res = -PSICONV_E_PARSE;
66     goto ERROR2;
67 frodo 2 }
68     len += 4;
69 frodo 64 (*result)->uid2 = psiconv_read_u32(buf,lev+2,off+len,&res);
70     if (res)
71     goto ERROR2;
72 frodo 2 psiconv_debug(lev+2,off+len,"UID2: %08x",(*result)->uid2);
73     len += 4;
74 frodo 64 (*result)->uid3 = psiconv_read_u32(buf,lev+2,off+len,&res);
75     if (res)
76     goto ERROR2;
77 frodo 2 psiconv_debug(lev+2,off+len,"UID3: %08x",(*result)->uid3);
78     len += 4;
79    
80     (*result)->file = psiconv_unknown_file;
81     if ((*result)->uid1 == PSICONV_ID_PSION5) {
82     if ((*result)->uid2 == PSICONV_ID_DATA_FILE) {
83     if ((*result)->uid3 == PSICONV_ID_WORD) {
84     (*result)->file = psiconv_word_file;
85     psiconv_debug(lev+2,off+len,"File is a Word file");
86     } else if ((*result)->uid3 == PSICONV_ID_TEXTED) {
87     (*result)->file = psiconv_texted_file;
88     psiconv_debug(lev+2,off+len,"File is a TextEd file");
89 frodo 24 } else if ((*result)->uid3 == PSICONV_ID_SKETCH) {
90     (*result)->file = psiconv_sketch_file;
91     psiconv_debug(lev+2,off+len,"File is a Sketch file");
92     }
93 frodo 12 } else if ((*result)->uid2 == PSICONV_ID_MBM_FILE) {
94     (*result)->file = psiconv_mbm_file;
95     if ((*result)->uid3 != 0x00)
96     psiconv_warn(lev+2,off+len,"UID3 set in MBM file?!?");
97     psiconv_debug(lev+2,off+len,"File is a MBM file");
98     }
99 frodo 2 }
100     if ((*result)->file == psiconv_unknown_file) {
101     psiconv_warn(lev+2,off+len,"Unknown file type");
102     (*result)->file = psiconv_unknown_file;
103     }
104    
105     psiconv_progress(lev+2,off+len,"Checking UID4");
106 frodo 64 temp = psiconv_read_u32(buf,lev+2,off+len,&res);
107     if (res)
108     goto ERROR2;
109 frodo 2 if (temp == psiconv_checkuid((*result)->uid1,(*result)->uid2,
110     (*result)->uid3))
111     psiconv_debug(lev+2,off+len,"Checksum %08x is correct",temp);
112     else {
113     psiconv_warn(lev+2,off+len,"Checksum failed, file corrupted!");
114     psiconv_debug(lev+2,off+len,"Expected checksum %08x, found %08x",
115     psiconv_checkuid((*result)->uid1,(*result)->uid2,
116     (*result)->uid3),temp);
117 frodo 64 res = -PSICONV_E_PARSE;
118     goto ERROR2;
119 frodo 2 }
120     len += 4;
121 frodo 41
122     DONE:
123 frodo 2 if (length)
124     *length = len;
125    
126     psiconv_progress(lev+1,off+len-1,
127     "End of Header Section (total length: %08x)",len);
128    
129     return res;
130 frodo 64
131     ERROR2:
132     free(*result);
133     ERROR1:
134     psiconv_warn(lev+1,off,"Reading of Header Section failed");
135     if (length)
136     *length = 0;
137     if (res == 0)
138     return -PSICONV_E_NOMEM;
139     else
140     return res;
141 frodo 2 }
142    
143     int psiconv_parse_section_table_section(const psiconv_buffer buf, int lev,
144     psiconv_u32 off, int *length,
145     psiconv_section_table_section *result)
146     {
147     int res=0;
148     int len=0;
149     psiconv_section_table_entry entry;
150    
151     int i;
152     psiconv_u8 nr;
153    
154     psiconv_progress(lev+1,off+len,"Going to read the section table section");
155 frodo 64 if (!(*result = psiconv_list_new(sizeof(*entry))))
156     goto ERROR1;
157 frodo 2
158     psiconv_progress(lev+2,off+len,"Going to read the section table length");
159 frodo 64 nr = psiconv_read_u8(buf,lev+2,off+len,&res);
160     if (res)
161     goto ERROR2;
162 frodo 2 psiconv_debug(lev+2,off+len,"Length: %08x",nr);
163     if (nr & 0x01) {
164     psiconv_warn(lev+2,off+len,
165     "Section table length odd - ignoring last entry");
166     }
167     len ++;
168    
169     psiconv_progress(lev+2,off+len,"Going to read the section table entries");
170     entry = malloc(sizeof(*entry));
171     for (i = 0; i < nr / 2; i++) {
172 frodo 64 entry->id = psiconv_read_u32(buf,lev+2,off + len,&res);
173     if (res)
174     goto ERROR3;
175 frodo 2 psiconv_debug(lev+2,off + len,"Entry %d: ID = %08x",i,entry->id);
176     len += 0x04;
177 frodo 64 entry->offset = psiconv_read_u32(buf,lev+2,off + len,&res);
178     if (res)
179     goto ERROR3;
180 frodo 2 psiconv_debug(lev+2,off +len,"Entry %d: Offset = %08x",i,entry->offset);
181     len += 0x04;
182 frodo 64 if ((res=psiconv_list_add(*result,entry)))
183     goto ERROR3;
184 frodo 2 }
185    
186     free(entry);
187    
188     if (length)
189     *length = len;
190    
191     psiconv_progress(lev+1,off+len-1,"End of section table section "
192 frodo 25 "(total length: %08x)", len);
193 frodo 2
194 frodo 64 return 0;
195     ERROR3:
196     free(entry);
197     ERROR2:
198     psiconv_list_free(*result);
199     ERROR1:
200     psiconv_warn(lev+1,off,"Reading of Section Table Section failed");
201     if (length)
202     *length = 0;
203     if (res == 0)
204     return -PSICONV_E_NOMEM;
205     else
206     return res;
207 frodo 2 }
208    
209     int psiconv_parse_application_id_section(const psiconv_buffer buf, int lev,
210     psiconv_u32 off, int *length,
211     psiconv_application_id_section *result)
212     {
213     int res=0;
214     int len=0;
215     int leng;
216    
217     psiconv_progress(lev+1,off,"Going to read the application id section");
218 frodo 64 if (!(*result = malloc(sizeof(**result))))
219     goto ERROR1;
220 frodo 2
221     psiconv_progress(lev+2,off+len,"Going to read the type identifier");
222 frodo 64 (*result)->id = psiconv_read_u32(buf,lev+2,off+len,&res);
223     if (res)
224     goto ERROR2;
225 frodo 2 psiconv_debug(lev+2,off+len,"Identifier: %08x",(*result)->id);
226     len += 4;
227    
228     psiconv_progress(lev+2,off+len,"Going to read the application id string");
229 frodo 64 (*result)->name = psiconv_read_string(buf,lev+2,off+len,&leng,&res);
230     if (res)
231     goto ERROR2;
232 frodo 2 len += leng;
233    
234     if (length)
235     *length = len;
236    
237     psiconv_progress(lev+1,off+len-1,"End of application id section "
238     "(total length: %08x", len);
239    
240     return res;
241 frodo 64 ERROR2:
242     free(*result);
243     ERROR1:
244     psiconv_warn(lev+1,off,"Reading of Application ID Section failed");
245     if (length)
246     *length = 0;
247     if (res == 0)
248     return -PSICONV_E_NOMEM;
249     else
250     return res;
251 frodo 2 }
252    
253     int psiconv_parse_text_section(const psiconv_buffer buf,int lev,psiconv_u32 off,
254     int *length,psiconv_text_and_layout *result)
255     {
256    
257     int res = 0;
258     int len=0;
259    
260     psiconv_u32 text_len;
261     psiconv_paragraph para;
262    
263     int nr;
264 frodo 64 int i,j,start,leng,temp;
265 frodo 2 char *str_copy;
266    
267     psiconv_progress(lev+1,off,"Going to parse the text section");
268     psiconv_progress(lev+2,off,"Reading the text length");
269 frodo 64
270     if(!(*result = psiconv_list_new(sizeof(*para))))
271     goto ERROR1;
272     if (!(para = malloc(sizeof(*para))))
273     goto ERROR2;
274    
275     text_len = psiconv_read_X(buf,lev+2,off,&leng,&res);
276 frodo 65 if (res)
277 frodo 64 goto ERROR3;
278 frodo 2 psiconv_debug(lev+2,off,"Length: %08x",text_len);
279     len += leng;
280    
281     psiconv_progress(lev+2,off+len,"Going to read all paragraph text");
282     nr = 0;
283     start = 0;
284 frodo 64 for (i = 0; i < text_len; i++) {
285     temp = psiconv_read_u8(buf,lev+2,off+len+i,&res);
286     if (res)
287     goto ERROR3;
288     if (temp == 0x06) {
289     if (!(para->text = malloc(i - start + 1)))
290     goto ERROR3;
291     for (j = 0; j < i - start; j++) {
292     temp = psiconv_read_u8(buf,lev+1,off + len + start + j,&res);
293     if (res)
294     goto ERROR4;
295     para->text[j] = temp;
296     }
297 frodo 2 para->text[j] = 0;
298    
299 frodo 64 if ((res = psiconv_list_add(*result,para)))
300     goto ERROR4;
301 frodo 2
302 frodo 64 if (!(str_copy = psiconv_make_printable(para->text)))
303     goto ERROR3;
304 frodo 2 psiconv_debug(lev+2,off+i+len,"Line %d: %d characters",nr,
305     strlen(str_copy) +1);
306     psiconv_debug(lev+2,off+i+len,"Line %d: `%s'",nr,str_copy);
307     free(str_copy);
308    
309     start = i + 1;
310     nr ++;
311     }
312 frodo 64 }
313 frodo 2
314     if (start != text_len) {
315     psiconv_warn(lev+2,off+start+len,
316     "Last line does not end on EOL (%d characters left)", len - start);
317 frodo 64 if (!(para->text = malloc(text_len - start + 1)))
318     goto ERROR3;
319     for (j = 0; j < text_len - start; j++) {
320     temp = psiconv_read_u8(buf,lev+2,off + start + j + len, &res);
321     if (res)
322     goto ERROR4;
323     para->text[j] = temp;
324     }
325 frodo 2 para->text[text_len - start] = 0;
326 frodo 64 if ((res = psiconv_list_add(*result,para)))
327     goto ERROR4;
328     if (!(str_copy = psiconv_make_printable(para->text)))
329     goto ERROR3;
330 frodo 2 psiconv_debug(lev+2,off+start+len,"Last line: %d characters",nr,
331     strlen(str_copy)+1);
332     psiconv_debug(lev+2,off+start+len,"Last line: `%s'",str_copy);
333     free(str_copy);
334     }
335    
336     free(para);
337    
338     /* Initialize the remaining parts of each paragraph */
339     for (i = 0; i < psiconv_list_length(*result); i ++) {
340 frodo 64 if (!(para = psiconv_list_get(*result,i))) {
341     psiconv_warn(lev+2,off+len,"Massive memory corruption");
342     goto ERROR2_0;
343     }
344     if (!(para->in_lines = psiconv_list_new(sizeof(
345     struct psiconv_in_line_layout_s))))
346     goto ERROR2_0;
347     if (!(para->replacements = psiconv_list_new(sizeof(
348     struct psiconv_replacement_s))))
349     goto ERROR2_1;
350     if (!(para->base_character = psiconv_basic_character_layout()))
351     goto ERROR2_2;
352     if (!(para->base_paragraph = psiconv_basic_paragraph_layout()))
353     goto ERROR2_3;
354 frodo 2 para->base_style = 0;
355     }
356    
357    
358     len += text_len;
359    
360     if (length)
361     *length = len;
362    
363     psiconv_progress(lev+1,off+len-1,"End of text section (total length: %08x",
364     len);
365    
366     return res;
367 frodo 64
368     ERROR2_3:
369     psiconv_free_character_layout(para->base_character);
370     ERROR2_2:
371     psiconv_list_free(para->replacements);
372     ERROR2_1:
373     psiconv_list_free(para->in_lines);
374     ERROR2_0:
375     for (j = 0; j < i; j++) {
376     if (!(para = psiconv_list_get(*result,j))) {
377     psiconv_warn(lev+1,off,"Massive memory corruption...");
378     break;
379     }
380     psiconv_list_free(para->in_lines);
381     psiconv_list_free(para->replacements);
382     psiconv_free_character_layout(para->base_character);
383     psiconv_free_paragraph_layout(para->base_paragraph);
384     }
385     goto ERROR2;
386    
387     ERROR4:
388     free(para->text);
389     ERROR3:
390     free(para);
391     ERROR2:
392     for (i = 0; i < psiconv_list_length(*result);i++) {
393     if (!(para = psiconv_list_get(*result,i))) {
394     psiconv_warn(lev+1,off,"Massive memory corruption...");
395     break;
396     }
397     free(para->text);
398     }
399     psiconv_list_free(*result);
400     ERROR1:
401     psiconv_warn(lev+1,off,"Reading of Text Section failed");
402     if (length)
403     *length = 0;
404     if (!res)
405     return -PSICONV_E_NOMEM;
406     else
407     return res;
408 frodo 2 }
409    
410     /* First do a parse_text_section, or you will get into trouble here */
411     int psiconv_parse_layout_section(const psiconv_buffer buf,
412     int lev,psiconv_u32 off,
413     int *length,
414     psiconv_text_and_layout result,
415     psiconv_word_styles_section styles,
416     int with_styles)
417     {
418     int res = 0;
419     int len = 0;
420     psiconv_u32 temp;
421     int parse_styles,nr,i,j,total,leng,line_length;
422    
423 frodo 56 typedef struct anon_style_s
424 frodo 2 {
425     int nr;
426     psiconv_s16 base_style;
427     psiconv_character_layout character;
428     psiconv_paragraph_layout paragraph;
429     } *anon_style;
430    
431     typedef psiconv_list anon_style_list; /* of struct anon_style */
432    
433     anon_style_list anon_styles;
434 frodo 56 struct anon_style_s anon;
435 frodo 2 anon_style anon_ptr=NULL;
436    
437 frodo 64 psiconv_character_layout temp_char;
438     psiconv_paragraph_layout temp_para;
439     psiconv_word_style temp_style;
440 frodo 2 psiconv_paragraph para;
441 frodo 56 struct psiconv_in_line_layout_s in_line;
442 frodo 2
443     int *inline_count;
444    
445    
446     psiconv_progress(lev+1,off,"Going to read the layout section");
447    
448     psiconv_progress(lev+2,off,"Going to read the section type");
449 frodo 64 temp = psiconv_read_u16(buf,lev+2,off+len,&res);
450     if (res)
451     goto ERROR1;
452 frodo 2 psiconv_debug(lev+2,off+len,"Type: %02x",temp);
453     parse_styles = with_styles;
454     if ((temp == 0x0001) && !with_styles) {
455     psiconv_warn(lev+2,off+len,"Styleless layout section expected, "
456     "but styled section found!");
457     parse_styles = 1;
458     } else if ((temp == 0x0000) && (with_styles)) {
459     psiconv_warn(lev+2,off+len,"Styled layout section expected, "
460     "but styleless section found!");
461     parse_styles = 0;
462     } else if ((temp != 0x0000) && (temp != 0x0001)) {
463     psiconv_warn(lev+2,off+len,
464     "Layout section type indicator has unknown value!");
465     }
466     len += 0x02;
467    
468     psiconv_progress(lev+2,off+len,"Going to read paragraph type list");
469 frodo 64 if (!(anon_styles = psiconv_list_new(sizeof(anon))))
470     goto ERROR1;
471 frodo 2 psiconv_progress(lev+3,off+len,"Going to read paragraph type list length");
472 frodo 64 nr = psiconv_read_u8(buf,lev+3,off+len,&res);
473     if (res)
474     goto ERROR2;
475 frodo 2 psiconv_debug(lev+3,off+len,"Length: %02x",nr);
476     len ++;
477    
478     psiconv_progress(lev+3,off+len,
479     "Going to read the paragraph type list elements");
480     for (i = 0; i < nr; i ++) {
481     psiconv_progress(lev+3,off+len,"Element %d",i);
482 frodo 64 anon.nr = psiconv_read_u32(buf,lev+4,off+len,&res);
483     if (res)
484     goto ERROR3;
485 frodo 2 psiconv_debug(lev+4,off+len,"Number: %08x",anon.nr);
486     len += 0x04;
487    
488     psiconv_progress(lev+4,off,"Going to determine the base style");
489     if (parse_styles) {
490 frodo 64 temp = psiconv_read_u32(buf,lev+4, off+len,&res);
491     if (res)
492     goto ERROR3;
493     anon.base_style = psiconv_read_u8(buf,lev+3, off+len+4+temp,&res);
494     if (res)
495     goto ERROR3;
496     psiconv_debug(lev+4,off+len+temp,
497 frodo 2 "Style indicator: %02x",anon.base_style);
498     } else
499     anon.base_style = 0;
500 frodo 64 if (!(temp_style = psiconv_get_style(styles,anon.base_style))) {
501     psiconv_warn(lev+4,off,"Unknown Style referenced");
502     if (!(temp_style = psiconv_get_style(styles,anon.base_style))) {
503     psiconv_warn(lev+4,off,"Base style unknown");
504     goto ERROR3;
505     }
506     }
507     if (!(anon.paragraph = psiconv_clone_paragraph_layout
508     (temp_style->paragraph)))
509     goto ERROR3;
510     if (!(anon.character = psiconv_clone_character_layout
511     (temp_style->character)))
512     goto ERROR3_1;
513 frodo 2
514     psiconv_progress(lev+4,off+len,"Going to read the paragraph layout");
515 frodo 64 if ((res = psiconv_parse_paragraph_layout_list(buf,lev+4,off+len,&leng,
516     anon.paragraph)))
517     goto ERROR3_2;
518 frodo 2 len += leng;
519     if (parse_styles)
520     len ++;
521    
522     psiconv_progress(lev+4,off+len,"Going to read the character layout");
523 frodo 64 if ((res = psiconv_parse_character_layout_list(buf,lev+4,off+len,&leng,
524     anon.character)))
525     goto ERROR3_2;
526 frodo 2 len += leng;
527 frodo 64 if ((res = psiconv_list_add(anon_styles,&anon)))
528     goto ERROR3_2;
529 frodo 2 }
530    
531     psiconv_progress(lev+2,off+len,"Going to parse the paragraph element list");
532     psiconv_progress(lev+3,off+len,"Going to read the number of paragraphs");
533 frodo 64 nr = psiconv_read_u32(buf,lev+3,off+len,&res);
534     if (res)
535     goto ERROR3;
536 frodo 2 if (nr != psiconv_list_length(result)) {
537     psiconv_warn(lev+3,off+len,
538     "Number of text paragraphs and paragraph elements does not match");
539     psiconv_debug(lev+3,off+len,
540     "%d text paragraphs, %d paragraph elements",
541     psiconv_list_length(result),nr);
542     }
543     psiconv_debug(lev+3,off+len,"Number of paragraphs: %d",nr);
544     len += 4;
545 frodo 64 if (!(inline_count = malloc(nr * sizeof(*inline_count))))
546     goto ERROR3;
547 frodo 2
548     psiconv_progress(lev+3,off+len,"Going to read the paragraph elements");
549     for (i = 0; i < nr; i ++) {
550     psiconv_progress(lev+3,off+len,"Element %d",i);
551     if (i >= psiconv_list_length(result)) {
552     psiconv_debug(lev+4,off+len,"Going to allocate a new element");
553 frodo 64 if (!(para = malloc(sizeof(*para))))
554     goto ERROR4;
555     if (!(para->in_lines = psiconv_list_new(sizeof(
556     struct psiconv_in_line_layout_s))))
557     goto ERROR4_1;
558 frodo 2 para->base_style = 0;
559 frodo 64 if (!(para->base_character = psiconv_basic_character_layout()))
560     goto ERROR4_2;
561     if (!(para->base_paragraph = psiconv_basic_paragraph_layout()))
562     goto ERROR4_3;
563     if ((res = psiconv_list_add(result,para)))
564     goto ERROR4_4;
565 frodo 2 free(para);
566     }
567 frodo 64 if (!(para = psiconv_list_get(result,i)))
568     goto ERROR4;
569 frodo 2
570     psiconv_progress(lev+4,off+len,"Going to read the paragraph length");
571 frodo 64 temp = psiconv_read_u32(buf,lev+4,off+len,&res);
572 frodo 65 if (res)
573 frodo 64 goto ERROR4;
574 frodo 2 if (temp != strlen(para->text)+1) {
575     psiconv_warn(lev+4,off+len,
576     "Disagreement of the length of paragraph in layout section");
577     psiconv_debug(lev+4,off+len,
578     "Paragraph length: layout section says %d, counted %d",
579     temp,strlen(para->text)+1);
580     } else
581     psiconv_debug(lev+4,off+len,"Paragraph length: %d",temp);
582     len += 4;
583    
584     psiconv_progress(lev+4,off+len,"Going to read the paragraph type");
585 frodo 64 temp = psiconv_read_u8(buf,lev+4,off+len,&res);
586 frodo 65 if (res)
587 frodo 64 goto ERROR4;
588 frodo 2 if (temp != 0x00) {
589     psiconv_debug(lev+4,off+len,"Type: %02x",temp);
590     for (j = 0; j < psiconv_list_length(anon_styles); j++) {
591 frodo 64 if (!(anon_ptr = psiconv_list_get(anon_styles,j))) {
592     psiconv_warn(lev+4,off+len,"Massive memory curruption");
593     goto ERROR4;
594     }
595 frodo 2 if (temp == anon_ptr->nr)
596     break;
597     }
598     if (j == psiconv_list_length(anon_styles)) {
599     psiconv_warn(lev+4,off+len,"Layout section paragraph type unknown");
600     psiconv_debug(lev+4,off+len,"Unknown type - using base styles instead");
601     para->base_style = 0;
602 frodo 64 if (!(temp_style = psiconv_get_style(styles,0))) {
603     psiconv_warn(lev+4,off,"Base style unknown");
604     goto ERROR4;
605     }
606     if (!(temp_para = psiconv_clone_paragraph_layout
607     (temp_style->paragraph)))
608     goto ERROR4;
609 frodo 2 psiconv_free_paragraph_layout(para->base_paragraph);
610 frodo 64 para->base_paragraph = temp_para;
611    
612     if (!(temp_char = psiconv_clone_character_layout
613     (temp_style->character)))
614     goto ERROR4;
615 frodo 2 psiconv_free_character_layout(para->base_character);
616 frodo 64 para->base_character = temp_char;
617 frodo 2 } else {
618     para->base_style = anon_ptr->base_style;
619 frodo 64 if (!(temp_para = psiconv_clone_paragraph_layout (anon_ptr->paragraph)))
620     goto ERROR4;
621 frodo 2 psiconv_free_paragraph_layout(para->base_paragraph);
622 frodo 64 para->base_paragraph = temp_para;
623    
624     if (!(temp_char = psiconv_clone_character_layout (anon_ptr->character)))
625     goto ERROR4;
626 frodo 2 psiconv_free_character_layout(para->base_character);
627 frodo 64 para->base_character = temp_char;
628 frodo 2 }
629     inline_count[i] = 0;
630     len += 0x01;
631     } else {
632     psiconv_debug(lev+4,off+len,"Type: %02x (not based on a paragraph type)"
633     ,temp);
634     len += 0x01;
635     if (parse_styles) {
636 frodo 64 temp = psiconv_read_u32(buf,lev+4,off+len,&res);
637     if (res)
638     goto ERROR4;
639     psiconv_progress(lev+4,off+len+temp+4,
640 frodo 2 "Going to read the paragraph element base style");
641 frodo 64 temp = psiconv_read_u8(buf,lev+4, off+len+temp+4,&res);
642     if (res)
643     goto ERROR4;
644     psiconv_debug(lev+4,off+len+temp+4, "Style: %02x",temp);
645 frodo 2 } else
646     temp = 0x00;
647 frodo 64
648     if (!(temp_style = psiconv_get_style (styles,temp))) {
649     psiconv_warn(lev+4,off,"Unknown Style referenced");
650     if (!(temp_style = psiconv_get_style(styles,0))) {
651     psiconv_warn(lev+4,off,"Base style unknown");
652     goto ERROR4;
653     }
654     }
655    
656     if (!(temp_para = psiconv_clone_paragraph_layout(temp_style->paragraph)))
657     goto ERROR4;
658 frodo 2 psiconv_free_paragraph_layout(para->base_paragraph);
659 frodo 64 para->base_paragraph = temp_para;
660    
661     if (!(temp_char = psiconv_clone_character_layout(temp_style->character)))
662     goto ERROR4;
663 frodo 2 psiconv_free_character_layout(para->base_character);
664 frodo 64 para->base_character = temp_char;
665    
666 frodo 2 para->base_style = temp;
667     psiconv_progress(lev+4,off+len,"Going to read paragraph layout");
668 frodo 65 if ((res = psiconv_parse_paragraph_layout_list(buf,lev+4,off+len,&leng,
669 frodo 64 para->base_paragraph)))
670     goto ERROR4;
671 frodo 2 len += leng;
672     if (parse_styles)
673     len += 1;
674     psiconv_progress(lev+4,off+len,"Going to read number of in-line "
675     "layout elements");
676 frodo 64 inline_count[i] = psiconv_read_u32(buf,lev+4,off+len,&res);
677     if (res)
678     goto ERROR4;
679 frodo 2 psiconv_debug(lev+4,off+len,"Nr: %08x",inline_count[i]);
680     len += 4;
681     }
682     }
683    
684     psiconv_progress(lev+2,off+len,"Going to read the text layout inline list");
685    
686     psiconv_progress(lev+3,off+len,"Going to read the number of elements");
687 frodo 64 nr = psiconv_read_u32(buf,lev+3,off+len,&res);
688     if (res)
689     goto ERROR4;
690 frodo 65 psiconv_debug(lev+3,off+len,"Elements: %08x",nr);
691 frodo 2 len += 0x04;
692    
693     psiconv_progress(lev+3,off+len,
694     "Going to read the text layout inline elements");
695     total = 0;
696     for (i = 0; i < psiconv_list_length(result); i++) {
697 frodo 64 if (!(para = psiconv_list_get(result,i))) {
698     psiconv_warn(lev+3,off+len,"Massive memory corruption");
699     goto ERROR4;
700     }
701 frodo 2 line_length = -1;
702     for (j = 0; j < inline_count[i]; j++) {
703     psiconv_progress(lev+3,off+len,"Element %d: Paragraph %d, element %d",
704     total,i,j);
705     if (total >= nr) {
706     psiconv_warn(lev+3,off+len,
707     "Layout section inlines: not enough element");
708     psiconv_debug(lev+3,off+len,"Can't read element!");
709     } else {
710     total ++;
711 frodo 64 if (!(in_line.layout = psiconv_clone_character_layout
712     (para->base_character)))
713     goto ERROR4;
714 frodo 2 psiconv_progress(lev+4,off+len,"Going to read the element type");
715 frodo 64 temp = psiconv_read_u8(buf,lev+4,len+off,&res);
716     if (res)
717     goto ERROR4;
718 frodo 2 len += 1;
719     psiconv_debug(lev+4,off,"Type: %02x",temp);
720     psiconv_progress(lev+4,off,
721 frodo 64 "Going to read the number of characters it applies to");
722     in_line.length = psiconv_read_u32(buf,lev+4,len+off,&res);
723     if (res)
724     goto ERROR4;
725 frodo 2 psiconv_debug(lev+4,off+len,"Length: %02x",in_line.length);
726     len += 4;
727     psiconv_progress(lev+4,off+len,"Going to read the character layout");
728 frodo 64 if ((res = psiconv_parse_character_layout_list(buf,lev+4,off+len,&leng,
729     in_line.layout)))
730     goto ERROR4;
731 frodo 2 len += leng;
732    
733     if (temp == 0x01) {
734     psiconv_debug(lev+4,off+len,"Skipping object data");
735     len += 0x10;
736     } else if (temp != 0x00) {
737     psiconv_warn(lev+4,off+len,"Layout section unknown inline type");
738     }
739     if (line_length + in_line.length > strlen(para->text)) {
740     psiconv_warn(lev+4,off+len,
741     "Layout section inlines: line length mismatch");
742     res = -1;
743     in_line.length = strlen(para->text) - line_length;
744     }
745     line_length += in_line.length;
746 frodo 64 if ((res = psiconv_list_add(para->in_lines,&in_line)))
747     goto ERROR4;
748 frodo 2 }
749     }
750     }
751    
752     if (total != nr) {
753     psiconv_warn(lev+4,off+len,
754     "Layout section too many inlines, skipping remaining");
755     }
756    
757     free(inline_count);
758    
759     for (i = 0 ; i < psiconv_list_length(anon_styles); i ++) {
760 frodo 64 if (!(anon_ptr = psiconv_list_get(anon_styles,i))) {
761     psiconv_warn(lev+4,off+len,"Massive memory corruption");
762     goto ERROR2;
763     }
764 frodo 2 psiconv_free_character_layout(anon_ptr->character);
765     psiconv_free_paragraph_layout(anon_ptr->paragraph);
766     }
767     psiconv_list_free(anon_styles);
768    
769     if (length)
770     *length = len;
771    
772     psiconv_progress(lev+1,off+len-1,"End of layout section (total length: %08x",
773     len);
774    
775 frodo 64 return 0;
776    
777     ERROR4_4:
778     psiconv_free_paragraph_layout(para->base_paragraph);
779     ERROR4_3:
780     psiconv_free_character_layout(para->base_character);
781     ERROR4_2:
782     psiconv_list_free(para->in_lines);
783     ERROR4_1:
784     free(para);
785     goto ERROR4;
786    
787     ERROR3_2:
788     psiconv_free_character_layout(anon.character);
789     ERROR3_1:
790     psiconv_free_paragraph_layout(anon.paragraph);
791     goto ERROR3;
792    
793     ERROR4:
794     free(inline_count);
795     ERROR3:
796     for (i = 0; i < psiconv_list_length(anon_styles); i++) {
797     if (!(anon_ptr = psiconv_list_get(anon_styles,i))) {
798     psiconv_warn(lev+1,off,"Massive memory corruption");
799     break;
800     }
801     psiconv_free_paragraph_layout(anon_ptr->paragraph);
802     psiconv_free_character_layout(anon_ptr->character);
803     }
804    
805     ERROR2:
806     psiconv_list_free(anon_styles);
807     ERROR1:
808     psiconv_warn(lev+1,off,"Reading of Layout Section failed");
809     if (length)
810     *length = 0;
811     if (!res)
812     return -PSICONV_E_NOMEM;
813     else
814     return res;
815 frodo 2 }
816    
817     int psiconv_parse_styled_layout_section(const psiconv_buffer buf,
818     int lev,psiconv_u32 off,
819     int *length,
820     psiconv_text_and_layout result,
821     psiconv_word_styles_section styles)
822     {
823     return psiconv_parse_layout_section(buf,lev,off,length,result,styles,1);
824     }
825    
826     int psiconv_parse_styleless_layout_section(const psiconv_buffer buf,
827     int lev,psiconv_u32 off,
828     int *length,
829     psiconv_text_and_layout result,
830     psiconv_character_layout base_char,
831     psiconv_paragraph_layout base_para)
832     {
833 frodo 64 int res = 0;
834 frodo 2 psiconv_word_styles_section styles_section;
835    
836 frodo 64 if (!(styles_section = malloc(sizeof(*styles_section))))
837     goto ERROR1;
838     if (!(styles_section->normal = malloc(sizeof(*styles_section->normal))))
839     goto ERROR2;
840     if (!(styles_section->normal->character =
841     psiconv_clone_character_layout(base_char)))
842     goto ERROR3;
843     if (!(styles_section->normal->paragraph =
844     psiconv_clone_paragraph_layout(base_para)))
845     goto ERROR4;
846 frodo 2 styles_section->normal->hotkey = 0;
847 frodo 64 if (!(styles_section->normal->name = strdup("")))
848     goto ERROR5;
849     if (!(styles_section->styles = psiconv_list_new(sizeof(
850     struct psiconv_word_style_s))))
851     goto ERROR6;
852 frodo 2
853     res = psiconv_parse_layout_section(buf,lev,off,length,result,
854     styles_section,0);
855    
856     psiconv_free_word_styles_section(styles_section);
857     return res;
858 frodo 64
859     ERROR6:
860     free(styles_section->normal->name);
861     ERROR5:
862     psiconv_free_paragraph_layout(styles_section->normal->paragraph);
863     ERROR4:
864     psiconv_free_character_layout(styles_section->normal->character);
865     ERROR3:
866     free(styles_section->normal);
867     ERROR2:
868     free(styles_section);
869     ERROR1:
870     psiconv_warn(lev+1,off,"Reading of Styleless Layout Section failed");
871     if (length)
872     *length = 0;
873     if (!res)
874     return -PSICONV_E_NOMEM;
875     else
876     return res;
877 frodo 2 }
878    

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