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