Annotation of embedaddon/libiconv/lib/iso2022_jp.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
22: */
23:
24: /* Specification: RFC 1468 */
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:
35: static int
1.1.1.2 ! misho 36: iso2022_jp_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
1.1 misho 37: {
38: state_t state = conv->istate;
39: int count = 0;
40: unsigned char c;
41: for (;;) {
42: c = *s;
43: if (c == ESC) {
44: if (n < count+3)
45: goto none;
46: if (s[1] == '(') {
47: if (s[2] == 'B') {
48: state = STATE_ASCII;
49: s += 3; count += 3;
50: if (n < count+1)
51: goto none;
52: continue;
53: }
54: if (s[2] == 'J') {
55: state = STATE_JISX0201ROMAN;
56: s += 3; count += 3;
57: if (n < count+1)
58: goto none;
59: continue;
60: }
61: goto ilseq;
62: }
63: if (s[1] == '$') {
64: if (s[2] == '@' || s[2] == 'B') {
65: /* We don't distinguish JIS X 0208-1978 and JIS X 0208-1983. */
66: state = STATE_JISX0208;
67: s += 3; count += 3;
68: if (n < count+1)
69: goto none;
70: continue;
71: }
72: goto ilseq;
73: }
74: goto ilseq;
75: }
76: break;
77: }
78: switch (state) {
79: case STATE_ASCII:
80: if (c < 0x80) {
81: int ret = ascii_mbtowc(conv,pwc,s,1);
82: if (ret == RET_ILSEQ)
83: goto ilseq;
84: if (ret != 1) abort();
85: conv->istate = state;
86: return count+1;
87: } else
88: goto ilseq;
89: case STATE_JISX0201ROMAN:
90: if (c < 0x80) {
91: int ret = jisx0201_mbtowc(conv,pwc,s,1);
92: if (ret == RET_ILSEQ)
93: goto ilseq;
94: if (ret != 1) abort();
95: conv->istate = state;
96: return count+1;
97: } else
98: goto ilseq;
99: case STATE_JISX0208:
100: if (n < count+2)
101: goto none;
102: if (s[0] < 0x80 && s[1] < 0x80) {
103: int ret = jisx0208_mbtowc(conv,pwc,s,2);
104: if (ret == RET_ILSEQ)
105: goto ilseq;
106: if (ret != 2) abort();
107: conv->istate = state;
108: return count+2;
109: } else
110: goto ilseq;
111: default: abort();
112: }
113:
114: none:
115: conv->istate = state;
116: return RET_TOOFEW(count);
117:
118: ilseq:
119: conv->istate = state;
120: return RET_SHIFT_ILSEQ(count);
121: }
122:
123: static int
1.1.1.2 ! misho 124: iso2022_jp_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, size_t n)
1.1 misho 125: {
126: state_t state = conv->ostate;
127: unsigned char buf[2];
128: int ret;
129:
130: /* Try ASCII. */
131: ret = ascii_wctomb(conv,buf,wc,1);
132: if (ret != RET_ILUNI) {
133: if (ret != 1) abort();
134: if (buf[0] < 0x80) {
135: int count = (state == STATE_ASCII ? 1 : 4);
136: if (n < count)
137: return RET_TOOSMALL;
138: if (state != STATE_ASCII) {
139: r[0] = ESC;
140: r[1] = '(';
141: r[2] = 'B';
142: r += 3;
143: state = STATE_ASCII;
144: }
145: r[0] = buf[0];
146: conv->ostate = state;
147: return count;
148: }
149: }
150:
151: /* Try JIS X 0201-1976 Roman. */
152: ret = jisx0201_wctomb(conv,buf,wc,1);
153: if (ret != RET_ILUNI) {
154: if (ret != 1) abort();
155: if (buf[0] < 0x80) {
156: int count = (state == STATE_JISX0201ROMAN ? 1 : 4);
157: if (n < count)
158: return RET_TOOSMALL;
159: if (state != STATE_JISX0201ROMAN) {
160: r[0] = ESC;
161: r[1] = '(';
162: r[2] = 'J';
163: r += 3;
164: state = STATE_JISX0201ROMAN;
165: }
166: r[0] = buf[0];
167: conv->ostate = state;
168: return count;
169: }
170: }
171:
172: /* Try JIS X 0208-1990 in place of JIS X 0208-1978 and JIS X 0208-1983. */
173: ret = jisx0208_wctomb(conv,buf,wc,2);
174: if (ret != RET_ILUNI) {
175: if (ret != 2) abort();
176: if (buf[0] < 0x80 && buf[1] < 0x80) {
177: int count = (state == STATE_JISX0208 ? 2 : 5);
178: if (n < count)
179: return RET_TOOSMALL;
180: if (state != STATE_JISX0208) {
181: r[0] = ESC;
182: r[1] = '$';
183: r[2] = 'B';
184: r += 3;
185: state = STATE_JISX0208;
186: }
187: r[0] = buf[0];
188: r[1] = buf[1];
189: conv->ostate = state;
190: return count;
191: }
192: }
193:
194: return RET_ILUNI;
195: }
196:
197: static int
1.1.1.2 ! misho 198: iso2022_jp_reset (conv_t conv, unsigned char *r, size_t n)
1.1 misho 199: {
200: state_t state = conv->ostate;
201: if (state != STATE_ASCII) {
202: if (n < 3)
203: return RET_TOOSMALL;
204: r[0] = ESC;
205: r[1] = '(';
206: r[2] = 'B';
207: /* conv->ostate = 0; will be done by the caller */
208: return 3;
209: } else
210: return 0;
211: }
212:
213: #undef STATE_JISX0208
214: #undef STATE_JISX0201ROMAN
215: #undef STATE_ASCII
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>