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.charset.Charset; 32 import java.nio.charset.CharsetDecoder; 33 import java.nio.charset.CharsetEncoder; 34 import java.nio.charset.CoderResult; 35 import java.nio.ByteBuffer; 36 import java.nio.CharBuffer; 37 import sun.nio.cs.HistoricallyNamedCharset; 38 39 public class PCK 40 extends Charset 41 implements HistoricallyNamedCharset 42 { 43 44 public PCK() { 45 super("x-PCK", ExtendedCharsets.aliasesFor("x-PCK")); 46 } 47 48 public String historicalName() { 49 return "PCK"; 50 } 51 52 public boolean contains(Charset cs) { 53 return ((cs.name().equals("US-ASCII")) 54 || (cs instanceof JIS_X_0201) 55 || (cs instanceof PCK)); 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 SJIS.Decoder { 74 75 JIS_X_0208_Solaris_Decoder jis0208; 76 private static final char REPLACE_CHAR='\uFFFD'; 77 78 private Decoder(Charset cs) { 79 super(cs); 80 jis0208 = new JIS_X_0208_Solaris_Decoder(cs); 81 } 82 83 protected char decodeDouble(int c1, int c2) { 84 char outChar; 85 86 if ((outChar = super.decodeDouble(c1, c2)) != '\uFFFD') { 87 // Map JIS X 0208:1983 0x213D <--> U+2015 88 return ((outChar != '\u2014')? outChar: '\u2015'); 89 } else { 90 int adjust = c2 < 0x9F ? 1 : 0; 91 int rowOffset = c1 < 0xA0 ? 0x70 : 0xB0; 92 int cellOffset = (adjust == 1) ? (c2 > 0x7F ? 0x20 : 0x1F) : 0x7E; 93 int b1 = ((c1 - rowOffset) << 1) - adjust; 94 int b2 = c2 - cellOffset; 95 char outChar2 = jis0208.decodeDouble(b1, b2); 96 return outChar2; 97 } 98 } 99 } 100 101 private static class Encoder extends SJIS.Encoder { 102 103 private JIS_X_0201.Encoder jis0201; 104 105 private static final short[] j0208Index1 = 106 JIS_X_0208_Solaris_Encoder.getIndex1(); 107 private static final String[] j0208Index2 = 108 JIS_X_0208_Solaris_Encoder.getIndex2(); 109 110 private Encoder(Charset cs) { 111 super(cs); 112 jis0201 = new JIS_X_0201.Encoder(cs); 113 } 114 115 protected int encodeDouble(char ch) { 116 int result = 0; 117 118 // PCK uses JIS_X_0208:1983 rather than JIS_X_0208:1997 119 120 switch (ch) { 121 case '\u2015': 122 return 0x815C; 123 case '\u2014': 124 return 0; 125 default: 126 break; 127 } 128 129 if ((result = super.encodeDouble(ch)) != 0) { 130 return result; 131 } 132 else { 133 int offset = j0208Index1[ch >> 8] << 8; 134 int pos = j0208Index2[offset >> 12].charAt((offset & 0xfff) + (ch & 0xff)); 135 if (pos != 0) { 136 int c1 = (pos >> 8) & 0xff; 137 int c2 = pos & 0xff; 138 int rowOffset = c1 < 0x5F ? 0x70 : 0xB0; 139 int cellOffset = (c1 % 2 == 1) ? (c2 > 0x5F ? 0x20 : 0x1F) : 0x7E; 140 result = ((((c1 + 1 ) >> 1) + rowOffset) << 8) | (c2 + cellOffset); 141 } 142 } 143 return result; 144 } 145 } 146 }