1 /*
2 * "streamable kanji code filter and converter"
3 * Copyright (c) 1998-2002 HappySize, Inc. All rights reserved.
4 *
5 * LICENSE NOTICES
6 *
7 * This file is part of "streamable kanji code filter and converter",
8 * which is distributed under the terms of GNU Lesser General Public
9 * License (version 2) as published by the Free Software Foundation.
10 *
11 * This software is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with "streamable kanji code filter and converter";
18 * if not, write to the Free Software Foundation, Inc., 59 Temple Place,
19 * Suite 330, Boston, MA 02111-1307 USA
20 *
21 * The author of this file:
22 *
23 */
24 /*
25 * The source code included in this files was separated from mbfilter_jis.c
26 * by rui hirokawa <hirokawa@php.net> on 18 aug 2011.
27 *
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "mbfilter.h"
35 #include "mbfilter_iso2022jp_2004.h"
36 #include "mbfilter_sjis_2004.h"
37
38 #include "unicode_table_jis2004.h"
39 #include "unicode_table_jis.h"
40
41 extern int mbfl_filt_conv_any_jis_flush(mbfl_convert_filter *filter);
42 static int mbfl_filt_ident_2022jp_2004(int c, mbfl_identify_filter *filter);
43
44 const mbfl_encoding mbfl_encoding_2022jp_2004 = {
45 mbfl_no_encoding_2022jp_2004,
46 "ISO-2022-JP-2004",
47 "ISO-2022-JP-2004",
48 NULL,
49 NULL,
50 MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE,
51 &vtbl_2022jp_2004_wchar,
52 &vtbl_wchar_2022jp_2004
53 };
54
55 const struct mbfl_identify_vtbl vtbl_identify_2022jp_2004 = {
56 mbfl_no_encoding_2022jp_2004,
57 mbfl_filt_ident_common_ctor,
58 mbfl_filt_ident_common_dtor,
59 mbfl_filt_ident_2022jp_2004
60 };
61
62 const struct mbfl_convert_vtbl vtbl_2022jp_2004_wchar = {
63 mbfl_no_encoding_2022jp_2004,
64 mbfl_no_encoding_wchar,
65 mbfl_filt_conv_common_ctor,
66 mbfl_filt_conv_common_dtor,
67 mbfl_filt_conv_jis2004_wchar,
68 mbfl_filt_conv_common_flush
69 };
70
71 const struct mbfl_convert_vtbl vtbl_wchar_2022jp_2004 = {
72 mbfl_no_encoding_wchar,
73 mbfl_no_encoding_2022jp_2004,
74 mbfl_filt_conv_common_ctor,
75 mbfl_filt_conv_common_dtor,
76 mbfl_filt_conv_wchar_jis2004,
77 mbfl_filt_conv_jis2004_flush
78 };
79
mbfl_filt_ident_2022jp_2004(int c,mbfl_identify_filter * filter)80 static int mbfl_filt_ident_2022jp_2004(int c, mbfl_identify_filter *filter)
81 {
82 retry:
83 switch (filter->status & 0xf) {
84 /* case 0x00: ASCII */
85 /* case 0x80: X 0212 */
86 /* case 0x90: X 0213 plane 1 */
87 /* case 0xa0: X 0213 plane 2 */
88 case 0:
89 if (c == 0x1b) {
90 filter->status += 2;
91 } else if (filter->status == 0x80 && c > 0x20 && c < 0x7f) { /* kanji first char */
92 filter->status += 1;
93 } else if (c >= 0 && c < 0x80) { /* latin, CTLs */
94 ;
95 } else {
96 filter->flag = 1; /* bad */
97 }
98 break;
99
100 /* case 0x81: X 0208 second char */
101 case 1:
102 if (c == 0x1b) {
103 filter->status++;
104 } else {
105 filter->status &= ~0xf;
106 if (c < 0x21 || c > 0x7e) { /* bad */
107 filter->flag = 1;
108 }
109 }
110 break;
111
112 /* ESC */
113 case 2:
114 if (c == 0x24) { /* '$' */
115 filter->status++;
116 } else if (c == 0x28) { /* '(' */
117 filter->status += 3;
118 } else {
119 filter->flag = 1; /* bad */
120 filter->status &= ~0xf;
121 goto retry;
122 }
123 break;
124
125 /* ESC $ */
126 case 3:
127 if (c == 0x42) { /* 'B' */
128 filter->status = 0x80;
129 } else if (c == 0x28) { /* '(' */
130 filter->status++;
131 } else {
132 filter->flag = 1; /* bad */
133 filter->status &= ~0xf;
134 goto retry;
135 }
136 break;
137
138 /* ESC $ ( */
139 case 4:
140 if (c == 0x51) { /* JIS X 0213 plane 1 */
141 filter->status = 0x90;
142 } else if (c == 0x50) { /* JIS X 0213 plane 2 */
143 filter->status = 0xa0;
144 } else {
145 filter->flag = 1; /* bad */
146 filter->status &= ~0xf;
147 goto retry;
148 }
149 break;
150
151 /* ESC ( */
152 case 5:
153 if (c == 0x42) { /* 'B' */
154 filter->status = 0;
155 } else {
156 filter->flag = 1; /* bad */
157 filter->status &= ~0xf;
158 goto retry;
159 }
160 break;
161
162 default:
163 filter->status = 0;
164 break;
165 }
166
167 return c;
168 }
169