001: /*
002: * Copyright 1996-2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.io;
027:
028: import sun.nio.cs.ext.EUC_TW;
029:
030: /*
031: * @author Limin Shi
032: */
033:
034: public class CharToByteEUC_TW extends CharToByteConverter {
035: private final byte MSB = (byte) 0x80;
036: private final byte SS2 = (byte) 0x8E;
037: private final byte P2 = (byte) 0xA2;
038: private final byte P3 = (byte) 0xA3;
039:
040: private final static EUC_TW nioCoder = new EUC_TW();
041:
042: private static String uniTab1 = nioCoder.getUniTab1();
043: private static String uniTab2 = nioCoder.getUniTab2();
044: private static String uniTab3 = nioCoder.getUniTab3();
045: private static String cnsTab1 = nioCoder.getCNSTab1();
046: private static String cnsTab2 = nioCoder.getCNSTab2();
047: private static String cnsTab3 = nioCoder.getCNSTab3();
048:
049: public int flush(byte[] output, int outStart, int outEnd)
050: throws MalformedInputException {
051: reset();
052: return 0;
053: }
054:
055: public void reset() {
056: byteOff = charOff = 0;
057: }
058:
059: public boolean canConvert(char ch) {
060: if (((0xFF00 & ch) != 0) && (getNative(ch) != -1)) {
061: return true;
062: }
063: return false;
064: }
065:
066: /**
067: * Character conversion
068: */
069: public int convert(char[] input, int inOff, int inEnd,
070: byte[] output, int outOff, int outEnd)
071: throws UnknownCharacterException, MalformedInputException,
072: ConversionBufferFullException {
073: int outputSize;
074: byte[] tmpbuf = new byte[4];
075: byte[] outputByte;
076:
077: byteOff = outOff;
078:
079: //Fixed 4122961 by bringing the charOff++ out to this
080: // loop where it belongs, changing the loop from
081: // while(){} to for(){}.
082: for (charOff = inOff; charOff < inEnd; charOff++) {
083: outputByte = tmpbuf;
084: if (input[charOff] < 0x80) { // ASCII
085: outputSize = 1;
086: outputByte[0] = (byte) (input[charOff] & 0x7f);
087: } else {
088: outputSize = unicodeToEUC(input[charOff], outputByte);
089: }
090:
091: if (outputSize == -1) {
092: if (subMode) {
093: outputByte = subBytes;
094: outputSize = subBytes.length;
095: } else {
096: badInputLength = 1;
097: throw new UnknownCharacterException();
098: }
099: }
100:
101: if (outEnd - byteOff < outputSize)
102: throw new ConversionBufferFullException();
103:
104: for (int i = 0; i < outputSize; i++)
105: output[byteOff++] = outputByte[i];
106: }
107:
108: return byteOff - outOff;
109:
110: }
111:
112: /**
113: * returns the maximum number of bytes needed to convert a char
114: */
115: public int getMaxBytesPerChar() {
116: return 4;
117: }
118:
119: /**
120: * Return the character set ID
121: */
122: public String getCharacterEncoding() {
123: return "EUC_TW";
124: }
125:
126: protected int getNative(char unicode) {
127: int i, cns; // 2 chars in CNS table make 1 CNS code
128:
129: if (unicode < UniTab2[0]) {
130: if ((i = searchTab(unicode, UniTab1)) == -1)
131: return -1;
132: cns = (CNSTab1[2 * i] << 16) + CNSTab1[2 * i + 1];
133: return cns;
134: } else if (unicode < UniTab3[0]) {
135: if ((i = searchTab(unicode, UniTab2)) == -1)
136: return -1;
137: cns = (CNSTab2[2 * i] << 16) + CNSTab2[2 * i + 1];
138: return cns;
139: } else {
140: if ((i = searchTab(unicode, UniTab3)) == -1)
141: return -1;
142: cns = (CNSTab3[2 * i] << 16) + CNSTab3[2 * i + 1];
143: return cns;
144: }
145: }
146:
147: protected int searchTab(char code, char[] table) {
148: int i = 0, l, h;
149:
150: for (l = 0, h = table.length - 1; l < h;) {
151: if (table[l] == code) {
152: i = l;
153: break;
154: }
155: if (table[h] == code) {
156: i = h;
157: break;
158: }
159: i = (l + h) / 2;
160: if (table[i] == code)
161: break;
162: if (table[i] < code)
163: l = i + 1;
164: else
165: h = i - 1;
166: }
167: if (code == table[i]) {
168: return i;
169: } else {
170: return -1;
171: }
172: }
173:
174: private int unicodeToEUC(char unicode, byte ebyte[]) {
175: int cns = getNative(unicode);
176:
177: if ((cns >> 16) == 0x01) { // Plane 1
178: ebyte[0] = (byte) (((cns & 0xff00) >> 8) | MSB);
179: ebyte[1] = (byte) ((cns & 0xff) | MSB);
180: return 2;
181: }
182:
183: byte cnsPlane = (byte) (cns >> 16);
184: if (cnsPlane >= (byte) 0x02) { // Plane 2
185: ebyte[0] = SS2;
186: ebyte[1] = (byte) (cnsPlane | (byte) 0xA0);
187: ebyte[2] = (byte) (((cns & 0xff00) >> 8) | MSB);
188: ebyte[3] = (byte) ((cns & 0xff) | MSB);
189: return 4;
190: }
191:
192: return -1;
193: }
194:
195: protected int unicodeToEUC(char unicode) {
196: if (unicode <= 0x7F) { // ASCII falls into EUC_TW CS0
197: return unicode;
198: }
199:
200: int cns = getNative(unicode);
201: int plane = cns >> 16;
202: int euc = (cns & 0x0000FFFF) | 0x00008080;
203:
204: if (plane == 1) {
205: return euc;
206: } else if (plane == 2) {
207: return ((SS2 << 24) & 0xFF000000)
208: | ((P2 << 16) & 0x00FF0000) | euc;
209: } else if (plane == 3) {
210: return ((SS2 << 24) & 0xFF000000)
211: | ((P3 << 16) & 0x00FF0000) | euc;
212: }
213:
214: return -1;
215: }
216:
217: private char[] UniTab1 = uniTab1.toCharArray();
218: private char[] UniTab2 = uniTab2.toCharArray();
219: private char[] UniTab3 = uniTab3.toCharArray();
220: private char[] CNSTab1 = cnsTab1.toCharArray();
221: private char[] CNSTab2 = cnsTab2.toCharArray();
222: private char[] CNSTab3 = cnsTab3.toCharArray();
223: }
|