| 1 | /* |
1 | /* |
| 2 | general.c - Part of psiconv, a PSION 5 file formats converter |
2 | general.c - Part of psiconv, a PSION 5 file formats converter |
| 3 | Copyright (c) 2003 Frodo Looijaard <frodol@dds.nl> |
3 | Copyright (c) 2003-2004 Frodo Looijaard <frodo@frodo.looijaard.name> |
| 4 | |
4 | |
| 5 | This program is free software; you can redistribute it and/or modify |
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 |
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 |
7 | the Free Software Foundation; either version 2 of the License, or |
| 8 | (at your option) any later version. |
8 | (at your option) any later version. |
| … | |
… | |
| 22 | |
22 | |
| 23 | #include "psiconv.h" |
23 | #include "psiconv.h" |
| 24 | #include "general.h" |
24 | #include "general.h" |
| 25 | #include <psiconv/list.h> |
25 | #include <psiconv/list.h> |
| 26 | #include <psiconv/unicode.h> |
26 | #include <psiconv/unicode.h> |
|
|
27 | #include <psiconv/error.h> |
|
|
28 | #include <stdlib.h> |
|
|
29 | #include <string.h> |
| 27 | |
30 | |
| 28 | /* Output a UCS2 character in one of the supported encodings. */ |
31 | /* Output a UCS2 character in one of the supported encodings. */ |
| 29 | int output_char(psiconv_config config, psiconv_list list, |
32 | void output_char(psiconv_config config, psiconv_list list, |
| 30 | psiconv_ucs2 character, encoding enc) |
33 | psiconv_ucs2 character, encoding enc) |
| 31 | { |
34 | { |
| 32 | psiconv_u8 temp; |
35 | psiconv_u8 temp; |
|
|
36 | psiconv_u8 *byteptr; |
| 33 | int res; |
37 | int res,i; |
|
|
38 | psiconv_buffer buf; |
|
|
39 | #define TEMPSTR_LEN 80 |
|
|
40 | char tempstr[TEMPSTR_LEN]; |
| 34 | |
41 | |
| 35 | if (enc == ENCODING_UCS2) { |
42 | if (enc == ENCODING_UCS2) { |
| 36 | temp = character >> 8; |
43 | temp = character >> 8; |
| 37 | if ((res = psiconv_list_add(list,&temp))) |
44 | if ((res = psiconv_list_add(list,&temp))) { |
| 38 | return res; |
45 | fputs("Out of memory error\n",stderr); |
|
|
46 | exit(1); |
|
|
47 | } |
| 39 | temp = character & 0xff; |
48 | temp = character & 0xff; |
| 40 | if ((res = psiconv_list_add(list,&temp))) |
49 | if ((res = psiconv_list_add(list,&temp))) { |
| 41 | return res; |
50 | fputs("Out of memory error\n",stderr); |
|
|
51 | exit(1); |
|
|
52 | } |
| 42 | } else if (enc == ENCODING_UTF8) { |
53 | } else if (enc == ENCODING_UTF8) { |
| 43 | if (character < 0x80) { |
54 | if (character < 0x80) { |
| 44 | temp = character; |
55 | temp = character; |
| 45 | if ((res = psiconv_list_add(list,&temp))) |
56 | if ((res = psiconv_list_add(list,&temp))) { |
| 46 | return res; |
57 | fputs("Out of memory error\n",stderr); |
|
|
58 | exit(1); |
|
|
59 | } |
| 47 | } else if (character < 0x800) { |
60 | } else if (character < 0x800) { |
| 48 | temp = 0xc0 + (character >> 6); |
61 | temp = 0xc0 + (character >> 6); |
| 49 | if ((res = psiconv_list_add(list,&temp))) |
62 | if ((res = psiconv_list_add(list,&temp))) { |
| 50 | return res; |
63 | fputs("Out of memory error\n",stderr); |
|
|
64 | exit(1); |
|
|
65 | } |
| 51 | temp = 0x80 + (character & 0x3f); |
66 | temp = 0x80 + (character & 0x3f); |
| 52 | if ((res = psiconv_list_add(list,&temp))) |
67 | if ((res = psiconv_list_add(list,&temp))) { |
| 53 | return res; |
68 | fputs("Out of memory error\n",stderr); |
|
|
69 | exit(1); |
|
|
70 | } |
| 54 | } else { |
71 | } else { |
| 55 | temp = 0xe0 + (character >> 12); |
72 | temp = 0xe0 + (character >> 12); |
| 56 | if ((res = psiconv_list_add(list,&temp))) |
73 | if ((res = psiconv_list_add(list,&temp))) { |
| 57 | return res; |
74 | fputs("Out of memory error\n",stderr); |
|
|
75 | exit(1); |
|
|
76 | } |
| 58 | temp = 0x80 + ((character >> 6) & 0x3f); |
77 | temp = 0x80 + ((character >> 6) & 0x3f); |
| 59 | if ((res = psiconv_list_add(list,&temp))) |
78 | if ((res = psiconv_list_add(list,&temp))) { |
| 60 | return res; |
79 | fputs("Out of memory error\n",stderr); |
|
|
80 | exit(1); |
|
|
81 | } |
| 61 | temp = 0x80 + (character & 0x3f); |
82 | temp = 0x80 + (character & 0x3f); |
| 62 | if ((res = psiconv_list_add(list,&temp))) |
83 | if ((res = psiconv_list_add(list,&temp))) { |
| 63 | return res; |
84 | fputs("Out of memory error\n",stderr); |
|
|
85 | exit(1); |
|
|
86 | } |
| 64 | } |
87 | } |
| 65 | } else if (enc == ENCODING_ASCII) { |
88 | } else if (enc == ENCODING_ASCII) { |
| 66 | if (character == 0xa0) |
89 | if (character == 0xa0) |
| 67 | temp = ' '; |
90 | temp = ' '; |
| 68 | else if (character >= 0x80) |
91 | else if (character >= 0x80) |
| 69 | temp = '?'; |
92 | temp = '?'; |
| 70 | else |
93 | else |
| 71 | temp = character; |
94 | temp = character; |
| 72 | if ((res = psiconv_list_add(list,&temp))) |
95 | if ((res = psiconv_list_add(list,&temp))) { |
| 73 | return res; |
96 | fputs("Out of memory error\n",stderr); |
|
|
97 | exit(1); |
|
|
98 | } |
|
|
99 | } else if (enc == ENCODING_ASCII_HTML) { |
|
|
100 | if (character >= 0x80) { |
|
|
101 | snprintf(tempstr,TEMPSTR_LEN,"&#x%x;",character); |
|
|
102 | output_simple_chars(config,list,tempstr,enc); |
|
|
103 | } else { |
|
|
104 | temp = character; |
|
|
105 | if ((res = psiconv_list_add(list,&temp))) { |
|
|
106 | fputs("Out of memory error\n",stderr); |
|
|
107 | exit(1); |
|
|
108 | } |
|
|
109 | } |
| 74 | } else if (enc == ENCODING_PSION) { |
110 | } else if (enc == ENCODING_PSION) { |
|
|
111 | if (!(buf = psiconv_buffer_new())) { |
|
|
112 | fputs("Out of memory error\n",stderr); |
|
|
113 | exit(1); |
|
|
114 | } |
| 75 | temp = psiconv_unicode_to_char(config,character); |
115 | psiconv_unicode_write_char(config,buf,0,character); |
|
|
116 | for (i = 0; i < psiconv_buffer_length(buf); i++) { |
|
|
117 | if (!(byteptr = psiconv_buffer_get(buf,i))) { |
|
|
118 | fputs("Internal memory corruption\n",stderr); |
|
|
119 | exit(1); |
|
|
120 | } |
| 76 | if ((res = psiconv_list_add(list,&temp))) |
121 | if ((res = psiconv_list_add(list,byteptr))) { |
| 77 | return res; |
122 | fputs("Out of memory error\n",stderr); |
|
|
123 | exit(1); |
|
|
124 | } |
|
|
125 | } |
|
|
126 | psiconv_buffer_free(buf); |
| 78 | } |
127 | } |
| 79 | return 0; |
|
|
| 80 | } |
128 | } |
| 81 | |
129 | |
| 82 | int output_string(psiconv_config config, psiconv_list list, |
130 | void output_string(psiconv_config config, psiconv_list list, |
| 83 | psiconv_ucs2 *string, encoding enc) |
131 | psiconv_ucs2 *string, encoding enc) |
| 84 | { |
132 | { |
| 85 | int i = 0; |
133 | int i = 0; |
| 86 | int res; |
|
|
| 87 | |
134 | |
| 88 | while (string[i]) { |
135 | while (string[i]) { |
| 89 | if ((res = output_char(config,list,string[i],enc))) |
136 | output_char(config,list,string[i],enc); |
| 90 | return res; |
|
|
| 91 | i++; |
137 | i++; |
| 92 | } |
138 | } |
| 93 | return 0; |
|
|
| 94 | } |
139 | } |
|
|
140 | |
|
|
141 | void output_simple_chars(psiconv_config config, psiconv_list list, |
|
|
142 | char *string, encoding enc) |
|
|
143 | { |
|
|
144 | psiconv_ucs2 *ucs_string; |
|
|
145 | int i; |
|
|
146 | |
|
|
147 | if (!(ucs_string = malloc(sizeof(*ucs_string) * (strlen(string) + 1)))) { |
|
|
148 | fputs("Out of memory error",stderr); |
|
|
149 | exit(1); |
|
|
150 | } |
|
|
151 | for (i = 0; i < strlen(string); i++) { |
|
|
152 | if ((string[i] != '\n') && ((string[i] < 0x20) || (string[i] > 0x7e))) { |
|
|
153 | fprintf(stderr,"output_simple_chars unknown char: %02x",string[i]); |
|
|
154 | exit(1); |
|
|
155 | } |
|
|
156 | ucs_string[i] = string[i]; |
|
|
157 | } |
|
|
158 | ucs_string[i] = string[i]; |
|
|
159 | output_string(config,list,ucs_string,enc); |
|
|
160 | free(ucs_string); |
|
|
161 | } |