Annotation of embedaddon/libiconv/lib/iso2022_jp1.h, revision 1.1.1.2
1.1 misho 1: /*
1.1.1.2 ! misho 2: * Copyright (C) 1999-2001, 2008, 2016 Free Software Foundation, Inc.
1.1 misho 3: * This file is part of the GNU LIBICONV Library.
4: *
5: * The GNU LIBICONV Library is free software; you can redistribute it
6: * and/or modify it under the terms of the GNU Library General Public
7: * License as published by the Free Software Foundation; either version 2
8: * of the License, or (at your option) any later version.
9: *
10: * The GNU LIBICONV Library is distributed in the hope that it will be
11: * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Library General Public License for more details.
14: *
15: * You should have received a copy of the GNU Library General Public
16: * License along with the GNU LIBICONV Library; see the file COPYING.LIB.
1.1.1.2 ! misho 17: * If not, see <https://www.gnu.org/licenses/>.
1.1 misho 18: */
19:
20: /*
21: * ISO-2022-JP-1
22: */
23:
24: /* Specification: RFC 2237 */
25:
26: #define ESC 0x1b
27:
28: /*
29: * The state can be one of the following values.
30: */
31: #define STATE_ASCII 0
32: #define STATE_JISX0201ROMAN 1
33: #define STATE_JISX0208 2
34: #define STATE_JISX0212 3
35:
36: static int
1.1.1.2 ! misho 37: iso2022_jp1_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
1.1 misho 38: {
39: state_t state = conv->istate;
40: int count = 0;
41: unsigned char c;
42: for (;;) {
43: c = *s;
44: if (c == ESC) {
45: if (n < count+3)
46: goto none;
47: if (s[1] == '(') {
48: if (s[2] == 'B') {
49: state = STATE_ASCII;
50: s += 3; count += 3;
51: if (n < count+1)
52: goto none;
53: continue;
54: }
55: if (s[2] == 'J') {
56: state = STATE_JISX0201ROMAN;
57: s += 3; count += 3;
58: if (n < count+1)
59: goto none;
60: continue;
61: }
62: goto ilseq;
63: }
64: if (s[1] == '$') {
65: if (s[2] == '@' || s[2] == 'B') {
66: /* We don't distinguish JIS X 0208-1978 and JIS X 0208-1983. */
67: state = STATE_JISX0208;
68: s += 3; count += 3;
69: if (n < count+1)
70: goto none;
71: continue;
72: }
73: if (s[2] == '(') {
74: if (n < count+4)
75: goto none;
76: if (s[3] == 'D') {
77: state = STATE_JISX0212;
78: s += 4; count += 4;
79: if (n < count+1)
80: goto none;
81: continue;
82: }
83: }
84: goto ilseq;
85: }
86: goto ilseq;
87: }
88: break;
89: }
90: switch (state) {
91: case STATE_ASCII:
92: if (c < 0x80) {
93: int ret = ascii_mbtowc(conv,pwc,s,1);
94: if (ret == RET_ILSEQ)
95: goto ilseq;
96: if (ret != 1) abort();
97: conv->istate = state;
98: return count+1;
99: } else
100: goto ilseq;
101: case STATE_JISX0201ROMAN:
102: if (c < 0x80) {
103: int ret = jisx0201_mbtowc(conv,pwc,s,1);
104: if (ret == RET_ILSEQ)
105: goto ilseq;
106: if (ret != 1) abort();
107: conv->istate = state;
108: return count+1;
109: } else
110: goto ilseq;
111: case STATE_JISX0208:
112: if (n < count+2)
113: goto none;
114: if (s[0] < 0x80 && s[1] < 0x80) {
115: int ret = jisx0208_mbtowc(conv,pwc,s,2);
116: if (ret == RET_ILSEQ)
117: goto ilseq;
118: if (ret != 2) abort();
119: conv->istate = state;
120: return count+2;
121: } else
122: goto ilseq;
123: case STATE_JISX0212:
124: if (n < count+2)
125: goto none;
126: if (s[0] < 0x80 && s[1] < 0x80) {
127: int ret = jisx0212_mbtowc(conv,pwc,s,2);
128: if (ret == RET_ILSEQ)
129: goto ilseq;
130: if (ret != 2) abort();
131: conv->istate = state;
132: return count+2;
133: } else
134: goto ilseq;
135: default: abort();
136: }
137:
138: none:
139: conv->istate = state;
140: return RET_TOOFEW(count);
141:
142: ilseq:
143: conv->istate = state;
144: return RET_SHIFT_ILSEQ(count);
145: }
146:
147: static int
1.1.1.2 ! misho 148: iso2022_jp1_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, size_t n)
1.1 misho 149: {
150: state_t state = conv->ostate;
151: unsigned char buf[2];
152: int ret;
153:
154: /* Try ASCII. */
155: ret = ascii_wctomb(conv,buf,wc,1);
156: if (ret != RET_ILUNI) {
157: if (ret != 1) abort();
158: if (buf[0] < 0x80) {
159: int count = (state == STATE_ASCII ? 1 : 4);
160: if (n < count)
161: return RET_TOOSMALL;
162: if (state != STATE_ASCII) {
163: r[0] = ESC;
164: r[1] = '(';
165: r[2] = 'B';
166: r += 3;
167: state = STATE_ASCII;
168: }
169: r[0] = buf[0];
170: conv->ostate = state;
171: return count;
172: }
173: }
174:
175: /* Try JIS X 0201-1976 Roman. */
176: ret = jisx0201_wctomb(conv,buf,wc,1);
177: if (ret != RET_ILUNI) {
178: if (ret != 1) abort();
179: if (buf[0] < 0x80) {
180: int count = (state == STATE_JISX0201ROMAN ? 1 : 4);
181: if (n < count)
182: return RET_TOOSMALL;
183: if (state != STATE_JISX0201ROMAN) {
184: r[0] = ESC;
185: r[1] = '(';
186: r[2] = 'J';
187: r += 3;
188: state = STATE_JISX0201ROMAN;
189: }
190: r[0] = buf[0];
191: conv->ostate = state;
192: return count;
193: }
194: }
195:
196: /* Try JIS X 0208-1990 in place of JIS X 0208-1978 and JIS X 0208-1983. */
197: ret = jisx0208_wctomb(conv,buf,wc,2);
198: if (ret != RET_ILUNI) {
199: if (ret != 2) abort();
200: if (buf[0] < 0x80 && buf[1] < 0x80) {
201: int count = (state == STATE_JISX0208 ? 2 : 5);
202: if (n < count)
203: return RET_TOOSMALL;
204: if (state != STATE_JISX0208) {
205: r[0] = ESC;
206: r[1] = '$';
207: r[2] = 'B';
208: r += 3;
209: state = STATE_JISX0208;
210: }
211: r[0] = buf[0];
212: r[1] = buf[1];
213: conv->ostate = state;
214: return count;
215: }
216: }
217:
218: /* Try JIS X 0212-1990. */
219: ret = jisx0212_wctomb(conv,buf,wc,2);
220: if (ret != RET_ILUNI) {
221: if (ret != 2) abort();
222: if (buf[0] < 0x80 && buf[1] < 0x80) {
223: int count = (state == STATE_JISX0212 ? 2 : 6);
224: if (n < count)
225: return RET_TOOSMALL;
226: if (state != STATE_JISX0212) {
227: r[0] = ESC;
228: r[1] = '$';
229: r[2] = '(';
230: r[3] = 'D';
231: r += 4;
232: state = STATE_JISX0212;
233: }
234: r[0] = buf[0];
235: r[1] = buf[1];
236: conv->ostate = state;
237: return count;
238: }
239: }
240:
241: return RET_ILUNI;
242: }
243:
244: static int
1.1.1.2 ! misho 245: iso2022_jp1_reset (conv_t conv, unsigned char *r, size_t n)
1.1 misho 246: {
247: state_t state = conv->ostate;
248: if (state != STATE_ASCII) {
249: if (n < 3)
250: return RET_TOOSMALL;
251: r[0] = ESC;
252: r[1] = '(';
253: r[2] = 'B';
254: /* conv->ostate = 0; will be done by the caller */
255: return 3;
256: } else
257: return 0;
258: }
259:
260: #undef STATE_JISX0212
261: #undef STATE_JISX0208
262: #undef STATE_JISX0201ROMAN
263: #undef STATE_ASCII
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>