1 /* 2 * Copyright 1997 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 package sun.io; 26 27 import sun.nio.cs.ext.DoubleByte; 28 import static sun.nio.cs.CharsetMapping.*; 29 30 public abstract class ByteToCharEUC2 extends ByteToCharConverter 31 { 32 private final int G0 = 0; 33 private final int G1 = 1; 34 private final int SS2 = 0x8E; 35 private final int SS3 = 0x8F; 36 37 private int firstByte, state; 38 39 private DoubleByte.Decoder dec; 40 41 public ByteToCharEUC2(DoubleByte.Decoder dec) { 42 super(); 43 state = G0; 44 this.dec = dec; 45 } 46 47 char decodeSingle(int b) { 48 return dec.decodeSingle(b); 49 } 50 51 char decodeDouble(int b1, int b2) { 52 return dec.decodeDouble(b1, b2); 53 } 54 55 /** 56 * flush out any residual data and reset the buffer state 57 */ 58 public int flush(char[] output, int outStart, int outEnd) 59 throws MalformedInputException 60 { 61 if (state != G0) { 62 reset(); 63 badInputLength = 0; 64 throw new MalformedInputException(); 65 } 66 67 reset(); 68 return 0; 69 } 70 71 /** 72 * Resets the converter. 73 */ 74 public void reset() { 75 state = G0; 76 charOff = byteOff = 0; 77 } 78 79 /** 80 * Character conversion 81 */ 82 public int convert(byte[] input, int inOff, int inEnd, 83 char[] output, int outOff, int outEnd) 84 throws UnknownCharacterException, MalformedInputException, 85 ConversionBufferFullException 86 { 87 int byte1; 88 char outputChar = UNMAPPABLE_DECODING; 89 byteOff = inOff; 90 charOff = outOff; 91 92 while (byteOff < inEnd) { 93 byte1 = input[byteOff] & 0xff; 94 switch (state) { 95 case G0: 96 if (byte1 == SS2 || // no general support 97 byte1 == SS3 ) { // for g2 or g3 98 badInputLength = 1; 99 throw new MalformedInputException(); 100 } 101 if ( byte1 <= 0x9f ) // < 0x9f has its own table 102 outputChar = decodeSingle(byte1); 103 else 104 if (byte1 < 0xa1 || byte1 > 0xfe) { // byte within range? 105 badInputLength = 1; 106 throw new MalformedInputException(); 107 } else { // G1 set first byte 108 firstByte = byte1; 109 state = G1; 110 } 111 break; 112 case G1: 113 state = G0; 114 if ( byte1 < 0xa1 || byte1 > 0xfe) { // valid G1 set second byte 115 badInputLength = 1; 116 throw new MalformedInputException(); 117 } 118 outputChar = decodeDouble(firstByte, byte1); 119 break; 120 } 121 if (state == G0) { 122 if (outputChar == UNMAPPABLE_DECODING) { 123 if (subMode) 124 outputChar = subChars[0]; 125 else { 126 badInputLength = 1; 127 throw new UnknownCharacterException(); 128 } 129 } 130 if (charOff >= outEnd) 131 throw new ConversionBufferFullException(); 132 output[charOff++] = outputChar; 133 } 134 byteOff++; 135 } 136 return charOff - outOff; 137 } 138 }