1 /* 2 * Copyright 2001-2005 Sun Microsystems, Inc. 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. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any questions. 24 */ 25 26 import java.nio.CharBuffer; 27 import java.nio.ByteBuffer; 28 import java.nio.charset.*; 29 import sun.nio.cs.ext.EUC_TW; 30 31 public abstract class X11CNS11643 extends Charset { 32 private final int plane; 33 public X11CNS11643 (int plane, String name) { 34 super(name, null); 35 switch (plane) { 36 case 1: 37 this.plane = 0; // CS1 38 break; 39 case 2: 40 case 3: 41 this.plane = plane; 42 break; 43 default: 44 throw new IllegalArgumentException 45 ("Only planes 1, 2, and 3 supported"); 46 } 47 } 48 49 public CharsetEncoder newEncoder() { 50 return new Encoder(this, plane); 51 } 52 53 public CharsetDecoder newDecoder() { 54 return new Decoder(this, plane); 55 } 56 57 public boolean contains(Charset cs) { 58 return cs instanceof X11CNS11643; 59 } 60 61 private class Encoder extends EUC_TW_OLD.Encoder { 62 private int plane; 63 public Encoder(Charset cs, int plane) { 64 super(cs); 65 this.plane = plane; 66 } 67 public boolean canEncode(char c) { 68 if (c <= 0x7F) { 69 return false; 70 } 71 int p = getNative(c) >> 16; 72 if (p == 1 && plane == 0 || 73 p == 2 && plane == 2 || 74 p == 3 && plane == 3) 75 return true; 76 return false; 77 } 78 79 public boolean isLegalReplacement(byte[] repl) { 80 return true; 81 } 82 83 protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) { 84 char[] sa = src.array(); 85 int sp = src.arrayOffset() + src.position(); 86 int sl = src.arrayOffset() + src.limit(); 87 byte[] da = dst.array(); 88 int dp = dst.arrayOffset() + dst.position(); 89 int dl = dst.arrayOffset() + dst.limit(); 90 91 try { 92 while (sp < sl) { 93 char c = sa[sp]; 94 if (c >= '\uFFFE' || c <= '\u007f') 95 return CoderResult.unmappableForLength(1); 96 int cns = getNative(c); 97 int p = cns >> 16; 98 if (p == 1 && plane == 0 || 99 p == 2 && plane == 2 || 100 p == 3 && plane == 3) { 101 if (dl - dp < 2) 102 return CoderResult.OVERFLOW; 103 da[dp++] = (byte) ((cns >> 8) & 0x7f); 104 da[dp++] = (byte) (cns & 0x7f); 105 sp++; 106 continue; 107 } 108 return CoderResult.unmappableForLength(1); 109 } 110 return CoderResult.UNDERFLOW; 111 } finally { 112 src.position(sp - src.arrayOffset()); 113 dst.position(dp - dst.arrayOffset()); 114 } 115 } 116 } 117 118 private class Decoder extends EUC_TW_OLD.Decoder { 119 private String table; 120 protected Decoder(Charset cs, int plane) { 121 super(cs); 122 switch (plane) { 123 case 0: 124 table = unicodeCNS1; 125 break; 126 case 2: 127 table = unicodeCNS2; 128 break; 129 case 3: 130 table = unicodeCNS3; 131 break; 132 default: 133 throw new IllegalArgumentException 134 ("Only planes 1, 2, and 3 supported"); 135 } 136 } 137 138 //we only work on array backed buffer. 139 protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) { 140 byte[] sa = src.array(); 141 int sp = src.arrayOffset() + src.position(); 142 int sl = src.arrayOffset() + src.limit(); 143 assert (sp <= sl); 144 sp = (sp <= sl ? sp : sl); 145 146 char[] da = dst.array(); 147 int dp = dst.arrayOffset() + dst.position(); 148 int dl = dst.arrayOffset() + dst.limit(); 149 assert (dp <= dl); 150 dp = (dp <= dl ? dp : dl); 151 152 try { 153 while (sp < sl) { 154 if ( sl - sp < 2) { 155 return CoderResult.UNDERFLOW; 156 } 157 byte b1 = sa[sp]; 158 byte b2 = sa[sp + 1]; 159 char c = replacement().charAt(0); 160 161 if (table == unicodeCNS3) { 162 char[] cc = convToSurrogate((byte)(b1 | 0x80), 163 (byte)(b2 | 0x80), 164 table); 165 if (cc != null && cc[0] == '\u0000') 166 c = cc[1]; 167 } else { 168 c = convToUnicode((byte)(b1 | 0x80), 169 (byte)(b2 | 0x80), 170 table); 171 } 172 if (c == replacement().charAt(0) 173 //to keep the compatibility with b2cX11CNS11643 174 /*|| c == '\u0000'*/) { 175 return CoderResult.unmappableForLength(2); 176 } 177 if (dl - dp < 1) 178 return CoderResult.OVERFLOW; 179 da[dp++] = c; 180 sp +=2; 181 } 182 return CoderResult.UNDERFLOW; 183 } finally { 184 src.position(sp - src.arrayOffset()); 185 dst.position(dp - dst.arrayOffset()); 186 } 187 } 188 } 189 }