001: /*
002: * @(#)ByteToCharEUC_JP.java 1.25 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:
028: package sun.io;
029:
030: /**
031: * @author Limin Shi
032: */
033:
034: public class ByteToCharEUC_JP extends ByteToCharJIS0208 {
035: private byte savedSecond = 0;
036: ByteToCharJIS0201 bcJIS0201 = new ByteToCharJIS0201();
037: ByteToCharJIS0212 bcJIS0212 = new ByteToCharJIS0212();
038:
039: public ByteToCharEUC_JP() {
040: super ();
041: start = 0xA1;
042: end = 0xFE;
043: savedSecond = 0;
044: }
045:
046: public int flush(char[] output, int outStart, int outEnd)
047: throws MalformedInputException {
048: if (savedSecond != 0) {
049: reset();
050: throw new MalformedInputException();
051: }
052: reset();
053: return 0;
054: }
055:
056: /**
057: * Resets the converter.
058: * Call this method to reset the converter to its initial state
059: */
060: public void reset() {
061: super .reset();
062: savedSecond = 0;
063: }
064:
065: public String getCharacterEncoding() {
066: return "EUC_JP";
067: }
068:
069: protected char convSingleByte(int b) {
070: if (b < 0 || b > 0x7F)
071: return REPLACE_CHAR;
072: return bcJIS0201.getUnicode(b);
073: }
074:
075: protected char getUnicode(int byte1, int byte2) {
076: if (byte1 == 0x8E) {
077: return bcJIS0201.getUnicode(byte2 - 256);
078: }
079: // Fix for bug 4121358 - similar fix for bug 4117820 put
080: // into ByteToCharDoubleByte.getUnicode()
081: if (((byte1 < 0) || (byte1 > index1.length))
082: || ((byte2 < start) || (byte2 > end)))
083: return REPLACE_CHAR;
084: int n = (index1[byte1 - 0x80] & 0xf) * (end - start + 1)
085: + (byte2 - start);
086: return index2[index1[byte1 - 0x80] >> 4].charAt(n);
087: }
088:
089: /**
090: * Converts sequences of bytes to characters.
091: * Conversions that result in Exceptions can be restarted by calling
092: * convert again, with appropriately modified parameters.
093: * @return the characters written to output.
094: * @param input byte array containing text in Double/single Byte
095: * @param inStart offset in input array
096: * @param inEnd offset of last byte to be converted
097: * @param output character array to receive conversion result
098: * @param outStart starting offset
099: * @param outEnd offset of last byte to be written to
100: * @throw UnsupportedCharacterException for any bytes
101: * that cannot be converted to the external character set.
102: */
103: public int convert(byte[] input, int inOff, int inEnd,
104: char[] output, int outOff, int outEnd)
105: throws UnknownCharacterException,
106: ConversionBufferFullException {
107: char outputChar = REPLACE_CHAR;
108: int inputSize = 0; // Size of input
109: // Record beginning offsets
110: charOff = outOff;
111: byteOff = inOff;
112: // Loop until we hit the end of the input
113: while (byteOff < inEnd) {
114: int byte1, byte2;
115: if (savedByte == 0) {
116: byte1 = input[byteOff];
117: inputSize = 1;
118: } else {
119: byte1 = savedByte;
120: savedByte = 0;
121: inputSize = 0;
122: }
123: outputChar = convSingleByte(byte1);
124: if (outputChar == REPLACE_CHAR) { // Multibyte char
125: if ((byte1 & 0xff) == 0x8F) { // JIS0212
126: if (byteOff + inputSize + 1 >= inEnd) {
127: // split in the middle of a character
128: // save the first 2 bytes for next time around
129: savedByte = (byte) byte1;
130: byteOff += inputSize;
131: if (byteOff < inEnd) {
132: savedSecond = input[byteOff];
133: byteOff++;
134: }
135: break;
136: }
137: if (savedSecond != 0) {
138: byte1 = savedSecond & 0xff;
139: savedSecond = 0;
140: } else {
141: byte1 = input[byteOff + inputSize] & 0xff;
142: inputSize++;
143: }
144: byte2 = input[byteOff + inputSize] & 0xff;
145: inputSize++;
146: outputChar = bcJIS0212.getUnicode(byte1 - 0x80,
147: byte2 - 0x80);
148: } else { // JIS0208
149: if (byteOff + inputSize >= inEnd) {
150: // split in the middle of a character
151: // save the first byte for next time around
152: savedByte = (byte) byte1;
153: byteOff += inputSize;
154: break;
155: }
156: byte1 &= 0xff;
157: byte2 = input[byteOff + inputSize] & 0xff;
158: inputSize++;
159: outputChar = getUnicode(byte1, byte2);
160: }
161: }
162: if (outputChar == REPLACE_CHAR) {
163: if (subMode)
164: outputChar = subChars[0];
165: else {
166: badInputLength = inputSize;
167: throw new UnknownCharacterException();
168: }
169: }
170: if (charOff >= outEnd)
171: throw new ConversionBufferFullException();
172: output[charOff++] = outputChar;
173: byteOff += inputSize;
174: }
175: return charOff - outOff;
176: }
177: }
|