blob: cc0e81c84447f84447461cabf6fc497798194c4e [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.awt.motif;
27
28import java.nio.CharBuffer;
29import java.nio.ByteBuffer;
30import java.nio.charset.*;
31import sun.nio.cs.ext.EUC_TW;
32
33public abstract class X11CNS11643 extends Charset {
34 private final int plane;
35 public X11CNS11643 (int plane, String name) {
36 super(name, null);
37 switch (plane) {
38 case 1:
39 this.plane = 0; // CS1
40 break;
41 case 2:
42 case 3:
43 this.plane = plane;
44 break;
45 default:
46 throw new IllegalArgumentException
47 ("Only planes 1, 2, and 3 supported");
48 }
49 }
50
51 public CharsetEncoder newEncoder() {
52 return new Encoder(this, plane);
53 }
54
55 public CharsetDecoder newDecoder() {
56 return new Decoder(this, plane);
57 }
58
59 public boolean contains(Charset cs) {
60 return cs instanceof X11CNS11643;
61 }
62
63 private class Encoder extends EUC_TW.Encoder {
64 private int plane;
65 public Encoder(Charset cs, int plane) {
66 super(cs);
67 this.plane = plane;
68 }
69 public boolean canEncode(char c) {
70 if (c <= 0x7F) {
71 return false;
72 }
73 int p = getNative(c) >> 16;
74 if (p == 1 && plane == 0 ||
75 p == 2 && plane == 2 ||
76 p == 3 && plane == 3)
77 return true;
78 return false;
79 }
80
81 public boolean isLegalReplacement(byte[] repl) {
82 return true;
83 }
84
85 protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) {
86 char[] sa = src.array();
87 int sp = src.arrayOffset() + src.position();
88 int sl = src.arrayOffset() + src.limit();
89 byte[] da = dst.array();
90 int dp = dst.arrayOffset() + dst.position();
91 int dl = dst.arrayOffset() + dst.limit();
92
93 try {
94 while (sp < sl) {
95 char c = sa[sp];
96 if (c >= '\uFFFE' || c <= '\u007f')
97 return CoderResult.unmappableForLength(1);
98 int cns = getNative(c);
99 int p = cns >> 16;
100 if (p == 1 && plane == 0 ||
101 p == 2 && plane == 2 ||
102 p == 3 && plane == 3) {
103 if (dl - dp < 2)
104 return CoderResult.OVERFLOW;
105 da[dp++] = (byte) ((cns >> 8) & 0x7f);
106 da[dp++] = (byte) (cns & 0x7f);
107 sp++;
108 continue;
109 }
110 return CoderResult.unmappableForLength(1);
111 }
112 return CoderResult.UNDERFLOW;
113 } finally {
114 src.position(sp - src.arrayOffset());
115 dst.position(dp - dst.arrayOffset());
116 }
117 }
118 }
119
120 private class Decoder extends EUC_TW.Decoder {
121 private String table;
122 protected Decoder(Charset cs, int plane) {
123 super(cs);
124 switch (plane) {
125 case 0:
126 table = unicodeCNS1;
127 break;
128 case 2:
129 table = unicodeCNS2;
130 break;
131 case 3:
132 table = unicodeCNS3;
133 break;
134 default:
135 throw new IllegalArgumentException
136 ("Only planes 1, 2, and 3 supported");
137 }
138 }
139
140 //we only work on array backed buffer.
141 protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {
142 byte[] sa = src.array();
143 int sp = src.arrayOffset() + src.position();
144 int sl = src.arrayOffset() + src.limit();
145 assert (sp <= sl);
146 sp = (sp <= sl ? sp : sl);
147
148 char[] da = dst.array();
149 int dp = dst.arrayOffset() + dst.position();
150 int dl = dst.arrayOffset() + dst.limit();
151 assert (dp <= dl);
152 dp = (dp <= dl ? dp : dl);
153
154 try {
155 while (sp < sl) {
156 if ( sl - sp < 2) {
157 return CoderResult.UNDERFLOW;
158 }
159 byte b1 = sa[sp];
160 byte b2 = sa[sp + 1];
161 char c = convToUnicode((byte)(b1 | 0x80),
162 (byte)(b2 | 0x80),
163 table);
164 if (c == replacement().charAt(0)
165 //to keep the compatibility with b2cX11CNS11643
166 /*|| c == '\u0000'*/) {
167 return CoderResult.unmappableForLength(2);
168 }
169 if (dl - dp < 1)
170 return CoderResult.OVERFLOW;
171 da[dp++] = c;
172 sp +=2;
173 }
174 return CoderResult.UNDERFLOW;
175 } finally {
176 src.position(sp - src.arrayOffset());
177 dst.position(dp - dst.arrayOffset());
178 }
179 }
180 }
181}