1 /* 2 * Copyright (c) 2001, 2013, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.nio.CharBuffer; 25 import java.nio.ByteBuffer; 26 import java.nio.charset.*; 27 import sun.nio.cs.*; 28 import sun.nio.cs.ext.*; 29 30 public abstract class X11CNS11643 extends Charset { 31 private final int plane; 32 public X11CNS11643 (int plane, String name) { 33 super(name, null); 34 switch (plane) { 35 case 1: 36 this.plane = 0; // CS1 37 break; 38 case 2: 39 case 3: 40 this.plane = plane; 41 break; 42 default: 43 throw new IllegalArgumentException 44 ("Only planes 1, 2, and 3 supported"); 45 } 46 } 47 48 public CharsetEncoder newEncoder() { 49 return new Encoder(this, plane); 50 } 51 52 public CharsetDecoder newDecoder() { 53 return new Decoder(this, plane); 54 } 55 56 public boolean contains(Charset cs) { 57 return cs instanceof X11CNS11643; 58 } 59 60 private class Encoder extends EUC_TW_OLD.Encoder { 61 private int plane; 62 public Encoder(Charset cs, int plane) { 63 super(cs); 64 this.plane = plane; 65 } 66 public boolean canEncode(char c) { 67 if (c <= 0x7F) { 68 return false; 69 } 70 int p = getNative(c) >> 16; 71 if (p == 1 && plane == 0 || 72 p == 2 && plane == 2 || 73 p == 3 && plane == 3) 74 return true; 75 return false; 76 } 77 78 public boolean isLegalReplacement(byte[] repl) { 79 return true; 80 } 81 82 protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) { 83 char[] sa = src.array(); 84 int sp = src.arrayOffset() + src.position(); 85 int sl = src.arrayOffset() + src.limit(); 86 byte[] da = dst.array(); 87 int dp = dst.arrayOffset() + dst.position(); 88 int dl = dst.arrayOffset() + dst.limit(); 89 90 try { 91 while (sp < sl) { 92 char c = sa[sp]; 93 if (c >= '\uFFFE' || c <= '\u007f') 94 return CoderResult.unmappableForLength(1); 95 int cns = getNative(c); 96 int p = cns >> 16; 97 if (p == 1 && plane == 0 || 98 p == 2 && plane == 2 || 99 p == 3 && plane == 3) { 100 if (dl - dp < 2) 101 return CoderResult.OVERFLOW; 102 da[dp++] = (byte) ((cns >> 8) & 0x7f); 103 da[dp++] = (byte) (cns & 0x7f); 104 sp++; 105 continue; 106 } 107 return CoderResult.unmappableForLength(1); 108 } 109 return CoderResult.UNDERFLOW; 110 } finally { 111 src.position(sp - src.arrayOffset()); 112 dst.position(dp - dst.arrayOffset()); 113 } 114 } 115 } 116 117 private class Decoder extends EUC_TW_OLD.Decoder { 118 private String table; 119 protected Decoder(Charset cs, int plane) { 120 super(cs); 121 switch (plane) { 122 case 0: 123 table = unicodeCNS1; 124 break; 125 case 2: 126 table = unicodeCNS2; 127 break; 128 case 3: 129 table = unicodeCNS3; 130 break; 131 default: 132 throw new IllegalArgumentException 133 ("Only planes 1, 2, and 3 supported"); 134 } 135 } 136 137 //we only work on array backed buffer. 138 protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) { 139 byte[] sa = src.array(); 140 int sp = src.arrayOffset() + src.position(); 141 int sl = src.arrayOffset() + src.limit(); 142 assert (sp <= sl); 143 sp = (sp <= sl ? sp : sl); 144 145 char[] da = dst.array(); 146 int dp = dst.arrayOffset() + dst.position(); 147 int dl = dst.arrayOffset() + dst.limit(); 148 assert (dp <= dl); 149 dp = (dp <= dl ? dp : dl); 150 151 try { 152 while (sp < sl) { 153 if ( sl - sp < 2) { 154 return CoderResult.UNDERFLOW; 155 } 156 byte b1 = sa[sp]; 157 byte b2 = sa[sp + 1]; 158 char c = replacement().charAt(0); 159 160 if (table == unicodeCNS3) { 161 char[] cc = convToSurrogate((byte)(b1 | 0x80), 162 (byte)(b2 | 0x80), 163 table); 164 if (cc != null && cc[0] == '\u0000') 165 c = cc[1]; 166 } else { 167 c = convToUnicode((byte)(b1 | 0x80), 168 (byte)(b2 | 0x80), 169 table); 170 } 171 if (c == replacement().charAt(0) 172 //to keep the compatibility with b2cX11CNS11643 173 /*|| c == '\u0000'*/) { 174 return CoderResult.unmappableForLength(2); 175 } 176 if (dl - dp < 1) 177 return CoderResult.OVERFLOW; 178 da[dp++] = c; 179 sp +=2; 180 } 181 return CoderResult.UNDERFLOW; 182 } finally { 183 src.position(sp - src.arrayOffset()); 184 dst.position(dp - dst.arrayOffset()); 185 } 186 } 187 } 188 }