/[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 88 - (hide annotations)
Sun Dec 31 01:36:30 2000 UTC (23 years, 10 months ago) by frodo
File MIME type: text/plain
File size: 12697 byte(s)
(Frodo) Empty Word and TextEd documents work!

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 88 int i,j,para_type,nr_of_inlines=0,res,ptl_length,pel_length;
141 frodo 79
142     if (!value) {
143     psiconv_warn(0,psiconv_buffer_length(buf),"Null text section");
144     return -PSICONV_E_GENERATE;
145     }
146    
147     if (!(paragraph_type_list = psiconv_list_new(sizeof(new_type)))) {
148     res = -PSICONV_E_NOMEM;
149     goto ERROR1;
150     }
151    
152 frodo 80 if (!(buf_types = psiconv_buffer_new())) {
153 frodo 79 res = -PSICONV_E_NOMEM;
154     goto ERROR2;
155     }
156    
157 frodo 80 if (!(buf_elements = psiconv_buffer_new())) {
158 frodo 79 res = -PSICONV_E_NOMEM;
159     goto ERROR3;
160     }
161    
162 frodo 80 if (!(buf_inlines = psiconv_buffer_new())) {
163 frodo 79 res = -PSICONV_E_NOMEM;
164     goto ERROR4;
165     }
166    
167     for (i = 0; i < psiconv_list_length(value); i++) {
168     if (!(paragraph = psiconv_list_get(value,i))) {
169     psiconv_warn(0,psiconv_buffer_length(buf),"Massive memory corruption");
170     res = -PSICONV_E_OTHER;
171     goto ERROR5;
172     }
173     if ((res = psiconv_write_u32(buf_elements,strlen(paragraph->text)+1)))
174     goto ERROR5;
175    
176     if (psiconv_list_length(paragraph->in_lines)) {
177     /* Inline layouts, so we generate a paragraph element and inline
178     elements */
179 frodo 80 if ((res = psiconv_write_u8(buf_elements,0x00)))
180 frodo 79 goto ERROR5;
181     if (!(style = psiconv_get_style(styles,paragraph->base_style))) {
182     psiconv_warn(0,psiconv_buffer_length(buf),"Unknown style");
183     res = -PSICONV_E_GENERATE;
184     goto ERROR5;
185     }
186     if ((res = psiconv_write_paragraph_layout_list(buf_elements,
187     paragraph->base_paragraph,
188     style->paragraph)))
189     goto ERROR5;
190     if (with_styles)
191     if ((res = psiconv_write_u8(buf_elements,paragraph->base_style)))
192     goto ERROR5;
193     if ((res = psiconv_write_u32(buf_elements,
194     psiconv_list_length(paragraph->in_lines))))
195     goto ERROR5;
196    
197     /* Generate the inlines. NB: Against what are all settings relative?!? */
198     for (j = 0; j < psiconv_list_length(paragraph->in_lines); j++) {
199     nr_of_inlines ++;
200     if (!(in_line = psiconv_list_get(paragraph->in_lines,j))) {
201     psiconv_warn(0,psiconv_buffer_length(buf),"Massive memory corruption");
202     res = -PSICONV_E_OTHER;
203     goto ERROR5;
204     }
205     if ((res = psiconv_write_u8(buf_inlines,0x00)))
206     goto ERROR5;
207     if ((res = psiconv_write_u32(buf_inlines,in_line->length)))
208     goto ERROR5;
209 frodo 80 if ((res = psiconv_write_character_layout_list(buf_inlines,
210 frodo 79 in_line->layout,
211     style->character)))
212     goto ERROR5;
213     }
214     } else {
215     /* No inline layouts, so we generate a paragraph type list */
216     para_type = 0;
217     for (j = 0; j < psiconv_list_length(paragraph_type_list); j++) {
218     if (!(paragraph_type = psiconv_list_get(paragraph_type_list,j))) {
219     psiconv_warn(0,psiconv_buffer_length(buf),"Massive memory corruption");
220     res = -PSICONV_E_OTHER;
221     goto ERROR5;
222     }
223     if ((paragraph->base_style == paragraph_type->style) &&
224     !psiconv_compare_character_layout(paragraph->base_character,
225     paragraph_type->character) &&
226     !psiconv_compare_paragraph_layout(paragraph->base_paragraph,
227     paragraph_type->paragraph)) {
228     para_type = paragraph_type->nr;
229     break;
230     }
231     }
232     if (!para_type) {
233     /* We need to add a new entry */
234     para_type = new_type.nr = j+1;
235     /* No need to copy them, we won't change them anyway */
236     new_type.paragraph = paragraph->base_paragraph;
237     new_type.character = paragraph->base_character;
238     new_type.style = paragraph->base_style;
239     paragraph_type = &new_type;
240     if ((res = psiconv_list_add(paragraph_type_list,paragraph_type)))
241     goto ERROR5;
242     if ((res = psiconv_write_u32(buf_types,paragraph_type->nr)))
243     goto ERROR5;
244     if (!(style = psiconv_get_style(styles,paragraph_type->style))) {
245     psiconv_warn(0,psiconv_buffer_length(buf),"Unknown style");
246     res = -PSICONV_E_GENERATE;
247     goto ERROR5;
248     }
249     if ((res = psiconv_write_paragraph_layout_list(buf_types,
250     paragraph_type->paragraph,style->paragraph)))
251     goto ERROR5;
252     if (with_styles)
253     if ((res = psiconv_write_u8(buf_types,paragraph_type->style)))
254     goto ERROR5;
255     if ((res = psiconv_write_character_layout_list(buf_types,
256     paragraph_type->character,style->character)))
257     goto ERROR5;
258     }
259     if ((res = psiconv_write_u8(buf_elements,para_type)))
260     goto ERROR5;
261     }
262     }
263    
264 frodo 88 /* HACK: special case: no paragraphs at all. We need to improvize. */
265     if (!psiconv_list_length(value)) {
266     if ((res = psiconv_write_u32(buf_types,1)))
267     goto ERROR5;
268     if ((res = psiconv_write_u32(buf_types,0)))
269     goto ERROR5;
270     if (with_styles)
271     if ((res = psiconv_write_u8(buf_types,0)))
272     goto ERROR5;
273     if ((res = psiconv_write_u32(buf_types,0)))
274     goto ERROR5;
275    
276     if ((res = psiconv_write_u32(buf_elements,1)))
277     goto ERROR5;
278     if ((res = psiconv_write_u8(buf_elements,1)))
279     goto ERROR5;
280     pel_length = 1;
281     ptl_length = 1;
282     } else {
283     pel_length = psiconv_list_length(value);
284     ptl_length = psiconv_list_length(paragraph_type_list);
285     }
286    
287 frodo 79 /* Now append everything */
288 frodo 80 if ((res = psiconv_write_u16(buf,with_styles?0x0001:0x0000)))
289 frodo 79 goto ERROR5;
290 frodo 88 if ((res = psiconv_write_u8(buf, ptl_length)))
291 frodo 79 goto ERROR5;
292     if ((res = psiconv_buffer_concat(buf,buf_types)))
293     goto ERROR5;
294 frodo 88 if ((res = psiconv_write_u32(buf,pel_length)))
295 frodo 79 goto ERROR5;
296     if ((res = psiconv_buffer_concat(buf,buf_elements)))
297     goto ERROR5;
298     if ((res = psiconv_write_u32(buf,nr_of_inlines)))
299     goto ERROR5;
300     res = psiconv_buffer_concat(buf,buf_inlines);
301    
302     ERROR5:
303     psiconv_buffer_free(buf_inlines);
304     ERROR4:
305     psiconv_buffer_free(buf_elements);
306     ERROR3:
307     psiconv_buffer_free(buf_types);
308     ERROR2:
309     psiconv_list_free(paragraph_type_list);
310     ERROR1:
311     return res;
312     }
313    
314     int psiconv_write_styled_layout_section(psiconv_buffer buf,
315     psiconv_text_and_layout result,
316     psiconv_word_styles_section styles)
317     {
318     return psiconv_write_layout_section(buf,result,styles,1);
319     }
320    
321     int psiconv_write_styleless_layout_section(psiconv_buffer buf,
322     const psiconv_text_and_layout value,
323     const psiconv_character_layout base_char,
324     const psiconv_paragraph_layout base_para)
325     {
326     int res = 0;
327     psiconv_word_styles_section styles_section;
328    
329     if (!(styles_section = malloc(sizeof(*styles_section))))
330     goto ERROR1;
331     if (!(styles_section->normal = malloc(sizeof(*styles_section->normal))))
332     goto ERROR2;
333     if (!(styles_section->normal->character =
334     psiconv_clone_character_layout(base_char)))
335     goto ERROR3;
336     if (!(styles_section->normal->paragraph =
337     psiconv_clone_paragraph_layout(base_para)))
338     goto ERROR4;
339     styles_section->normal->hotkey = 0;
340     if (!(styles_section->normal->name = strdup("")))
341     goto ERROR5;
342     if (!(styles_section->styles = psiconv_list_new(sizeof(
343     struct psiconv_word_style_s))))
344     goto ERROR6;
345    
346     res = psiconv_write_layout_section(buf,value,styles_section,0);
347     psiconv_free_word_styles_section(styles_section);
348     return res;
349    
350     ERROR6:
351     free(styles_section->normal->name);
352     ERROR5:
353     psiconv_free_paragraph_layout(styles_section->normal->paragraph);
354     ERROR4:
355     psiconv_free_character_layout(styles_section->normal->character);
356     ERROR3:
357     free(styles_section->normal);
358     ERROR2:
359     free(styles_section);
360     ERROR1:
361     if (!res)
362     return -PSICONV_E_NOMEM;
363     else
364     return res;
365     }

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