001: /*
002: * @(#)ByteToCharEUC.java 1.10 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027: package sun.io;
028:
029: /**
030: * @author Malcolm Ayres
031: */
032: public abstract class ByteToCharEUC extends ByteToCharConverter {
033: private final int G0 = 0;
034: private final int G1 = 1;
035: private final int SS2 = 0x8E;
036: private final int SS3 = 0x8F;
037: private int firstByte, state;
038: protected String mappingTableG1;
039: protected String byteToCharTable;
040:
041: public ByteToCharEUC() {
042: super ();
043: state = G0;
044: }
045:
046: /**
047: * flush out any residual data and reset the buffer state
048: */
049: public int flush(char[] output, int outStart, int outEnd)
050: throws MalformedInputException {
051: if (state != G0) {
052: reset();
053: badInputLength = 0;
054: throw new MalformedInputException();
055: }
056: reset();
057: return 0;
058: }
059:
060: /**
061: * Resets the converter.
062: */
063: public void reset() {
064: state = G0;
065: charOff = byteOff = 0;
066: }
067:
068: /**
069: * Character conversion
070: */
071: public int convert(byte[] input, int inOff, int inEnd,
072: char[] output, int outOff, int outEnd)
073: throws UnknownCharacterException, MalformedInputException,
074: ConversionBufferFullException {
075: int byte1;
076: char outputChar = '\uFFFD';
077: byteOff = inOff;
078: charOff = outOff;
079: while (byteOff < inEnd) {
080: byte1 = input[byteOff];
081: if (byte1 < 0)
082: byte1 += 256;
083: switch (state) {
084: case G0:
085: if (byte1 == SS2 || // no general support
086: byte1 == SS3) { // for g2 or g3
087: badInputLength = 1;
088: throw new MalformedInputException();
089: }
090: if (byte1 <= 0x9f) // < 0x9f has its own table
091: outputChar = byteToCharTable.charAt(byte1);
092: else if (byte1 < 0xa1 || byte1 > 0xfe) { // byte within range?
093: badInputLength = 1;
094: throw new MalformedInputException();
095: } else { // G1 set first byte
096: firstByte = byte1;
097: state = G1;
098: }
099: break;
100:
101: case G1:
102: state = G0;
103: if (byte1 < 0xa1 || byte1 > 0xfe) { // valid G1 set second byte
104: badInputLength = 1;
105: throw new MalformedInputException();
106: }
107: outputChar = mappingTableG1
108: .charAt(((firstByte - 0xa1) * 94) + byte1
109: - 0xa1);
110: break;
111: }
112: if (state == G0) {
113: if (outputChar == '\uFFFD') {
114: if (subMode)
115: outputChar = subChars[0];
116: else {
117: badInputLength = 1;
118: throw new UnknownCharacterException();
119: }
120: }
121: if (charOff >= outEnd)
122: throw new ConversionBufferFullException();
123: output[charOff++] = outputChar;
124: }
125: byteOff++;
126: }
127: return charOff - outOff;
128: }
129: }
|