1 /* -*- c-basic-offset:2; tab-width:2; indent-tabs-mode:nil -*- */
2 
3 #include "ef_iso2022_conv.h"
4 
5 #include "ef_iso2022_intern.h"
6 #include "ef_zh_cn_map.h"
7 #include "ef_zh_tw_map.h"
8 #include "ef_ko_kr_map.h"
9 #include "ef_viet_map.h"
10 #include "ef_ru_map.h"
11 #include "ef_uk_map.h"
12 #include "ef_tg_map.h"
13 #include "ef_ucs4_map.h"
14 
15 /* --- static functions --- */
16 
designate_to_g0(u_char * dst,size_t dst_size,int * is_full,ef_charset_t cs)17 static size_t designate_to_g0(u_char *dst, size_t dst_size, int *is_full, ef_charset_t cs) {
18   *is_full = 0;
19 
20   if (IS_CS94SB(cs)) {
21     if (3 > dst_size) {
22       *is_full = 1;
23 
24       return 0;
25     }
26 
27     *(dst++) = '\x1b';
28     *(dst++) = '(';
29     *(dst++) = CS94SB_FT(cs);
30 
31     return 3;
32   } else if (IS_CS94MB(cs)) {
33     if (4 > dst_size) {
34       *is_full = 1;
35 
36       return 0;
37     }
38 
39     *(dst++) = '\x1b';
40     *(dst++) = '$';
41     *(dst++) = '(';
42     *(dst++) = CS94MB_FT(cs);
43 
44     return 4;
45   } else if (IS_CS96SB(cs)) {
46     if (3 > dst_size) {
47       *is_full = 1;
48 
49       return 0;
50     }
51 
52     *(dst++) = '\x1b';
53     *(dst++) = '-';
54     *(dst++) = CS96SB_FT(cs);
55 
56     return 3;
57   } else if (IS_CS96MB(cs)) {
58     if (4 > dst_size) {
59       *is_full = 1;
60 
61       return 0;
62     }
63 
64     *(dst++) = '\x1b';
65     *(dst++) = '$';
66     *(dst++) = '-';
67     *(dst++) = CS96MB_FT(cs);
68 
69     return 4;
70   }
71 
72   /* error */
73 
74   return 0;
75 }
76 
77 /* --- global functions --- */
78 
ef_iso2022_illegal_char(ef_conv_t * conv,u_char * dst,size_t dst_size,int * is_full,ef_char_t * ch)79 size_t ef_iso2022_illegal_char(ef_conv_t *conv, u_char *dst, size_t dst_size, int *is_full,
80                                 ef_char_t *ch) {
81   ef_iso2022_conv_t *iso2022_conv;
82   size_t filled_size;
83   size_t size;
84   int count;
85 
86   iso2022_conv = (ef_iso2022_conv_t*)conv;
87 
88   *is_full = 0;
89 
90   if (!IS_CS_BASED_ON_ISO2022(ch->cs)) {
91     /* error */
92 
93     return 0;
94   }
95 
96   filled_size = 0;
97 
98   /*
99    * locking shift G0 to GL
100    */
101   if (iso2022_conv->gl != &iso2022_conv->g0) {
102     if (filled_size + 1 > dst_size) {
103       *is_full = 1;
104 
105       return 0;
106     }
107 
108     *(dst++) = LS0;
109 
110     filled_size++;
111   }
112 
113   /*
114    * designating ch->cs to G0.
115    */
116 
117   if ((size = designate_to_g0(dst, dst_size - filled_size, is_full, ch->cs)) == 0) {
118     return 0;
119   }
120 
121   dst += size;
122   filled_size += size;
123 
124   /*
125    * appending character bytes.
126    */
127 
128   if (filled_size + ch->size > dst_size) {
129     *is_full = 1;
130 
131     return 0;
132   }
133 
134   if (IS_CS94SB(ch->cs) || IS_CS94MB(ch->cs)) {
135     for (count = 0; count < ch->size; count++) {
136       *(dst++) = ch->ch[count];
137     }
138   } else if (IS_CS96SB(ch->cs) || IS_CS96MB(ch->cs)) {
139     for (count = 0; count < ch->size; count++) {
140       *(dst++) = MAP_TO_GR(ch->ch[count]);
141     }
142   } else {
143     /* error */
144 
145     return 0;
146   }
147 
148   filled_size += ch->size;
149 
150   /*
151    * restoring GL
152    */
153 
154   if (iso2022_conv->gl == &iso2022_conv->g1) {
155     if (filled_size + 1 > dst_size) {
156       *is_full = 1;
157 
158       return 0;
159     }
160 
161     *(dst++) = LS1;
162 
163     filled_size++;
164   } else if (iso2022_conv->gl == &iso2022_conv->g2) {
165     if (filled_size + 2 > dst_size) {
166       *is_full = 1;
167 
168       return 0;
169     }
170 
171     *(dst++) = ESC;
172     *(dst++) = LS2;
173 
174     filled_size += 2;
175   } else if (iso2022_conv->gl == &iso2022_conv->g3) {
176     if (filled_size + 2 > dst_size) {
177       *is_full = 1;
178 
179       return 0;
180     }
181 
182     *(dst++) = ESC;
183     *(dst++) = LS3;
184 
185     filled_size += 2;
186   }
187 
188   /*
189    * restoring G0
190    */
191 
192   if ((size = designate_to_g0(dst, dst_size - filled_size, is_full, iso2022_conv->g0)) == 0) {
193     return 0;
194   }
195 
196   return filled_size + size;
197 }
198 
ef_iso2022_remap_unsupported_charset(ef_char_t * ch)199 void ef_iso2022_remap_unsupported_charset(ef_char_t *ch) {
200   ef_char_t c;
201 
202   if (IS_CS_BASED_ON_ISO2022(ch->cs)) {
203     /* do nothing */
204   } else if (ch->cs == ISO10646_UCS4_1) {
205     if (ef_map_ucs4_to_iso2022cs(&c, ch)) {
206       *ch = c;
207     }
208   } else if (ch->cs == VISCII) {
209     if (ef_map_viscii_to_tcvn5712_3_1993(&c, ch)) {
210       *ch = c;
211     }
212   } else if (ch->cs == KOI8_R) {
213     if (ef_map_koi8_r_to_iso8859_5_r(&c, ch)) {
214       *ch = c;
215     }
216   } else if (ch->cs == KOI8_U) {
217     if (ef_map_koi8_u_to_iso8859_5_r(&c, ch)) {
218       *ch = c;
219     }
220   } else if (ch->cs == KOI8_T) {
221     if (ef_map_koi8_t_to_iso8859_5_r(&c, ch)) {
222       *ch = c;
223     }
224   } else if (ch->cs == GBK) {
225     if (ef_map_gbk_to_gb2312_80(&c, ch)) {
226       *ch = c;
227     }
228   } else {
229     if (ch->cs == JOHAB) {
230       if (!ef_map_johab_to_uhc(&c, ch)) {
231         return;
232       }
233 
234       *ch = c;
235     }
236 
237     if (ch->cs == UHC) {
238       if (ef_map_uhc_to_ksc5601_1987(&c, ch)) {
239         *ch = c;
240       }
241 
242       return;
243     }
244 
245     /* HKSCS includes BIG5 */
246     if (ch->cs == HKSCS) {
247       ch->cs = BIG5;
248     }
249 
250     if (ch->cs == BIG5) {
251       if (ef_map_big5_to_cns11643_1992(&c, ch)) {
252         *ch = c;
253       }
254 
255       return;
256     }
257   }
258 }
259