Annotation of embedaddon/libiconv/lib/iso2022_jp.h, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc.
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.
17: * If not, write to the Free Software Foundation, Inc., 51 Franklin Street,
18: * Fifth Floor, Boston, MA 02110-1301, USA.
19: */
20:
21: /*
22: * ISO-2022-JP
23: */
24:
25: /* Specification: RFC 1468 */
26:
27: #define ESC 0x1b
28:
29: /*
30: * The state can be one of the following values.
31: */
32: #define STATE_ASCII 0
33: #define STATE_JISX0201ROMAN 1
34: #define STATE_JISX0208 2
35:
36: static int
37: iso2022_jp_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n)
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: goto ilseq;
74: }
75: goto ilseq;
76: }
77: break;
78: }
79: switch (state) {
80: case STATE_ASCII:
81: if (c < 0x80) {
82: int ret = ascii_mbtowc(conv,pwc,s,1);
83: if (ret == RET_ILSEQ)
84: goto ilseq;
85: if (ret != 1) abort();
86: conv->istate = state;
87: return count+1;
88: } else
89: goto ilseq;
90: case STATE_JISX0201ROMAN:
91: if (c < 0x80) {
92: int ret = jisx0201_mbtowc(conv,pwc,s,1);
93: if (ret == RET_ILSEQ)
94: goto ilseq;
95: if (ret != 1) abort();
96: conv->istate = state;
97: return count+1;
98: } else
99: goto ilseq;
100: case STATE_JISX0208:
101: if (n < count+2)
102: goto none;
103: if (s[0] < 0x80 && s[1] < 0x80) {
104: int ret = jisx0208_mbtowc(conv,pwc,s,2);
105: if (ret == RET_ILSEQ)
106: goto ilseq;
107: if (ret != 2) abort();
108: conv->istate = state;
109: return count+2;
110: } else
111: goto ilseq;
112: default: abort();
113: }
114:
115: none:
116: conv->istate = state;
117: return RET_TOOFEW(count);
118:
119: ilseq:
120: conv->istate = state;
121: return RET_SHIFT_ILSEQ(count);
122: }
123:
124: static int
125: iso2022_jp_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n)
126: {
127: state_t state = conv->ostate;
128: unsigned char buf[2];
129: int ret;
130:
131: /* Try ASCII. */
132: ret = ascii_wctomb(conv,buf,wc,1);
133: if (ret != RET_ILUNI) {
134: if (ret != 1) abort();
135: if (buf[0] < 0x80) {
136: int count = (state == STATE_ASCII ? 1 : 4);
137: if (n < count)
138: return RET_TOOSMALL;
139: if (state != STATE_ASCII) {
140: r[0] = ESC;
141: r[1] = '(';
142: r[2] = 'B';
143: r += 3;
144: state = STATE_ASCII;
145: }
146: r[0] = buf[0];
147: conv->ostate = state;
148: return count;
149: }
150: }
151:
152: /* Try JIS X 0201-1976 Roman. */
153: ret = jisx0201_wctomb(conv,buf,wc,1);
154: if (ret != RET_ILUNI) {
155: if (ret != 1) abort();
156: if (buf[0] < 0x80) {
157: int count = (state == STATE_JISX0201ROMAN ? 1 : 4);
158: if (n < count)
159: return RET_TOOSMALL;
160: if (state != STATE_JISX0201ROMAN) {
161: r[0] = ESC;
162: r[1] = '(';
163: r[2] = 'J';
164: r += 3;
165: state = STATE_JISX0201ROMAN;
166: }
167: r[0] = buf[0];
168: conv->ostate = state;
169: return count;
170: }
171: }
172:
173: /* Try JIS X 0208-1990 in place of JIS X 0208-1978 and JIS X 0208-1983. */
174: ret = jisx0208_wctomb(conv,buf,wc,2);
175: if (ret != RET_ILUNI) {
176: if (ret != 2) abort();
177: if (buf[0] < 0x80 && buf[1] < 0x80) {
178: int count = (state == STATE_JISX0208 ? 2 : 5);
179: if (n < count)
180: return RET_TOOSMALL;
181: if (state != STATE_JISX0208) {
182: r[0] = ESC;
183: r[1] = '$';
184: r[2] = 'B';
185: r += 3;
186: state = STATE_JISX0208;
187: }
188: r[0] = buf[0];
189: r[1] = buf[1];
190: conv->ostate = state;
191: return count;
192: }
193: }
194:
195: return RET_ILUNI;
196: }
197:
198: static int
199: iso2022_jp_reset (conv_t conv, unsigned char *r, int n)
200: {
201: state_t state = conv->ostate;
202: if (state != STATE_ASCII) {
203: if (n < 3)
204: return RET_TOOSMALL;
205: r[0] = ESC;
206: r[1] = '(';
207: r[2] = 'B';
208: /* conv->ostate = 0; will be done by the caller */
209: return 3;
210: } else
211: return 0;
212: }
213:
214: #undef STATE_JISX0208
215: #undef STATE_JISX0201ROMAN
216: #undef STATE_ASCII
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>