1 /* 2 * Copyright (c) 2003, 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 */ 25 26 /* 27 */ 28 29 import java.nio.ByteBuffer; 30 import java.nio.CharBuffer; 31 import java.nio.charset.Charset; 32 import java.nio.charset.CharsetDecoder; 33 import java.nio.charset.CharsetEncoder; 34 import java.nio.charset.CoderResult; 35 import sun.nio.cs.HistoricallyNamedCharset; 36 import sun.nio.cs.Surrogate; 37 38 public class EUC_JP_Open_OLD 39 extends Charset 40 implements HistoricallyNamedCharset 41 { 42 public EUC_JP_Open_OLD() { 43 super("x-eucJP-Open_OLD", null); 44 } 45 46 public String historicalName() { 47 return "EUC_JP_Solaris"; 48 } 49 50 public boolean contains(Charset cs) { 51 return ((cs.name().equals("US-ASCII")) 52 || (cs instanceof JIS_X_0201_OLD) 53 || (cs instanceof EUC_JP_OLD)); 54 } 55 56 public CharsetDecoder newDecoder() { 57 return new Decoder(this); 58 } 59 60 public CharsetEncoder newEncoder() { 61 62 // Need to force the replacement byte to 0x3f 63 // because JIS_X_0208_Encoder defines its own 64 // alternative 2 byte substitution to permit it 65 // to exist as a self-standing Encoder 66 67 byte[] replacementBytes = { (byte)0x3f }; 68 return new Encoder(this).replaceWith(replacementBytes); 69 } 70 71 private static class Decoder extends EUC_JP_OLD.Decoder { 72 JIS_X_0201_OLD.Decoder decoderJ0201; 73 JIS_X_0212_Solaris_Decoder decodeMappingJ0212; 74 JIS_X_0208_Solaris_Decoder decodeMappingJ0208; 75 76 private static final short[] j0208Index1 = 77 JIS_X_0208_Solaris_Decoder.getIndex1(); 78 private static final String[] j0208Index2 = 79 JIS_X_0208_Solaris_Decoder.getIndex2(); 80 private static final int start = 0xa1; 81 private static final int end = 0xfe; 82 83 protected final char REPLACE_CHAR='\uFFFD'; 84 85 private Decoder(Charset cs) { 86 super(cs); 87 decoderJ0201 = new JIS_X_0201_OLD.Decoder(cs); 88 decodeMappingJ0212 = new JIS_X_0212_Solaris_Decoder(cs); 89 } 90 91 92 protected char decode0212(int byte1, int byte2) { 93 return decodeMappingJ0212.decodeDouble(byte1, byte2); 94 95 } 96 97 protected char decodeDouble(int byte1, int byte2) { 98 if (byte1 == 0x8e) { 99 return decoderJ0201.decode(byte2 - 256); 100 } 101 102 if (((byte1 < 0) 103 || (byte1 > j0208Index1.length)) 104 || ((byte2 < start) 105 || (byte2 > end))) 106 return REPLACE_CHAR; 107 108 char result = super.decodeDouble(byte1, byte2); 109 if (result != '\uFFFD') { 110 return result; 111 } else { 112 int n = (j0208Index1[byte1 - 0x80] & 0xf) * 113 (end - start + 1) 114 + (byte2 - start); 115 return j0208Index2[j0208Index1[byte1 - 0x80] >> 4].charAt(n); 116 } 117 } 118 } 119 120 121 private static class Encoder extends EUC_JP_OLD.Encoder { 122 123 JIS_X_0201_OLD.Encoder encoderJ0201; 124 JIS_X_0212_Solaris_Encoder encoderJ0212; 125 126 private static final short[] j0208Index1 = 127 JIS_X_0208_Solaris_Encoder.getIndex1(); 128 private static final String[] j0208Index2 = 129 JIS_X_0208_Solaris_Encoder.getIndex2(); 130 131 private final Surrogate.Parser sgp = new Surrogate.Parser(); 132 133 private Encoder(Charset cs) { 134 super(cs); 135 encoderJ0201 = new JIS_X_0201_OLD.Encoder(cs); 136 encoderJ0212 = new JIS_X_0212_Solaris_Encoder(cs); 137 } 138 139 protected int encodeSingle(char inputChar, byte[] outputByte) { 140 byte b; 141 142 if (inputChar == 0) { 143 outputByte[0] = (byte)0; 144 return 1; 145 } 146 147 if ((b = encoderJ0201.encode(inputChar)) == 0) 148 return 0; 149 150 if (b > 0 && b < 128) { 151 outputByte[0] = b; 152 return 1; 153 } 154 155 outputByte[0] = (byte)0x8e; 156 outputByte[1] = b; 157 return 2; 158 } 159 160 protected int encodeDouble(char ch) { 161 int r = super.encodeDouble(ch); 162 if (r != 0) { 163 return r; 164 } 165 else { 166 int offset = j0208Index1[((ch & 0xff00) >> 8 )] << 8; 167 r = j0208Index2[offset >> 12].charAt((offset & 0xfff) + 168 (ch & 0xFF)); 169 if (r > 0x7500) 170 return 0x8F8080 + encoderJ0212.encodeDouble(ch); 171 } 172 return (r==0 ? 0: r + 0x8080); 173 } 174 } 175 }