History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/io/ByteToCharJISAutoDetect.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/io/ByteToCharJISAutoDetect.java+239−0
@@ -0,0 +1,239 @@
1/*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package sun.io;
26
27import java.io.UnsupportedEncodingException;
28import sun.nio.cs.ext.JISAutoDetect;
29
30public class ByteToCharJISAutoDetect extends ByteToCharConverter {
31
32 private final static int EUCJP_MASK = 0x01;
33 private final static int SJIS2B_MASK = 0x02;
34 private final static int SJIS1B_MASK = 0x04;
35 private final static int EUCJP_KANA1_MASK = 0x08;
36 private final static int EUCJP_KANA2_MASK = 0x10;
37 private final static byte[] maskTable1 = JISAutoDetect.getByteMask1();
38 private final static byte[] maskTable2 = JISAutoDetect.getByteMask2();
39
40 private final static int SS2 = 0x8e;
41 private final static int SS3 = 0x8f;
42
43 // SJISName is set to either "SJIS" or "MS932"
44 private String SJISName;
45 private String EUCJPName;
46
47 private String convName = null;
48 private ByteToCharConverter detectedConv = null;
49 private ByteToCharConverter defaultConv = null;
50
51 public ByteToCharJISAutoDetect() {
52 super();
53 SJISName = CharacterEncoding.getSJISName();
54 EUCJPName = CharacterEncoding.getEUCJPName();
55 defaultConv = new ByteToCharISO8859_1();
56 defaultConv.subChars = subChars;
57 defaultConv.subMode = subMode;
58 }
59
60 public int flush(char [] output, int outStart, int outEnd)
61 throws MalformedInputException, ConversionBufferFullException
62 {
63 badInputLength = 0;
64 if(detectedConv != null)
65 return detectedConv.flush(output, outStart, outEnd);
66 else
67 return defaultConv.flush(output, outStart, outEnd);
68 }
69
70
71 /**
72 * Character conversion
73 */
74 public int convert(byte[] input, int inOff, int inEnd,
75 char[] output, int outOff, int outEnd)
76 throws UnknownCharacterException, MalformedInputException,
77 ConversionBufferFullException
78 {
79 int num = 0;
80
81 charOff = outOff;
82 byteOff = inOff;
83
84 try {
85 if (detectedConv == null) {
86 int euckana = 0;
87 int ss2count = 0;
88 int firstmask = 0;
89 int secondmask = 0;
90 int cnt;
91 boolean nonAsciiFound = false;
92
93 for (cnt = inOff; cnt < inEnd; cnt++) {
94 firstmask = 0;
95 secondmask = 0;
96 int byte1 = input[cnt]&0xff;
97 int byte2;
98
99 // TODO: should check valid escape sequences!
100 if (byte1 == 0x1b) {
101 convName = "ISO2022JP";
102 break;
103 }
104
105 // Try to convert all leading ASCII characters.
106 if ((nonAsciiFound == false) && (byte1 < 0x80)) {
107 if (charOff >= outEnd)
108 throw new ConversionBufferFullException();
109 output[charOff++] = (char) byte1;
110 byteOff++;
111 num++;
112 continue;
113 }
114
115 // We can no longer convert ASCII.
116 nonAsciiFound = true;
117
118 firstmask = maskTable1[byte1];
119 if (byte1 == SS2)
120 ss2count++;
121
122 if (firstmask != 0) {
123 if (cnt+1 < inEnd) {
124 byte2 = input[++cnt] & 0xff;
125 secondmask = maskTable2[byte2];
126 int mask = firstmask & secondmask;
127 if (mask == EUCJP_MASK) {
128 convName = EUCJPName;
129 break;
130 }
131 if ((mask == SJIS2B_MASK) || (mask == SJIS1B_MASK)
132 || (JISAutoDetect.canBeSJIS1B(firstmask) && secondmask == 0)) {
133 convName = SJISName;
134 break;
135 }
136
137 // If the first byte is a SS3 and the third byte
138 // is not an EUC byte, it should be SJIS.
139 // Otherwise, we can't determine it yet, but it's
140 // very likely SJIS. So we don't take the EUCJP CS3
141 // character boundary. If we tried both
142 // possibilities here, it might be able to be
143 // determined correctly.
144 if ((byte1 == SS3) && JISAutoDetect.canBeEUCJP(secondmask)) {
145 if (cnt+1 < inEnd) {
146 int nextbyte = input[cnt+1] & 0xff;
147 if (! JISAutoDetect.canBeEUCJP(maskTable2[nextbyte]))
148 convName = SJISName;
149 } else
150 convName = SJISName;
151 }
152 if (JISAutoDetect.canBeEUCKana(firstmask, secondmask))
153 euckana++;
154 } else {
155 if ((firstmask & SJIS1B_MASK) != 0) {
156 convName = SJISName;
157 break;
158 }
159 }
160 }
161 }
162
163 if (nonAsciiFound && (convName == null)) {
164 if ((euckana > 1) || (ss2count > 1))
165 convName = EUCJPName;
166 else
167 convName = SJISName;
168 }
169
170 if (convName != null) {
171 try {
172 detectedConv = ByteToCharConverter.getConverter(convName);
173 detectedConv.subChars = subChars;
174 detectedConv.subMode = subMode;
175 } catch (UnsupportedEncodingException e){
176 detectedConv = null;
177 convName = null;
178 }
179 }
180 }
181 } catch (ConversionBufferFullException bufferFullException) {
182 throw bufferFullException;
183 } catch (Exception e) {
184 // If we fail to detect the converter needed for any reason,
185 // use the default converter.
186 detectedConv = defaultConv;
187 }
188
189 // If we've converted all ASCII characters, then return.
190 if (byteOff == inEnd) {
191 return num;
192 }
193
194 if(detectedConv != null) {
195 try {
196 num += detectedConv.convert(input, inOff + num, inEnd,
197 output, outOff + num, outEnd);
198 } finally {
199 charOff = detectedConv.nextCharIndex();
200 byteOff = detectedConv.nextByteIndex();
201 badInputLength = detectedConv.badInputLength;
202 }
203 } else {
204 try {
205 num += defaultConv.convert(input, inOff + num, inEnd,
206 output, outOff + num, outEnd);
207 } finally {
208 charOff = defaultConv.nextCharIndex();
209 byteOff = defaultConv.nextByteIndex();
210 badInputLength = defaultConv.badInputLength;
211 }
212 }
213 return num;
214 }
215
216 public void reset() {
217 if(detectedConv != null) {
218 detectedConv.reset();
219 detectedConv = null;
220 convName = null;
221 } else
222 defaultConv.reset();
223 charOff = byteOff = 0;
224 }
225
226 public String getCharacterEncoding() {
227 return "JISAutoDetect";
228 }
229
230 public String toString() {
231 String s = getCharacterEncoding();
232 if (detectedConv != null) {
233 s += "[" + detectedConv.getCharacterEncoding() + "]";
234 } else {
235 s += "[unknown]";
236 }
237 return s;
238 }
239}