0N/A/*
2362N/A * Copyright (c) 1997, 2001, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.io;
0N/A
0N/A/**
0N/A * @author Tom Zhou
0N/A */
0N/Apublic class ByteToCharISO2022CN extends ByteToCharConverter
0N/A{
0N/A private String SODesignator[];
0N/A private String SS2Designator[] = null;
0N/A private String SS3Designator[] = null;
0N/A private ByteToCharConverter SOConverter[];
0N/A private ByteToCharConverter SS2Converter[] = null;
0N/A private ByteToCharConverter SS3Converter[] = null;
0N/A
0N/A private static final byte ISO_ESC = 0x1b;
0N/A private static final byte ISO_SI = 0x0f;
0N/A private static final byte ISO_SO = 0x0e;
0N/A private static final byte ISO_SS2_7 = 0x4e;
0N/A private static final byte ISO_SS3_7 = 0x4f;
0N/A private static final byte MSB = (byte)0x80;
0N/A private static final char REPLACE_CHAR = '\uFFFD';
0N/A private static final byte maximumDesignatorLength = 3;
0N/A
0N/A private static final byte SOFlag = 0;
0N/A private static final byte SS2Flag = 1;
0N/A private static final byte SS3Flag = 2;
0N/A private static final byte G0 = 0;
0N/A private static final byte G1 = 1;
0N/A
0N/A private ByteToCharConverter tmpConverter[];
0N/A
0N/A private int curSODes, curSS2Des, curSS3Des;
0N/A private boolean shiftout;
0N/A
0N/A private byte remainByte[] = new byte[10];
0N/A private int remainIndex = -1;
0N/A private byte state, firstByte;
0N/A
0N/A public void reset()
0N/A {
0N/A int i = 0;
0N/A
0N/A shiftout = false;
0N/A state = G0;
0N/A firstByte = 0;
0N/A
0N/A curSODes = 0;
0N/A curSS2Des = 0;
0N/A curSS3Des = 0;
0N/A
0N/A charOff = byteOff = 0;
0N/A remainIndex = -1;
0N/A
0N/A for(i = 0; i < remainByte.length; i++)
0N/A remainByte[i] = 0;
0N/A }
0N/A
0N/A public int flush(char[] output, int outStart, int outEnd)
0N/A throws MalformedInputException
0N/A {
0N/A int i;
0N/A if (state != G0) {
0N/A badInputLength = 0;
0N/A throw new MalformedInputException();
0N/A }
0N/A reset();
0N/A return 0;
0N/A }
0N/A
0N/A private byte[] savetyGetSrc(byte[] input, int inOff, int inEnd, int nbytes)
0N/A {
0N/A int i;
0N/A byte tmp[];
0N/A
0N/A if(inOff <= (inEnd-nbytes+1))
0N/A tmp = new byte[nbytes];
0N/A else
0N/A tmp = new byte[inEnd-inOff];
0N/A
0N/A for(i = 0; i < tmp.length; i++)
0N/A tmp[i] = input[inOff+i];
0N/A return tmp;
0N/A }
0N/A
0N/A private char getUnicode(byte byte1, byte byte2, byte shiftFlag)
0N/A {
0N/A byte1 |= MSB;
0N/A byte2 |= MSB;
0N/A char[] tmpChar = new char[1];
0N/A
0N/A switch(shiftFlag) {
0N/A case SOFlag:
0N/A try {
0N/A byte[] tmpByte = {byte1,byte2};
0N/A SOConverter[curSODes].convert(tmpByte, 0, 2, tmpChar, 0, 1);
0N/A }
0N/A catch (Exception e) {}
0N/A break;
0N/A case SS2Flag:
0N/A try {
0N/A byte[] tmpByte = {(byte)0x8e, (byte)0xa2, byte1, byte2};
0N/A SS2Converter[curSS2Des].convert(tmpByte, 0, 4, tmpChar, 0, 1);
0N/A }
0N/A catch (Exception e){}
0N/A break;
0N/A case SS3Flag:
0N/A try {
0N/A byte[] tmpByte = {(byte)0x8e, (byte)0xa3, byte1,byte2};
0N/A SS3Converter[curSS3Des].convert(tmpByte, 0, 4, tmpChar, 0, 1);
0N/A }
0N/A catch (Exception e){}
0N/A break;
0N/A default:
0N/A tmpChar[0] = REPLACE_CHAR;
0N/A }
0N/A return tmpChar[0];
0N/A }
0N/A
0N/A public final int convert(byte[] input, int inOff, int inEnd,
0N/A char[] output, int outOff, int outEnd)
0N/A throws ConversionBufferFullException,
0N/A MalformedInputException
0N/A {
0N/A int i;
0N/A int DesignatorLength = 0;
0N/A charOff = outOff;
0N/A byteOff = inOff;
0N/A
0N/A // Loop until we hit the end of the input
0N/A while (byteOff < inEnd) {
0N/A // If we don't have room for the output, throw an exception
0N/A if (charOff >= outEnd)
0N/A throw new ConversionBufferFullException();
0N/A if(remainIndex < 0) {
0N/A remainByte[0] = input[byteOff];
0N/A remainIndex = 0;
0N/A byteOff++;
0N/A }
0N/A switch (remainByte[0]) {
0N/A case ISO_SO:
0N/A shiftout = true;
0N/A if(remainIndex > 0)
0N/A System.arraycopy(remainByte, 1, remainByte, 0, remainIndex);
0N/A remainIndex--;
0N/A break;
0N/A case ISO_SI:
0N/A shiftout = false;
0N/A if(remainIndex > 0)
0N/A System.arraycopy(remainByte, 1, remainByte, 0, remainIndex);
0N/A remainIndex--;
0N/A break;
0N/A case ISO_ESC:
0N/A byte tmp[] = savetyGetSrc(input, byteOff, inEnd,
0N/A (maximumDesignatorLength-remainIndex));
0N/A System.arraycopy(tmp, 0, remainByte, remainIndex+1, tmp.length);
0N/A
0N/A remainIndex += tmp.length;
0N/A byteOff += tmp.length;
0N/A if(tmp.length<(maximumDesignatorLength-remainIndex))
0N/A break;
0N/A String tmpString = new String(remainByte, 1, remainIndex);
0N/A for (i = 0; i < SODesignator.length; i++) {
0N/A if(tmpString.indexOf(SODesignator[i]) == 0) {
0N/A curSODes = i;
0N/A DesignatorLength = SODesignator[i].length();
0N/A break;
0N/A }
0N/A }
0N/A
0N/A if (DesignatorLength == 0) { // designator not recognized
0N/A badInputLength = tmp.length;
0N/A throw new MalformedInputException();
0N/A }
0N/A
0N/A if (i == SODesignator.length) {
0N/A for (i = 0; i < SS2Designator.length; i++) {
0N/A if(tmpString.indexOf(SS2Designator[i]) == 0) {
0N/A curSS2Des = i;
0N/A DesignatorLength = SS2Designator[i].length();
0N/A break;
0N/A }
0N/A }
0N/A if(i == SS2Designator.length) {
0N/A for(i = 0; i < SS3Designator.length; i++) {
0N/A if (tmpString.indexOf(SS3Designator[i]) == 0) {
0N/A curSS3Des = i;
0N/A DesignatorLength = SS3Designator[i].length();
0N/A break;
0N/A }
0N/A }
0N/A if (i == SS3Designator.length) {
0N/A switch(remainByte[1]) {
0N/A case ISO_SS2_7:
0N/A output[charOff] = getUnicode(remainByte[2],
0N/A remainByte[3],
0N/A SS2Flag);
0N/A charOff++;
0N/A DesignatorLength = 3;
0N/A break;
0N/A case ISO_SS3_7:
0N/A output[charOff] = getUnicode(remainByte[2],
0N/A remainByte[3],
0N/A SS3Flag);
0N/A charOff++;
0N/A DesignatorLength = 3;
0N/A break;
0N/A default:
0N/A DesignatorLength = 0;
0N/A }
0N/A }
0N/A }
0N/A }
0N/A if (remainIndex > DesignatorLength) {
0N/A for(i = 0; i < remainIndex-DesignatorLength; i++)
0N/A remainByte[i] = remainByte[DesignatorLength+1+i];
0N/A remainIndex = i-1;
0N/A } else {
0N/A remainIndex = -1;
0N/A }
0N/A break;
0N/A default:
0N/A if (!shiftout) {
0N/A output[charOff] = (char)remainByte[0];
0N/A charOff++;
0N/A } else {
0N/A switch (state) {
0N/A case G0:
0N/A firstByte = remainByte[0];
0N/A state = G1;
0N/A break;
0N/A case G1:
0N/A output[charOff] = getUnicode(firstByte, remainByte[0],
0N/A SOFlag);
0N/A charOff++;
0N/A state = G0;
0N/A break;
0N/A }
0N/A }
0N/A if (remainIndex > 0)
0N/A System.arraycopy(remainByte, 1, remainByte, 0, remainIndex);
0N/A remainIndex--;
0N/A }
0N/A }
0N/A return charOff - outOff;
0N/A }
0N/A
0N/A public ByteToCharISO2022CN()
0N/A {
0N/A SODesignator = new String[3];
0N/A SODesignator[0] = "$A";
0N/A SODesignator[1] = "$)A";
0N/A SODesignator[2] = "$)G";
0N/A SS2Designator = new String[1];
0N/A SS2Designator[0] = "$*H";
0N/A SS3Designator = new String[1];
0N/A SS3Designator[0] = "$+I";
0N/A
0N/A SOConverter = new ByteToCharConverter[3];
0N/A SS2Converter = new ByteToCharConverter[1];
0N/A SS3Converter = new ByteToCharConverter[1];
0N/A
0N/A try {
0N/A SOConverter[0] = SOConverter[1]
0N/A = ByteToCharConverter.getConverter("GB2312");
0N/A SOConverter[2] = SS2Converter[0] = SS3Converter[0]
0N/A = ByteToCharConverter.getConverter("CNS11643");
0N/A } catch (Exception e) {};
0N/A }
0N/A
0N/A // Return the character set id
0N/A public String getCharacterEncoding()
0N/A {
0N/A return "ISO2022CN";
0N/A }
0N/A}