/[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 142 - (hide annotations)
Tue Jan 29 18:38:38 2002 UTC (22 years, 3 months ago) by frodo
File MIME type: text/plain
File size: 13801 byte(s)
(Frodo) DMALLOC support

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

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