/[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 159 - (hide annotations)
Wed Nov 19 21:04:06 2003 UTC (20 years, 4 months ago) by frodo
File MIME type: text/plain
File size: 29040 byte(s)
(Frodo) Data structures for (Word) objects created.

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 64 if (!(in_line.layout = psiconv_clone_character_layout
721     (para->base_character)))
722     goto ERROR4;
723 frodo 2 psiconv_progress(lev+4,off+len,"Going to read the element type");
724 frodo 64 temp = psiconv_read_u8(buf,lev+4,len+off,&res);
725     if (res)
726     goto ERROR4;
727 frodo 2 len += 1;
728 frodo 70 psiconv_debug(lev+4,off+len,"Type: %02x",temp);
729     psiconv_progress(lev+4,off+len,
730 frodo 64 "Going to read the number of characters it applies to");
731     in_line.length = psiconv_read_u32(buf,lev+4,len+off,&res);
732     if (res)
733     goto ERROR4;
734 frodo 2 psiconv_debug(lev+4,off+len,"Length: %02x",in_line.length);
735     len += 4;
736     psiconv_progress(lev+4,off+len,"Going to read the character layout");
737 frodo 64 if ((res = psiconv_parse_character_layout_list(buf,lev+4,off+len,&leng,
738     in_line.layout)))
739     goto ERROR4;
740 frodo 2 len += leng;
741    
742     if (temp == 0x01) {
743     psiconv_debug(lev+4,off+len,"Skipping object data");
744     len += 0x10;
745     } else if (temp != 0x00) {
746     psiconv_warn(lev+4,off+len,"Layout section unknown inline type");
747     }
748     if (line_length + in_line.length > strlen(para->text)) {
749     psiconv_warn(lev+4,off+len,
750     "Layout section inlines: line length mismatch");
751     res = -1;
752     in_line.length = strlen(para->text) - line_length;
753     }
754     line_length += in_line.length;
755 frodo 64 if ((res = psiconv_list_add(para->in_lines,&in_line)))
756     goto ERROR4;
757 frodo 2 }
758     }
759     }
760    
761     if (total != nr) {
762     psiconv_warn(lev+4,off+len,
763     "Layout section too many inlines, skipping remaining");
764     }
765    
766     free(inline_count);
767    
768     for (i = 0 ; i < psiconv_list_length(anon_styles); i ++) {
769 frodo 64 if (!(anon_ptr = psiconv_list_get(anon_styles,i))) {
770     psiconv_warn(lev+4,off+len,"Massive memory corruption");
771     goto ERROR2;
772     }
773 frodo 2 psiconv_free_character_layout(anon_ptr->character);
774     psiconv_free_paragraph_layout(anon_ptr->paragraph);
775     }
776     psiconv_list_free(anon_styles);
777    
778     if (length)
779     *length = len;
780    
781 frodo 70 psiconv_progress(lev+1,off+len-1,"End of layout section (total length: %08x)",
782 frodo 2 len);
783    
784 frodo 64 return 0;
785    
786     ERROR4_4:
787     psiconv_free_paragraph_layout(para->base_paragraph);
788     ERROR4_3:
789     psiconv_free_character_layout(para->base_character);
790     ERROR4_2:
791     psiconv_list_free(para->in_lines);
792     ERROR4_1:
793     free(para);
794     goto ERROR4;
795    
796     ERROR3_2:
797     psiconv_free_character_layout(anon.character);
798     ERROR3_1:
799     psiconv_free_paragraph_layout(anon.paragraph);
800     goto ERROR3;
801    
802     ERROR4:
803     free(inline_count);
804     ERROR3:
805     for (i = 0; i < psiconv_list_length(anon_styles); i++) {
806     if (!(anon_ptr = psiconv_list_get(anon_styles,i))) {
807     psiconv_warn(lev+1,off,"Massive memory corruption");
808     break;
809     }
810     psiconv_free_paragraph_layout(anon_ptr->paragraph);
811     psiconv_free_character_layout(anon_ptr->character);
812     }
813    
814     ERROR2:
815     psiconv_list_free(anon_styles);
816     ERROR1:
817     psiconv_warn(lev+1,off,"Reading of Layout Section failed");
818     if (length)
819     *length = 0;
820     if (!res)
821     return -PSICONV_E_NOMEM;
822     else
823     return res;
824 frodo 2 }
825    
826     int psiconv_parse_styled_layout_section(const psiconv_buffer buf,
827     int lev,psiconv_u32 off,
828     int *length,
829     psiconv_text_and_layout result,
830     psiconv_word_styles_section styles)
831     {
832     return psiconv_parse_layout_section(buf,lev,off,length,result,styles,1);
833     }
834    
835     int psiconv_parse_styleless_layout_section(const psiconv_buffer buf,
836 frodo 79 int lev,psiconv_u32 off,
837     int *length,
838     psiconv_text_and_layout result,
839     const psiconv_character_layout base_char,
840     const psiconv_paragraph_layout base_para)
841 frodo 2 {
842 frodo 64 int res = 0;
843 frodo 2 psiconv_word_styles_section styles_section;
844    
845 frodo 64 if (!(styles_section = malloc(sizeof(*styles_section))))
846     goto ERROR1;
847     if (!(styles_section->normal = malloc(sizeof(*styles_section->normal))))
848     goto ERROR2;
849     if (!(styles_section->normal->character =
850     psiconv_clone_character_layout(base_char)))
851     goto ERROR3;
852     if (!(styles_section->normal->paragraph =
853     psiconv_clone_paragraph_layout(base_para)))
854     goto ERROR4;
855 frodo 2 styles_section->normal->hotkey = 0;
856 frodo 64 if (!(styles_section->normal->name = strdup("")))
857     goto ERROR5;
858     if (!(styles_section->styles = psiconv_list_new(sizeof(
859     struct psiconv_word_style_s))))
860     goto ERROR6;
861 frodo 2
862     res = psiconv_parse_layout_section(buf,lev,off,length,result,
863     styles_section,0);
864    
865     psiconv_free_word_styles_section(styles_section);
866     return res;
867 frodo 64
868     ERROR6:
869     free(styles_section->normal->name);
870     ERROR5:
871     psiconv_free_paragraph_layout(styles_section->normal->paragraph);
872     ERROR4:
873     psiconv_free_character_layout(styles_section->normal->character);
874     ERROR3:
875     free(styles_section->normal);
876     ERROR2:
877     free(styles_section);
878     ERROR1:
879     psiconv_warn(lev+1,off,"Reading of Styleless Layout Section failed");
880     if (length)
881     *length = 0;
882     if (!res)
883     return -PSICONV_E_NOMEM;
884     else
885     return res;
886 frodo 2 }
887    

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