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