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