blob: c6f2d2026f1c3218ae340ef1b039496ffeee3f24 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2002 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
26package sun.io;
27
28/**
29 * @author Limin Shi
30 * Sean Jiang
31 */
32
33public abstract class ByteToCharDoubleByte extends ByteToCharConverter {
34 protected byte savedByte;
35
36 /*
37 * 1st level index, provided by subclass
38 */
39 protected short index1[];
40
41 /*
42 * 2nd level index, provided by subclass
43 * every string has 0x10*(end-start+1) characters.
44 */
45 protected String index2[];
46
47 protected int start;
48 protected int end;
49
50 /*
51 * Size of bad input that caused conversion to stop
52 */
53 protected int badInputLength;
54
55 public ByteToCharDoubleByte() {
56 super();
57 savedByte = 0;
58 }
59
60
61 public short[] getIndex1() {
62 return(index1);
63 }
64
65 public String[] getIndex2() {
66 return(index2);
67 }
68
69 public int flush(char[] output, int outStart, int outEnd)
70 throws MalformedInputException
71 {
72 if (savedByte != 0) {
73 reset();
74 badInputLength = 0;
75 throw new MalformedInputException();
76 }
77 reset();
78 return 0;
79 }
80
81 /**
82 * Converts sequences of bytes to characters.
83 * Conversions that result in Exceptions can be restarted by calling
84 * convert again, with appropriately modified parameters.
85 * @return the characters written to output.
86 * @param input byte array containing text in Double/single Byte
87 * @param inStart offset in input array
88 * @param inEnd offset of last byte to be converted
89 * @param output character array to receive conversion result
90 * @param outStart starting offset
91 * @param outEnd offset of last byte to be written to
92 * @throw UnsupportedCharacterException for any bytes
93 * that cannot be converted to the external character set.
94 */
95 public int convert(byte[] input, int inOff, int inEnd,
96 char[] output, int outOff, int outEnd)
97 throws UnknownCharacterException, MalformedInputException,
98 ConversionBufferFullException
99 {
100 char outputChar = REPLACE_CHAR;
101 int inputSize = 0; // Size of input
102
103 // Record beginning offsets
104 charOff = outOff;
105 byteOff = inOff;
106
107 // Loop until we hit the end of the input
108 while (byteOff < inEnd) {
109 int byte1, byte2;
110
111 if (savedByte == 0) {
112 byte1 = input[byteOff];
113 inputSize = 1;
114 } else {
115 byte1 = savedByte;
116 savedByte = 0;
117 inputSize = 0;
118 }
119
120 outputChar = convSingleByte(byte1);
121
122 if (outputChar == REPLACE_CHAR) { // DoubleByte char
123 if (byteOff + inputSize >= inEnd) {
124 // split in the middle of a character
125 // save the first byte for next time around
126 savedByte = (byte) byte1;
127 byteOff += inputSize;
128 break;
129 }
130
131 byte1 &= 0xff;
132 byte2 = input[byteOff + inputSize] & 0xff;
133
134 inputSize++;
135 outputChar = getUnicode(byte1, byte2);
136 }
137
138 if (outputChar == REPLACE_CHAR) {
139 if (subMode)
140 outputChar = subChars[0];
141 else {
142 badInputLength = inputSize;
143 throw new UnknownCharacterException();
144 }
145 }
146
147 if (charOff >= outEnd)
148 throw new ConversionBufferFullException();
149
150 output[charOff++] = outputChar;
151 byteOff += inputSize;
152 }
153
154 return charOff - outOff;
155 }
156
157 /**
158 * Resets the converter.
159 * Call this method to reset the converter to its initial state
160 */
161 public void reset() {
162 byteOff = charOff = 0;
163 savedByte = 0;
164 }
165
166
167 /*
168 * Can be changed by subclass
169 */
170 protected char convSingleByte(int b) {
171 if (b >= 0)
172 return (char) b;
173 return REPLACE_CHAR;
174 }
175
176 /*
177 * Can be changed by subclass
178 */
179 protected char getUnicode(int byte1, int byte2) {
180 // Fix for bug 4117820 - similar fix for bug 4121358 put
181 // into ByteToCharEUC_JP.getUnicode()
182 if (((byte1 < 0) || (byte1 > index1.length))
183 || ((byte2 < start) || (byte2 > end)))
184 return REPLACE_CHAR;
185
186 int n = (index1[byte1] & 0xf) * (end - start + 1) + (byte2 - start);
187 return index2[index1[byte1] >> 4].charAt(n);
188 }
189
190 protected final static char REPLACE_CHAR = '\uFFFD';
191}