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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 89 - (hide annotations)
Sun Jan 7 20:30:13 2001 UTC (23 years, 3 months ago) by frodo
File MIME type: text/plain
File size: 13757 byte(s)
(Frodo) Sanitaized the input for layout section generation; it should now
        work more often.

1 frodo 73 /*
2     generate_common.c - Part of psiconv, a PSION 5 file formats converter
3     Copyright (c) 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 "generate_routines.h"
26     #include "error.h"
27    
28 frodo 79 static int psiconv_write_layout_section(psiconv_buffer buf,
29     const psiconv_text_and_layout value,
30     const psiconv_word_styles_section styles,
31     int with_styles);
32 frodo 73
33     /* Maybe use a psiconv_header_section variable instead? */
34     int psiconv_write_header_section(psiconv_buffer buf,psiconv_u32 uid1,
35     psiconv_u32 uid2, psiconv_u32 uid3)
36     {
37     int res;
38     if ((res = psiconv_write_u32(buf,uid1)))
39     return res;
40     if ((res = psiconv_write_u32(buf,uid2)))
41     return res;
42     if ((res = psiconv_write_u32(buf,uid3)))
43     return res;
44     return psiconv_write_u32(buf,psiconv_checkuid(uid1,uid2,uid3));
45     }
46    
47     int psiconv_write_section_table_section(psiconv_buffer buf,
48     const psiconv_section_table_section value)
49     {
50     int res,i;
51     psiconv_section_table_entry entry;
52    
53     if (!value) {
54 frodo 79 psiconv_warn(0,psiconv_buffer_length(buf),"Null section table section");
55 frodo 73 return -PSICONV_E_GENERATE;
56     }
57    
58 frodo 76 if ((res = psiconv_write_u8(buf,2 * psiconv_list_length(value))))
59     return res;
60 frodo 73 for (i = 0; i < psiconv_list_length(value); i++) {
61     if (!(entry = psiconv_list_get(value,i))) {
62 frodo 79 psiconv_warn(0,psiconv_buffer_length(buf),"Massive memory corruption");
63 frodo 76 return -PSICONV_E_NOMEM;
64 frodo 73 }
65     if ((res = psiconv_write_u32(buf,entry->id)))
66 frodo 76 return res;
67 frodo 80 if ((res = psiconv_write_offset(buf,entry->offset)))
68 frodo 76 return res;
69 frodo 73 }
70 frodo 76 return -PSICONV_E_OK;
71 frodo 73 }
72    
73     int psiconv_write_application_id_section(psiconv_buffer buf,psiconv_u32 id,
74     const psiconv_string_t text)
75     {
76     int res;
77     if ((res = psiconv_write_u32(buf,id)))
78     return res;
79     return psiconv_write_string(buf,text);
80     }
81    
82     int psiconv_write_text_section(psiconv_buffer buf,
83     const psiconv_text_and_layout value)
84     {
85     int res;
86     psiconv_buffer extra_buf;
87     int i,j;
88     psiconv_paragraph paragraph;
89    
90     if (!value) {
91 frodo 79 psiconv_warn(0,psiconv_buffer_length(buf),"Null text section");
92 frodo 73 return -PSICONV_E_GENERATE;
93     }
94    
95 frodo 88 if (psiconv_list_length(value)) {
96     if (!(extra_buf = psiconv_buffer_new()))
97     return -PSICONV_E_NOMEM;
98     for (i = 0; i < psiconv_list_length(value); i++) {
99     if (!(paragraph = psiconv_list_get(value,i))) {
100     psiconv_warn(0,psiconv_buffer_length(buf),"Massive memory corruption");
101     res = -PSICONV_E_OTHER;
102     goto ERROR;
103     }
104     for (j = 0; j < strlen(paragraph->text); j++)
105     if ((res = psiconv_write_u8(extra_buf,paragraph->text[j])))
106     goto ERROR;
107     psiconv_write_u8(extra_buf,0x06);
108     }
109     if ((res = psiconv_write_X(buf,psiconv_buffer_length(extra_buf))))
110 frodo 73 goto ERROR;
111 frodo 88 res = psiconv_buffer_concat(buf,extra_buf);
112     } else
113     /* Hack: empty text sections are just not allowed */
114     return psiconv_write_u16(buf,0x0602);
115 frodo 73
116     ERROR:
117 frodo 79 psiconv_buffer_free(extra_buf);
118 frodo 75 return res;
119 frodo 73 }
120 frodo 79
121     int psiconv_write_layout_section(psiconv_buffer buf,
122     const psiconv_text_and_layout value,
123     const psiconv_word_styles_section styles,
124     int with_styles)
125     {
126     typedef struct psiconv_paragraph_type_list_s
127     {
128     psiconv_character_layout character;
129     psiconv_paragraph_layout paragraph;
130     psiconv_u8 style;
131     psiconv_u8 nr;
132     } *psiconv_paragraph_type_list;
133     psiconv_list paragraph_type_list; /* Of psiconv_paragraph_type_list_s */
134     psiconv_paragraph_type_list paragraph_type;
135     struct psiconv_paragraph_type_list_s new_type;
136     psiconv_buffer buf_types,buf_elements,buf_inlines;
137     psiconv_paragraph paragraph;
138     psiconv_in_line_layout in_line;
139     psiconv_word_style style;
140 frodo 89 psiconv_character_layout para_charlayout;
141     int i,j,para_type,nr_of_inlines=0,res,ptl_length,pel_length,thislen,paralen;
142 frodo 79
143     if (!value) {
144     psiconv_warn(0,psiconv_buffer_length(buf),"Null text section");
145     return -PSICONV_E_GENERATE;
146     }
147    
148     if (!(paragraph_type_list = psiconv_list_new(sizeof(new_type)))) {
149     res = -PSICONV_E_NOMEM;
150     goto ERROR1;
151     }
152    
153 frodo 80 if (!(buf_types = psiconv_buffer_new())) {
154 frodo 79 res = -PSICONV_E_NOMEM;
155     goto ERROR2;
156     }
157    
158 frodo 80 if (!(buf_elements = psiconv_buffer_new())) {
159 frodo 79 res = -PSICONV_E_NOMEM;
160     goto ERROR3;
161     }
162    
163 frodo 80 if (!(buf_inlines = psiconv_buffer_new())) {
164 frodo 79 res = -PSICONV_E_NOMEM;
165     goto ERROR4;
166     }
167    
168     for (i = 0; i < psiconv_list_length(value); i++) {
169     if (!(paragraph = psiconv_list_get(value,i))) {
170     psiconv_warn(0,psiconv_buffer_length(buf),"Massive memory corruption");
171     res = -PSICONV_E_OTHER;
172     goto ERROR5;
173     }
174     if ((res = psiconv_write_u32(buf_elements,strlen(paragraph->text)+1)))
175     goto ERROR5;
176    
177 frodo 89 if (psiconv_list_length(paragraph->in_lines) > 1) {
178 frodo 79 /* Inline layouts, so we generate a paragraph element and inline
179     elements */
180 frodo 80 if ((res = psiconv_write_u8(buf_elements,0x00)))
181 frodo 79 goto ERROR5;
182     if (!(style = psiconv_get_style(styles,paragraph->base_style))) {
183     psiconv_warn(0,psiconv_buffer_length(buf),"Unknown style");
184     res = -PSICONV_E_GENERATE;
185     goto ERROR5;
186     }
187     if ((res = psiconv_write_paragraph_layout_list(buf_elements,
188     paragraph->base_paragraph,
189     style->paragraph)))
190     goto ERROR5;
191     if (with_styles)
192     if ((res = psiconv_write_u8(buf_elements,paragraph->base_style)))
193     goto ERROR5;
194     if ((res = psiconv_write_u32(buf_elements,
195     psiconv_list_length(paragraph->in_lines))))
196     goto ERROR5;
197    
198     /* Generate the inlines. NB: Against what are all settings relative?!? */
199 frodo 89 paralen = 0;
200 frodo 79 for (j = 0; j < psiconv_list_length(paragraph->in_lines); j++) {
201     nr_of_inlines ++;
202     if (!(in_line = psiconv_list_get(paragraph->in_lines,j))) {
203 frodo 89 psiconv_warn(0,psiconv_buffer_length(buf),
204     "Massive memory corruption");
205 frodo 79 res = -PSICONV_E_OTHER;
206     goto ERROR5;
207     }
208     if ((res = psiconv_write_u8(buf_inlines,0x00)))
209     goto ERROR5;
210 frodo 89 thislen = in_line->length;
211     paralen += thislen;
212     /* If this is the last in_line, we need to make sure that the
213     complete length of all inlines equals the text length */
214     if (j == psiconv_list_length(paragraph->in_lines)-1) {
215     if (paralen > strlen(paragraph->text)+1) {
216     res = -PSICONV_E_GENERATE;
217     goto ERROR5;
218     }
219     thislen += strlen(paragraph->text)+1-paralen;
220     }
221     if ((res = psiconv_write_u32(buf_inlines,thislen)))
222 frodo 79 goto ERROR5;
223 frodo 80 if ((res = psiconv_write_character_layout_list(buf_inlines,
224 frodo 79 in_line->layout,
225     style->character)))
226     goto ERROR5;
227     }
228     } else {
229 frodo 89 /* No inline layouts (or only 1), so we generate a paragraph type list */
230 frodo 79 para_type = 0;
231 frodo 89 /* Set para_charlayout to the correct character-level layout */
232     if (psiconv_list_length(paragraph->in_lines) == 0)
233     para_charlayout = paragraph->base_character;
234     else {
235     if (!(in_line = psiconv_list_get(paragraph->in_lines,0))) {
236     psiconv_warn(0,psiconv_buffer_length(buf),
237     "Massive memory corruption");
238     res = -PSICONV_E_OTHER;
239     goto ERROR5;
240     }
241     para_charlayout = in_line->layout;
242     }
243 frodo 79 for (j = 0; j < psiconv_list_length(paragraph_type_list); j++) {
244     if (!(paragraph_type = psiconv_list_get(paragraph_type_list,j))) {
245 frodo 89 psiconv_warn(0,psiconv_buffer_length(buf),
246     "Massive memory corruption");
247 frodo 79 res = -PSICONV_E_OTHER;
248     goto ERROR5;
249     }
250     if ((paragraph->base_style == paragraph_type->style) &&
251 frodo 89 !psiconv_compare_character_layout(para_charlayout,
252 frodo 79 paragraph_type->character) &&
253     !psiconv_compare_paragraph_layout(paragraph->base_paragraph,
254     paragraph_type->paragraph)) {
255     para_type = paragraph_type->nr;
256     break;
257     }
258     }
259     if (!para_type) {
260     /* We need to add a new entry */
261     para_type = new_type.nr = j+1;
262     /* No need to copy them, we won't change them anyway */
263     new_type.paragraph = paragraph->base_paragraph;
264 frodo 89 new_type.character = para_charlayout;
265 frodo 79 new_type.style = paragraph->base_style;
266     paragraph_type = &new_type;
267     if ((res = psiconv_list_add(paragraph_type_list,paragraph_type)))
268     goto ERROR5;
269     if ((res = psiconv_write_u32(buf_types,paragraph_type->nr)))
270     goto ERROR5;
271     if (!(style = psiconv_get_style(styles,paragraph_type->style))) {
272     psiconv_warn(0,psiconv_buffer_length(buf),"Unknown style");
273     res = -PSICONV_E_GENERATE;
274     goto ERROR5;
275     }
276     if ((res = psiconv_write_paragraph_layout_list(buf_types,
277     paragraph_type->paragraph,style->paragraph)))
278     goto ERROR5;
279     if (with_styles)
280     if ((res = psiconv_write_u8(buf_types,paragraph_type->style)))
281     goto ERROR5;
282     if ((res = psiconv_write_character_layout_list(buf_types,
283     paragraph_type->character,style->character)))
284     goto ERROR5;
285     }
286     if ((res = psiconv_write_u8(buf_elements,para_type)))
287     goto ERROR5;
288     }
289     }
290    
291 frodo 88 /* HACK: special case: no paragraphs at all. We need to improvize. */
292     if (!psiconv_list_length(value)) {
293     if ((res = psiconv_write_u32(buf_types,1)))
294     goto ERROR5;
295     if ((res = psiconv_write_u32(buf_types,0)))
296     goto ERROR5;
297     if (with_styles)
298     if ((res = psiconv_write_u8(buf_types,0)))
299     goto ERROR5;
300     if ((res = psiconv_write_u32(buf_types,0)))
301     goto ERROR5;
302    
303     if ((res = psiconv_write_u32(buf_elements,1)))
304     goto ERROR5;
305     if ((res = psiconv_write_u8(buf_elements,1)))
306     goto ERROR5;
307     pel_length = 1;
308     ptl_length = 1;
309     } else {
310     pel_length = psiconv_list_length(value);
311     ptl_length = psiconv_list_length(paragraph_type_list);
312     }
313    
314 frodo 79 /* Now append everything */
315 frodo 80 if ((res = psiconv_write_u16(buf,with_styles?0x0001:0x0000)))
316 frodo 79 goto ERROR5;
317 frodo 88 if ((res = psiconv_write_u8(buf, ptl_length)))
318 frodo 79 goto ERROR5;
319     if ((res = psiconv_buffer_concat(buf,buf_types)))
320     goto ERROR5;
321 frodo 88 if ((res = psiconv_write_u32(buf,pel_length)))
322 frodo 79 goto ERROR5;
323     if ((res = psiconv_buffer_concat(buf,buf_elements)))
324     goto ERROR5;
325     if ((res = psiconv_write_u32(buf,nr_of_inlines)))
326     goto ERROR5;
327     res = psiconv_buffer_concat(buf,buf_inlines);
328    
329     ERROR5:
330     psiconv_buffer_free(buf_inlines);
331     ERROR4:
332     psiconv_buffer_free(buf_elements);
333     ERROR3:
334     psiconv_buffer_free(buf_types);
335     ERROR2:
336     psiconv_list_free(paragraph_type_list);
337     ERROR1:
338     return res;
339     }
340    
341     int psiconv_write_styled_layout_section(psiconv_buffer buf,
342     psiconv_text_and_layout result,
343     psiconv_word_styles_section styles)
344     {
345     return psiconv_write_layout_section(buf,result,styles,1);
346     }
347    
348     int psiconv_write_styleless_layout_section(psiconv_buffer buf,
349     const psiconv_text_and_layout value,
350     const psiconv_character_layout base_char,
351     const psiconv_paragraph_layout base_para)
352     {
353     int res = 0;
354     psiconv_word_styles_section styles_section;
355    
356     if (!(styles_section = malloc(sizeof(*styles_section))))
357     goto ERROR1;
358     if (!(styles_section->normal = malloc(sizeof(*styles_section->normal))))
359     goto ERROR2;
360     if (!(styles_section->normal->character =
361     psiconv_clone_character_layout(base_char)))
362     goto ERROR3;
363     if (!(styles_section->normal->paragraph =
364     psiconv_clone_paragraph_layout(base_para)))
365     goto ERROR4;
366     styles_section->normal->hotkey = 0;
367     if (!(styles_section->normal->name = strdup("")))
368     goto ERROR5;
369     if (!(styles_section->styles = psiconv_list_new(sizeof(
370     struct psiconv_word_style_s))))
371     goto ERROR6;
372    
373     res = psiconv_write_layout_section(buf,value,styles_section,0);
374     psiconv_free_word_styles_section(styles_section);
375     return res;
376    
377     ERROR6:
378     free(styles_section->normal->name);
379     ERROR5:
380     psiconv_free_paragraph_layout(styles_section->normal->paragraph);
381     ERROR4:
382     psiconv_free_character_layout(styles_section->normal->character);
383     ERROR3:
384     free(styles_section->normal);
385     ERROR2:
386     free(styles_section);
387     ERROR1:
388     if (!res)
389     return -PSICONV_E_NOMEM;
390     else
391     return res;
392     }

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