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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 94 - (show annotations)
Wed Jan 17 00:05:08 2001 UTC (23 years, 2 months ago) by frodo
File MIME type: text/plain
File size: 28971 byte(s)
(Frodo) Start of Sheet support: base types defined, page and status section
        parsed, supporting definitions in data.c

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

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