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_jis.h"
39 
40 extern int mbfl_filt_conv_any_jis_flush(mbfl_convert_filter *filter);
41 static int mbfl_filt_ident_2022jp_2004(int c, mbfl_identify_filter *filter);
42 
43 const mbfl_encoding mbfl_encoding_2022jp_2004 = {
44 	mbfl_no_encoding_2022jp_2004,
45 	"ISO-2022-JP-2004",
46 	"ISO-2022-JP-2004",
47 	NULL,
48 	NULL,
49 	MBFL_ENCTYPE_MBCS | MBFL_ENCTYPE_SHFTCODE | MBFL_ENCTYPE_GL_UNSAFE,
50 	&vtbl_2022jp_2004_wchar,
51 	&vtbl_wchar_2022jp_2004
52 };
53 
54 const struct mbfl_identify_vtbl vtbl_identify_2022jp_2004 = {
55 	mbfl_no_encoding_2022jp_2004,
56 	mbfl_filt_ident_common_ctor,
57 	mbfl_filt_ident_common_dtor,
58 	mbfl_filt_ident_2022jp_2004
59 };
60 
61 const struct mbfl_convert_vtbl vtbl_2022jp_2004_wchar = {
62 	mbfl_no_encoding_2022jp_2004,
63 	mbfl_no_encoding_wchar,
64 	mbfl_filt_conv_common_ctor,
65 	mbfl_filt_conv_common_dtor,
66 	mbfl_filt_conv_jis2004_wchar,
67 	mbfl_filt_conv_common_flush
68 };
69 
70 const struct mbfl_convert_vtbl vtbl_wchar_2022jp_2004 = {
71 	mbfl_no_encoding_wchar,
72 	mbfl_no_encoding_2022jp_2004,
73 	mbfl_filt_conv_common_ctor,
74 	mbfl_filt_conv_common_dtor,
75 	mbfl_filt_conv_wchar_jis2004,
76 	mbfl_filt_conv_jis2004_flush
77 };
78 
mbfl_filt_ident_2022jp_2004(int c,mbfl_identify_filter * filter)79 static int mbfl_filt_ident_2022jp_2004(int c, mbfl_identify_filter *filter)
80 {
81 retry:
82 	switch (filter->status & 0xf) {
83 /*	case 0x00:	 ASCII */
84 /*	case 0x80:	 X 0212 */
85 /*	case 0x90:	 X 0213 plane 1 */
86 /*	case 0xa0:	 X 0213 plane 2 */
87 	case 0:
88 		if (c == 0x1b) {
89 			filter->status += 2;
90 		} else if (filter->status == 0x80 && c > 0x20 && c < 0x7f) {		/* kanji first char */
91 			filter->status += 1;
92 		} else if (c >= 0 && c < 0x80) {		/* latin, CTLs */
93 			;
94 		} else {
95 			filter->flag = 1;	/* bad */
96 		}
97 		break;
98 
99 /*	case 0x81:	 X 0208 second char */
100 	case 1:
101 		if (c == 0x1b) {
102 			filter->status++;
103 		} else {
104 			filter->status &= ~0xf;
105 			if (c < 0x21 || c > 0x7e) {		/* bad */
106 				filter->flag = 1;
107 			}
108 		}
109 		break;
110 
111 	/* ESC */
112 	case 2:
113 		if (c == 0x24) {		/* '$' */
114 			filter->status++;
115 		} else if (c == 0x28) {		/* '(' */
116 			filter->status += 3;
117 		} else {
118 			filter->flag = 1;	/* bad */
119 			filter->status &= ~0xf;
120 			goto retry;
121 		}
122 		break;
123 
124 	/* ESC $ */
125 	case 3:
126 		if (c == 0x42) {		/* 'B' */
127 			filter->status = 0x80;
128 		} else if (c == 0x28) {		/* '(' */
129 			filter->status++;
130 		} else {
131 			filter->flag = 1;	/* bad */
132 			filter->status &= ~0xf;
133 			goto retry;
134 		}
135 		break;
136 
137 	/* ESC $ ( */
138 	case 4:
139 		if (c == 0x51) {		/* JIS X 0213 plane 1 */
140 			filter->status = 0x90;
141 		} else if (c == 0x50) {		/* JIS X 0213 plane 2 */
142 			filter->status = 0xa0;
143 		} else {
144 			filter->flag = 1;	/* bad */
145 			filter->status &= ~0xf;
146 			goto retry;
147 		}
148 		break;
149 
150 	/* ESC ( */
151 	case 5:
152 		if (c == 0x42) {		/* 'B' */
153 			filter->status = 0;
154 		} else {
155 			filter->flag = 1;	/* bad */
156 			filter->status &= ~0xf;
157 			goto retry;
158 		}
159 		break;
160 
161 	default:
162 		filter->status = 0;
163 		break;
164 	}
165 
166 	return c;
167 }
168