1 /* -*- c-basic-offset:2; tab-width:2; indent-tabs-mode:nil -*- */
2
3 #include "ef_euccn_parser.h"
4
5 #include <stdio.h> /* NULL */
6 #include <pobl/bl_debug.h>
7 #include <pobl/bl_str.h>
8
9 #include "ef_iso2022_parser.h"
10 #include "ef_gb18030_2000_intern.h"
11 #include "ef_ucs_property.h"
12
13 #if 0
14 #define __DEBUG
15 #endif
16
17 /* --- static functions --- */
18
gbk_parser_next_char_intern(ef_parser_t * parser,ef_char_t * ch,int is_gb18030)19 static int gbk_parser_next_char_intern(ef_parser_t *parser, ef_char_t *ch, int is_gb18030) {
20 if (parser->is_eos) {
21 return 0;
22 }
23
24 ef_parser_mark(parser);
25
26 if (/* 0x00 <= *parser->str && */ *parser->str <= 0x80) {
27 ch->ch[0] = *parser->str;
28 ch->cs = US_ASCII;
29 ch->size = 1;
30 ch->property = 0;
31
32 ef_parser_increment(parser);
33
34 return 1;
35 } else {
36 u_char bytes[4];
37 u_char ucs4[4];
38
39 if (is_gb18030) {
40 if (0x81 <= *parser->str && *parser->str <= 0xa0) {
41 bytes[0] = *parser->str;
42
43 if (ef_parser_increment(parser) == 0) {
44 goto shortage;
45 }
46
47 if (0x30 <= *parser->str && *parser->str <= 0x39) {
48 goto is_4_bytes;
49 }
50 } else if (0xa1 <= *parser->str && *parser->str <= 0xfe) {
51 bytes[0] = *parser->str;
52
53 if (ef_parser_increment(parser) == 0) {
54 goto shortage;
55 }
56
57 if (0x30 <= *parser->str && *parser->str <= 0x39) {
58 goto is_4_bytes;
59 }
60 } else {
61 #ifdef DEBUG
62 bl_warn_printf(BL_DEBUG_TAG " illegal GBK format. [%x ...]\n", *parser->str);
63 #endif
64
65 goto error;
66 }
67 } else {
68 bytes[0] = *parser->str;
69
70 if (ef_parser_increment(parser) == 0) {
71 goto shortage;
72 }
73 }
74
75 ch->ch[0] = bytes[0];
76
77 if (*parser->str < 0x40) {
78 #ifdef DEBUG
79 bl_warn_printf(BL_DEBUG_TAG " illegal GBK format. [%.2x%.2x ...]\n", bytes[0], *parser->str);
80 #endif
81
82 goto error;
83 }
84
85 ch->ch[1] = *parser->str;
86 ch->size = 2;
87 ch->cs = GBK;
88 ch->property = 0;
89
90 ef_parser_increment(parser);
91
92 return 1;
93
94 is_4_bytes:
95 bytes[1] = *parser->str;
96
97 if (ef_parser_increment(parser) == 0) {
98 goto shortage;
99 }
100
101 if (*parser->str < 0x81 || 0xfe < *parser->str) {
102 #ifdef DEBUG
103 bl_warn_printf(BL_DEBUG_TAG " illegal GBK format. [%.2x%.2x%.2x ...]\n", bytes[0], bytes[1],
104 *parser->str);
105 #endif
106
107 goto error;
108 }
109
110 bytes[2] = *parser->str;
111
112 if (ef_parser_increment(parser) == 0) {
113 goto shortage;
114 }
115
116 if (*parser->str < 0x30 || 0x39 < *parser->str) {
117 #ifdef DEBUG
118 bl_warn_printf(BL_DEBUG_TAG " illegal GBK format. [%.2x%.2x%.2x%.2x]\n", bytes[0], bytes[1],
119 bytes[2], *parser->str);
120 #endif
121
122 goto error;
123 }
124
125 bytes[3] = *parser->str;
126
127 ef_parser_increment(parser);
128
129 if (ef_decode_gb18030_2000_to_ucs4(ucs4, bytes) == 0) {
130 goto error;
131 }
132
133 memcpy(ch->ch, ucs4, 4);
134 ch->size = 4;
135 ch->cs = ISO10646_UCS4_1;
136 ch->property = 0;
137
138 return 1;
139 }
140
141 error:
142 shortage:
143 ef_parser_reset(parser);
144
145 return 0;
146 }
147
gbk_parser_next_char(ef_parser_t * parser,ef_char_t * ch)148 static int gbk_parser_next_char(ef_parser_t *parser, ef_char_t *ch) {
149 return gbk_parser_next_char_intern(parser, ch, 0);
150 }
151
gb18030_parser_next_char(ef_parser_t * parser,ef_char_t * ch)152 static int gb18030_parser_next_char(ef_parser_t *parser, ef_char_t *ch) {
153 return gbk_parser_next_char_intern(parser, ch, 1);
154 }
155
euccn_parser_init_intern(ef_parser_t * parser,ef_charset_t g1_cs)156 static void euccn_parser_init_intern(ef_parser_t *parser, ef_charset_t g1_cs) {
157 ef_iso2022_parser_t *iso2022_parser;
158
159 ef_parser_init(parser);
160
161 iso2022_parser = (ef_iso2022_parser_t *)parser;
162
163 iso2022_parser->g0 = US_ASCII;
164 iso2022_parser->g1 = g1_cs;
165 iso2022_parser->g2 = UNKNOWN_CS;
166 iso2022_parser->g3 = UNKNOWN_CS;
167
168 iso2022_parser->gl = &iso2022_parser->g0;
169 iso2022_parser->gr = &iso2022_parser->g1;
170
171 iso2022_parser->non_iso2022_cs = UNKNOWN_CS;
172
173 iso2022_parser->is_single_shifted = 0;
174 }
175
euccn_parser_init(ef_parser_t * parser)176 static void euccn_parser_init(ef_parser_t *parser) { euccn_parser_init_intern(parser, GB2312_80); }
177
178 /*
179 * shared by gbk and gbk18030_2000
180 */
gbk_parser_init(ef_parser_t * parser)181 static void gbk_parser_init(ef_parser_t *parser) { euccn_parser_init_intern(parser, GBK); }
182
gbk_parser_new(void (* init)(struct ef_parser *),int (* next_char)(struct ef_parser *,ef_char_t *))183 static ef_parser_t *gbk_parser_new(void (*init)(struct ef_parser *),
184 int (*next_char)(struct ef_parser *, ef_char_t *)) {
185 ef_iso2022_parser_t *iso2022_parser;
186
187 if ((iso2022_parser = ef_iso2022_parser_new()) == NULL) {
188 return NULL;
189 }
190
191 (*init)((ef_parser_t *)iso2022_parser);
192
193 /* override */
194 iso2022_parser->parser.init = init;
195 iso2022_parser->parser.next_char = next_char;
196
197 return (ef_parser_t *)iso2022_parser;
198 }
199
200 /* --- global functions --- */
201
ef_euccn_parser_new(void)202 ef_parser_t *ef_euccn_parser_new(void) {
203 ef_iso2022_parser_t *iso2022_parser;
204
205 if ((iso2022_parser = ef_iso2022_parser_new()) == NULL) {
206 return NULL;
207 }
208
209 euccn_parser_init((ef_parser_t *)iso2022_parser);
210
211 /* override */
212 iso2022_parser->parser.init = euccn_parser_init;
213
214 return (ef_parser_t *)iso2022_parser;
215 }
216
ef_gbk_parser_new(void)217 ef_parser_t *ef_gbk_parser_new(void) {
218 return gbk_parser_new(gbk_parser_init, gbk_parser_next_char);
219 }
220
ef_gb18030_2000_parser_new(void)221 ef_parser_t *ef_gb18030_2000_parser_new(void) {
222 return gbk_parser_new(gbk_parser_init, gb18030_parser_next_char);
223 }
224