1 /* 2 * Copyright (c) 2002, 2012, 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 package $PACKAGE$; 27 28 import java.nio.ByteBuffer; 29 import java.nio.CharBuffer; 30 import java.nio.charset.Charset; 31 import java.nio.charset.CharsetDecoder; 32 import java.nio.charset.CharsetEncoder; 33 import java.nio.charset.CoderResult; 34 import sun.nio.cs.HistoricallyNamedCharset; 35 import sun.nio.cs.DelegatableDecoder; 36 import sun.nio.cs.DoubleByte; 37 import sun.nio.cs.Surrogate; 38 import sun.nio.cs.SingleByte; 39 import sun.nio.cs.*; 40 import static sun.nio.cs.CharsetMapping.*; 41 42 public class EUC_JP 43 extends Charset 44 implements HistoricallyNamedCharset 45 { 46 public EUC_JP() { 47 super("EUC-JP", $ALIASES$); 48 } 49 50 public String historicalName() { 51 return "EUC_JP"; 52 } 53 54 public boolean contains(Charset cs) { 55 return ((cs.name().equals("US-ASCII")) 56 || (cs instanceof JIS_X_0201) 57 || (cs instanceof JIS_X_0208) 58 || (cs instanceof JIS_X_0212) 59 || (cs instanceof EUC_JP)); 60 } 61 62 public CharsetDecoder newDecoder() { 63 return new Decoder(this); 64 } 65 66 public CharsetEncoder newEncoder() { 67 return new Encoder(this); 68 } 69 70 static class Decoder extends CharsetDecoder 71 implements DelegatableDecoder { 72 73 final static SingleByte.Decoder DEC0201 = 74 (SingleByte.Decoder)new JIS_X_0201().newDecoder(); 75 76 final static DoubleByte.Decoder DEC0208 = 77 (DoubleByte.Decoder)new JIS_X_0208().newDecoder(); 78 79 final static DoubleByte.Decoder DEC0212 = 80 (DoubleByte.Decoder)new JIS_X_0212().newDecoder(); 81 82 private final SingleByte.Decoder dec0201; 83 private final DoubleByte.Decoder dec0208; 84 private final DoubleByte.Decoder dec0212; 85 86 protected Decoder(Charset cs) { 87 this(cs, 0.5f, 1.0f, DEC0201, DEC0208, DEC0212); 88 } 89 90 protected Decoder(Charset cs, float avgCpb, float maxCpb, 91 SingleByte.Decoder dec0201, 92 DoubleByte.Decoder dec0208, 93 DoubleByte.Decoder dec0212) { 94 super(cs, avgCpb, maxCpb); 95 this.dec0201 = dec0201; 96 this.dec0208 = dec0208; 97 this.dec0212 = dec0212; 98 } 99 100 101 protected char decodeDouble(int byte1, int byte2) { 102 if (byte1 == 0x8e) { 103 if (byte2 < 0x80) 104 return UNMAPPABLE_DECODING; 105 return dec0201.decode((byte)byte2); 106 } 107 return dec0208.decodeDouble(byte1 - 0x80, byte2 - 0x80); 108 } 109 110 private CoderResult decodeArrayLoop(ByteBuffer src, 111 CharBuffer dst) 112 { 113 byte[] sa = src.array(); 114 int sp = src.arrayOffset() + src.position(); 115 int sl = src.arrayOffset() + src.limit(); 116 assert (sp <= sl); 117 sp = (sp <= sl ? sp : sl); 118 119 char[] da = dst.array(); 120 int dp = dst.arrayOffset() + dst.position(); 121 int dl = dst.arrayOffset() + dst.limit(); 122 assert (dp <= dl); 123 dp = (dp <= dl ? dp : dl); 124 125 int b1 = 0, b2 = 0; 126 int inputSize = 0; 127 char outputChar = UNMAPPABLE_DECODING; 128 try { 129 while (sp < sl) { 130 b1 = sa[sp] & 0xff; 131 inputSize = 1; 132 133 if ((b1 & 0x80) == 0) { 134 outputChar = (char)b1; 135 } else { // Multibyte char 136 if (b1 == 0x8f) { // JIS0212 137 if (sp + 3 > sl) 138 return CoderResult.UNDERFLOW; 139 b1 = sa[sp + 1] & 0xff; 140 b2 = sa[sp + 2] & 0xff; 141 inputSize += 2; 142 if (dec0212 == null) // JIS02012 not supported 143 return CoderResult.unmappableForLength(inputSize); 144 outputChar = dec0212.decodeDouble(b1-0x80, b2-0x80); 145 } else { // JIS0201, JIS0208 146 if (sp + 2 > sl) 147 return CoderResult.UNDERFLOW; 148 b2 = sa[sp + 1] & 0xff; 149 inputSize++; 150 outputChar = decodeDouble(b1, b2); 151 } 152 } 153 if (outputChar == UNMAPPABLE_DECODING) { // can't be decoded 154 return CoderResult.unmappableForLength(inputSize); 155 } 156 if (dp + 1 > dl) 157 return CoderResult.OVERFLOW; 158 da[dp++] = outputChar; 159 sp += inputSize; 160 } 161 return CoderResult.UNDERFLOW; 162 } finally { 163 src.position(sp - src.arrayOffset()); 164 dst.position(dp - dst.arrayOffset()); 165 } 166 } 167 168 private CoderResult decodeBufferLoop(ByteBuffer src, 169 CharBuffer dst) 170 { 171 int mark = src.position(); 172 int b1 = 0, b2 = 0; 173 int inputSize = 0; 174 char outputChar = UNMAPPABLE_DECODING; 175 176 try { 177 while (src.hasRemaining()) { 178 b1 = src.get() & 0xff; 179 inputSize = 1; 180 if ((b1 & 0x80) == 0) { 181 outputChar = (char)b1; 182 } else { // Multibyte char 183 if (b1 == 0x8f) { // JIS0212 184 if (src.remaining() < 2) 185 return CoderResult.UNDERFLOW; 186 b1 = src.get() & 0xff; 187 b2 = src.get() & 0xff; 188 inputSize += 2; 189 if (dec0212 == null) // JIS02012 not supported 190 return CoderResult.unmappableForLength(inputSize); 191 outputChar = dec0212.decodeDouble(b1-0x80, b2-0x80); 192 } else { // JIS0201 JIS0208 193 if (src.remaining() < 1) 194 return CoderResult.UNDERFLOW; 195 b2 = src.get() & 0xff; 196 inputSize++; 197 outputChar = decodeDouble(b1, b2); 198 } 199 } 200 if (outputChar == UNMAPPABLE_DECODING) { 201 return CoderResult.unmappableForLength(inputSize); 202 } 203 if (dst.remaining() < 1) 204 return CoderResult.OVERFLOW; 205 dst.put(outputChar); 206 mark += inputSize; 207 } 208 return CoderResult.UNDERFLOW; 209 } finally { 210 src.position(mark); 211 } 221 public void implReset() { 222 super.implReset(); 223 } 224 public CoderResult implFlush(CharBuffer out) { 225 return super.implFlush(out); 226 } 227 } 228 229 230 static class Encoder extends CharsetEncoder { 231 232 final static SingleByte.Encoder ENC0201 = 233 (SingleByte.Encoder)new JIS_X_0201().newEncoder(); 234 235 final static DoubleByte.Encoder ENC0208 = 236 (DoubleByte.Encoder)new JIS_X_0208().newEncoder(); 237 238 final static DoubleByte.Encoder ENC0212 = 239 (DoubleByte.Encoder)new JIS_X_0212().newEncoder(); 240 241 private final Surrogate.Parser sgp = new Surrogate.Parser(); 242 243 244 private final SingleByte.Encoder enc0201; 245 private final DoubleByte.Encoder enc0208; 246 private final DoubleByte.Encoder enc0212; 247 248 protected Encoder(Charset cs) { 249 this(cs, 3.0f, 3.0f, ENC0201, ENC0208, ENC0212); 250 } 251 252 protected Encoder(Charset cs, float avgBpc, float maxBpc, 253 SingleByte.Encoder enc0201, 254 DoubleByte.Encoder enc0208, 255 DoubleByte.Encoder enc0212) { 256 super(cs, avgBpc, maxBpc); 257 this.enc0201 = enc0201; 258 this.enc0208 = enc0208; 259 this.enc0212 = enc0212; 260 } 261 262 public boolean canEncode(char c) { 263 byte[] encodedBytes = new byte[3]; 264 return encodeSingle(c, encodedBytes) != 0 || 265 encodeDouble(c) != UNMAPPABLE_ENCODING; 266 } 267 268 protected int encodeSingle(char inputChar, byte[] outputByte) { 269 int b = enc0201.encode(inputChar); 270 if (b == UNMAPPABLE_ENCODING) 271 return 0; 272 if (b >= 0 && b < 128) { 273 outputByte[0] = (byte)b; 274 return 1; 275 } 276 outputByte[0] = (byte)0x8e; 277 outputByte[1] = (byte)b; 278 return 2; 279 } 280 281 protected int encodeDouble(char ch) { 282 int b = enc0208.encodeChar(ch); 283 if (b != UNMAPPABLE_ENCODING) 284 return b + 0x8080; 285 if (enc0212 != null) { 286 b = enc0212.encodeChar(ch); 287 if (b != UNMAPPABLE_ENCODING) 288 b += 0x8F8080; 289 } 290 return b; 291 } 292 293 private CoderResult encodeArrayLoop(CharBuffer src, 294 ByteBuffer dst) 295 { 296 char[] sa = src.array(); 297 int sp = src.arrayOffset() + src.position(); 298 int sl = src.arrayOffset() + src.limit(); 299 assert (sp <= sl); 300 sp = (sp <= sl ? sp : sl); 301 byte[] da = dst.array(); 302 int dp = dst.arrayOffset() + dst.position(); 303 int dl = dst.arrayOffset() + dst.limit(); 304 assert (dp <= dl); 305 dp = (dp <= dl ? dp : dl); 306 307 int outputSize = 0; 308 byte[] outputByte; | 1 /* 2 * Copyright (c) 2002, 2018, 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 package $PACKAGE$; 27 28 import java.nio.ByteBuffer; 29 import java.nio.CharBuffer; 30 import java.nio.charset.Charset; 31 import java.nio.charset.CharsetDecoder; 32 import java.nio.charset.CharsetEncoder; 33 import java.nio.charset.CoderResult; 34 import sun.nio.cs.HistoricallyNamedCharset; 35 import sun.nio.cs.DelegatableDecoder; 36 import sun.nio.cs.DoubleByte; 37 import sun.nio.cs.Surrogate; 38 import sun.nio.cs.SingleByte; 39 import sun.nio.cs.*; 40 import static sun.nio.cs.CharsetMapping.*; 41 42 public class IBM29626C 43 extends Charset 44 implements HistoricallyNamedCharset 45 { 46 public IBM29626C() { 47 super("x-IBM29626C", $ALIASES$); 48 } 49 50 public String historicalName() { 51 return "Cp29626C"; 52 } 53 54 public boolean contains(Charset cs) { 55 return ((cs.name().equals("US-ASCII")) 56 || (cs instanceof IBM29626C)); 57 } 58 59 public CharsetDecoder newDecoder() { 60 return new Decoder(this); 61 } 62 63 public CharsetEncoder newEncoder() { 64 return new Encoder(this); 65 } 66 67 static class Decoder extends CharsetDecoder 68 implements DelegatableDecoder { 69 70 final static SingleByte.Decoder DEC0201 = 71 (SingleByte.Decoder)new JIS_X_0201().newDecoder(); 72 73 final static DoubleByte.Decoder DEC0208 = 74 (DoubleByte.Decoder)new JIS_X_0208().newDecoder(); 75 76 final static DoubleByte.Decoder DEC0212 = 77 (DoubleByte.Decoder)new JIS_X_0212().newDecoder(); 78 79 final static DoubleByte.Encoder ibm943 = 80 (DoubleByte.Encoder)new IBM943().newEncoder(); 81 82 private final SingleByte.Decoder dec0201; 83 private final DoubleByte.Decoder dec0208; 84 private final DoubleByte.Decoder dec0212; 85 86 private final String G2_b = 87 "\uA1F1\uA1F2\uA2CC\uADA1\uADA2\uADA3\uADA4\uADA5\uADA6\uADA7"+ 88 "\uADA8\uADA9\uADAA\uADAB\uADAC\uADAD\uADAE\uADAF\uADB0\uADB1"+ 89 "\uADB2\uADB3\uADB4\uADB5\uADB6\uADB7\uADB8\uADB9\uADBA\uADBB"+ 90 "\uADBC\uADBD\uADBE\uADC0\uADC1\uADC2\uADC3\uADC4\uADC5\uADC6"+ 91 "\uADC7\uADC8\uADC9\uADCA\uADCB\uADCC\uADCD\uADCE\uADCF\uADD0"+ 92 "\uADD1\uADD2\uADD3\uADD4\uADD5\uADD6\uADDF\uADE0\uADE1\uADE2"+ 93 "\uADE3\uADE4\uADE5\uADE6\uADE7\uADE8\uADE9\uADEA\uADEB\uADEC"+ 94 "\uADED\uADEE\uADEF\uADF0\uADF1\uADF2\uADF3\uADF4\uADF5\uADF6"+ 95 "\uADF7\uADF8\uADF9\uADFA\uADFB\uADFC"; 96 97 private final String G2_c = 98 "\uFFE0\uFFE1\uFFE2\u2460\u2461\u2462\u2463\u2464\u2465\u2466"+ 99 "\u2467\u2468\u2469\u246A\u246B\u246C\u246D\u246E\u246F\u2470"+ 100 "\u2471\u2472\u2473\u2160\u2161\u2162\u2163\u2164\u2165\u2166"+ 101 "\u2167\u2168\u2169\u3349\u3314\u3322\u334D\u3318\u3327\u3303"+ 102 "\u3336\u3351\u3357\u330D\u3326\u3323\u332B\u334A\u333B\u339C"+ 103 "\u339D\u339E\u338E\u338F\u33C4\u33A1\u337B\u301D\u301F\u2116"+ 104 "\u33CD\u2121\u32A4\u32A5\u32A6\u32A7\u32A8\u3231\u3232\u3239"+ 105 "\u337E\u337D\u337C\u2252\u2261\u222B\u222E\u2211\u221A\u22A5"+ 106 "\u2220\u221F\u22BF\u2235\u2229\u222A"; 107 108 private final String G3_b = 109 "\uF3B8\uF3B9\uF3AB\uF3AC\uF3AD\uF3AE\uF3AF\uF3B0\uF3B1\uF3B2"+ 110 "\uF3B3\uF3B4\uF3A1\uF3A2\uF3A3\uF3A4\uF3A5\uF3A6\uF3A7\uF3A8"+ 111 "\uF3A9\uF3AA\uF3B7\uF3B8\uF4A2\uF4A3\uF4A4\uF4A5\uF4A6\uF4A8"+ 112 "\uF4A9\uF4AC\uF4AE\uF4AF\uF4B0\uF4B2\uF4B3\uF4B4\uF4B5\uF4B6"+ 113 "\uF4B7\uF4BA\uF4BD\uF4BE\uF4C0\uF4BF\uF4C2\uF4A1\uF4C6\uF4C7"+ 114 "\uF4C8\uF4CB\uF4D0\uF4D4\uF4D5\uF4D7\uF4D9\uF4DC\uF4DF\uF4E0"+ 115 "\uF4E1\uF4E5\uF4E7\uF4EA\uF4ED\uF4EE\uF4EF\uF4F4\uF4F5\uF4F6"+ 116 "\uF4F8\uF3B8\uF4B9\uF4EB\uF4A7\uF4AA\uF4AB\uF4B1\uF4B8\uF4BB"+ 117 "\uF4BC\uF4C4\uF4C5\uF4C9\uF4CC\uF4CD\uF4CE\uF4CF\uF4D1\uF4D3"+ 118 "\uF4D6\uF4D8\uF4DA\uF4DB\uF4DE\uF4E2\uF4E3\uF4E4\uF4E6\uF4E8"+ 119 "\uF4E9\uF4EC\uF4F1\uF4F2\uF4F3\uF4F7\uF3B6\uF3B5"; 120 121 private final String G3_c = 122 "\u2116\u2121\u2160\u2161\u2162\u2163\u2164\u2165\u2166\u2167"+ 123 "\u2168\u2169\u2170\u2171\u2172\u2173\u2174\u2175\u2176\u2177"+ 124 "\u2178\u2179\u3231\u00A6\u4EFC\u50F4\u51EC\u5307\u5324\u548A"+ 125 "\u5759\u589E\u5BEC\u5CF5\u5D53\u5FB7\u6085\u6120\u654E\u663B"+ 126 "\u6665\u6801\u6A6B\u6AE2\u6DF2\u6DF8\u7028\u70BB\u7501\u7682"+ 127 "\u769E\u7930\u7AE7\u7DA0\u7DD6\u8362\u85B0\u8807\u8B7F\u8CF4"+ 128 "\u8D76\u90DE\u9115\u9592\u973B\u974D\u9751\u999E\u9AD9\u9B72"+ 129 "\u9ED1\uF86F\uF929\uF9DC\uFA0E\uFA0F\uFA10\uFA11\uFA12\uFA13"+ 130 "\uFA14\uFA15\uFA16\uFA17\uFA18\uFA19\uFA1A\uFA1B\uFA1C\uFA1D"+ 131 "\uFA1E\uFA1F\uFA20\uFA21\uFA22\uFA23\uFA24\uFA25\uFA26\uFA27"+ 132 "\uFA28\uFA29\uFA2A\uFA2B\uFA2C\uFA2D\uFF02\uFF07"; 133 134 protected Decoder(Charset cs) { 135 this(cs, 0.5f, 1.0f, DEC0201, DEC0208, DEC0212); 136 } 137 138 protected Decoder(Charset cs, float avgCpb, float maxCpb, 139 SingleByte.Decoder dec0201, 140 DoubleByte.Decoder dec0208, 141 DoubleByte.Decoder dec0212) { 142 super(cs, avgCpb, maxCpb); 143 this.dec0201 = dec0201; 144 this.dec0208 = dec0208; 145 this.dec0212 = dec0212; 146 } 147 148 149 protected char decodeSingle(int b) { 150 if (b < 0x8e) 151 return (char) b; 152 if (b < 0x90) 153 return UNMAPPABLE_DECODING; 154 if (b < 0xa0) 155 return (char) b; 156 return UNMAPPABLE_DECODING; 157 } 158 159 protected char decodeUDC(int byte1, int byte2, int offset) { 160 if ((byte1 >= 0xf5 && byte1 <= 0xfe) 161 && (byte2 >= 0xa1 && byte2 <= 0xfe)) { 162 return (char)((byte1 - 0xf5) * 94 + (byte2 - 0xa1) + offset); 163 } 164 return UNMAPPABLE_DECODING; 165 } 166 167 final static String g1_c = "\u00a2\u00a3\u00ac\\\u007e"; 168 169 protected char decodeDouble(int byte1, int byte2) { 170 if (byte1 == 0x8e) { 171 if (byte2 < 0x80) 172 return UNMAPPABLE_DECODING; 173 char c = dec0201.decode((byte)byte2); 174 if (byte2 >= 0xe0 && byte2 <= 0xe4) 175 c = g1_c.charAt(byte2 - 0xe0); 176 return c; 177 } 178 if ((byte1 >= 0xa1 && byte1 <= 0xfe) 179 && (byte2 >= 0xa1 && byte2 <= 0xfe)) { 180 char c = (char)((byte1 << 8) + byte2); 181 int idx = G2_b.indexOf(c); 182 if (idx > -1) 183 return G2_c.charAt(idx); 184 } 185 char ch = dec0208.decodeDouble(byte1 - 0x80, byte2 - 0x80); 186 if (ch == UNMAPPABLE_DECODING) 187 ch = decodeUDC(byte1, byte2, 0xe000); 188 return ch; 189 } 190 191 protected char decodeDoubleG3(int byte1, int byte2) { 192 if ((byte1 >= 0xa1 && byte1 <= 0xfe) 193 && (byte2 >= 0xa1 && byte2 <= 0xfe)) { 194 char c = (char)((byte1 << 8) + byte2); 195 int idx = G3_b.indexOf(c); 196 if (idx > -1) 197 return G3_c.charAt(idx); 198 } 199 char ch = dec0212.decodeDouble(byte1 - 0x80, byte2 - 0x80); 200 if (ch == '\u2116') 201 ch = UNMAPPABLE_DECODING; 202 if (ch != UNMAPPABLE_DECODING) 203 ch = ibm943.canEncode(ch) ? ch : UNMAPPABLE_DECODING; 204 if (ch == UNMAPPABLE_DECODING) 205 ch = decodeUDC(byte1, byte2, 0xe3ac); 206 return ch; 207 } 208 209 private CoderResult decodeArrayLoop(ByteBuffer src, 210 CharBuffer dst) 211 { 212 byte[] sa = src.array(); 213 int sp = src.arrayOffset() + src.position(); 214 int sl = src.arrayOffset() + src.limit(); 215 assert (sp <= sl); 216 sp = (sp <= sl ? sp : sl); 217 218 char[] da = dst.array(); 219 int dp = dst.arrayOffset() + dst.position(); 220 int dl = dst.arrayOffset() + dst.limit(); 221 assert (dp <= dl); 222 dp = (dp <= dl ? dp : dl); 223 224 int b1 = 0, b2 = 0; 225 int inputSize = 0; 226 char outputChar = UNMAPPABLE_DECODING; 227 try { 228 while (sp < sl) { 229 b1 = sa[sp] & 0xff; 230 inputSize = 1; 231 232 outputChar = decodeSingle(b1); 233 if (outputChar == UNMAPPABLE_DECODING) { // Multibyte char 234 if (b1 == 0x8f) { // JIS0212 235 if (sp + 3 > sl) 236 return CoderResult.UNDERFLOW; 237 b1 = sa[sp + 1] & 0xff; 238 b2 = sa[sp + 2] & 0xff; 239 inputSize += 2; 240 outputChar = decodeDoubleG3(b1, b2); 241 } else { // JIS0201, JIS0208 242 if (sp + 2 > sl) 243 return CoderResult.UNDERFLOW; 244 b2 = sa[sp + 1] & 0xff; 245 inputSize++; 246 outputChar = decodeDouble(b1, b2); 247 } 248 } 249 if (outputChar == UNMAPPABLE_DECODING) { // can't be decoded 250 return CoderResult.unmappableForLength(inputSize); 251 } 252 if (dp + 1 > dl) 253 return CoderResult.OVERFLOW; 254 da[dp++] = outputChar; 255 sp += inputSize; 256 } 257 return CoderResult.UNDERFLOW; 258 } finally { 259 src.position(sp - src.arrayOffset()); 260 dst.position(dp - dst.arrayOffset()); 261 } 262 } 263 264 private CoderResult decodeBufferLoop(ByteBuffer src, 265 CharBuffer dst) 266 { 267 int mark = src.position(); 268 int b1 = 0, b2 = 0; 269 int inputSize = 0; 270 char outputChar = UNMAPPABLE_DECODING; 271 272 try { 273 while (src.hasRemaining()) { 274 b1 = src.get() & 0xff; 275 inputSize = 1; 276 outputChar = decodeSingle(b1); 277 if (outputChar == UNMAPPABLE_DECODING) { // Multibyte char 278 if (b1 == 0x8f) { // JIS0212 279 if (src.remaining() < 2) 280 return CoderResult.UNDERFLOW; 281 b1 = src.get() & 0xff; 282 b2 = src.get() & 0xff; 283 inputSize += 2; 284 outputChar = decodeDoubleG3(b1, b2); 285 } else { // JIS0201 JIS0208 286 if (src.remaining() < 1) 287 return CoderResult.UNDERFLOW; 288 b2 = src.get() & 0xff; 289 inputSize++; 290 outputChar = decodeDouble(b1, b2); 291 } 292 } 293 if (outputChar == UNMAPPABLE_DECODING) { 294 return CoderResult.unmappableForLength(inputSize); 295 } 296 if (dst.remaining() < 1) 297 return CoderResult.OVERFLOW; 298 dst.put(outputChar); 299 mark += inputSize; 300 } 301 return CoderResult.UNDERFLOW; 302 } finally { 303 src.position(mark); 304 } 314 public void implReset() { 315 super.implReset(); 316 } 317 public CoderResult implFlush(CharBuffer out) { 318 return super.implFlush(out); 319 } 320 } 321 322 323 static class Encoder extends CharsetEncoder { 324 325 final static SingleByte.Encoder ENC0201 = 326 (SingleByte.Encoder)new JIS_X_0201().newEncoder(); 327 328 final static DoubleByte.Encoder ENC0208 = 329 (DoubleByte.Encoder)new JIS_X_0208().newEncoder(); 330 331 final static DoubleByte.Encoder ENC0212 = 332 (DoubleByte.Encoder)new JIS_X_0212().newEncoder(); 333 334 final static DoubleByte.Encoder ibm943 = 335 (DoubleByte.Encoder)new IBM943().newEncoder(); 336 337 private final Surrogate.Parser sgp = new Surrogate.Parser(); 338 339 private final SingleByte.Encoder enc0201; 340 private final DoubleByte.Encoder enc0208; 341 private final DoubleByte.Encoder enc0212; 342 343 private final String G2_c = 344 "\u2015\u2211\u221F\u2225\u222E\u22BF\u2460\u2461\u2462\u2463"+ 345 "\u2464\u2465\u2466\u2467\u2468\u2469\u246A\u246B\u246C\u246D"+ 346 "\u246E\u246F\u2470\u2471\u2472\u2473\u301D\u301F\u3232\u3239"+ 347 "\u32A4\u32A5\u32A6\u32A7\u32A8\u3303\u330D\u3314\u3318\u3322"+ 348 "\u3323\u3326\u3327\u332B\u3336\u333B\u3349\u334A\u334D\u3351"+ 349 "\u3357\u337B\u337C\u337D\u337E\u338E\u338F\u339C\u339D\u339E"+ 350 "\u33A1\u33C4\u33CD\u4FE0\u525D\u555E\u5699\u56CA\u5861\u5C5B"+ 351 "\u5C62\u6414\u6451\u6522\u6805\u688E\u6F51\u7006\u7130\u7626"+ 352 "\u79B1\u7C1E\u7E48\u7E61\u7E6B\u8141\u8346\u840A\u8523\u87EC"+ 353 "\u881F\u8EC0\u91AC\u91B1\u9830\u9839\u985A\u9A52\u9DD7\u9E7C"+ 354 "\u9EB4\u9EB5\uFF0D\uFF5E\uFFE0\uFFE1\uFFE2"; 355 356 private final String G2_b = 357 "\uA1BD\uADF4\uADF8\uA1C2\uADF3\uADF9\uADA1\uADA2\uADA3\uADA4"+ 358 "\uADA5\uADA6\uADA7\uADA8\uADA9\uADAA\uADAB\uADAC\uADAD\uADAE"+ 359 "\uADAF\uADB0\uADB1\uADB2\uADB3\uADB4\uADE0\uADE1\uADEB\uADEC"+ 360 "\uADE5\uADE6\uADE7\uADE8\uADE9\uADC6\uADCA\uADC1\uADC4\uADC2"+ 361 "\uADCC\uADCB\uADC5\uADCD\uADC7\uADCF\uADC0\uADCE\uADC3\uADC8"+ 362 "\uADC9\uADDF\uADEF\uADEE\uADED\uADD3\uADD4\uADD0\uADD1\uADD2"+ 363 "\uADD6\uADD5\uADE3\uB6A2\uC7ED\uB0A2\uB3FA\uC7B9\uC5B6\uD6A2"+ 364 "\uBCC8\uC1DF\uC4CF\uDAB9\uBAF4\uDBF4\uC8AE\uC6C2\uB1EB\uC1E9"+ 365 "\uC5F8\uC3BD\uE5DA\uBDAB\uB7D2\uE7A6\uB7D5\uCDE9\uBED5\uC0E6"+ 366 "\uCFB9\uB6ED\uBEDF\uC8B0\uCBCB\uF0F8\uC5BF\uC2CD\uB2AA\uB8B4"+ 367 "\uB9ED\uCCCD\uA1DD\uA1C1\uA1F1\uA1F2\uA2CC"; 368 369 private final String G3_c = 370 "\u2116\u2121\u2160\u2161\u2162\u2163\u2164\u2165\u2166\u2167"+ 371 "\u2168\u2169\u2170\u2171\u2172\u2173\u2174\u2175\u2176\u2177"+ 372 "\u2178\u2179\u3231\u4EFC\u50F4\u51EC\u5307\u5324\u548A\u5759"+ 373 "\u589E\u5BEC\u5CF5\u5D53\u5FB7\u6085\u6120\u654E\u663B\u6665"+ 374 "\u6801\u6A6B\u6AE2\u6DF2\u6DF8\u7028\u70BB\u7501\u7682\u769E"+ 375 "\u7930\u7AE7\u7DA0\u7DD6\u8362\u85B0\u8807\u8B7F\u8CF4\u8D76"+ 376 "\u90DE\u9115\u9592\u973B\u974D\u9751\u999E\u9AD9\u9B72\u9ED1"+ 377 "\uF86F\uF929\uF9DC\uFA0E\uFA0F\uFA10\uFA11\uFA12\uFA13\uFA14"+ 378 "\uFA15\uFA16\uFA17\uFA18\uFA19\uFA1A\uFA1B\uFA1C\uFA1D\uFA1E"+ 379 "\uFA1F\uFA20\uFA21\uFA22\uFA23\uFA24\uFA25\uFA26\uFA27\uFA28"+ 380 "\uFA29\uFA2A\uFA2B\uFA2C\uFA2D\uFF02\uFF07\uFFE4"; 381 382 private final String G3_b = 383 "\uF3B8\uF3B9\uF3AB\uF3AC\uF3AD\uF3AE\uF3AF\uF3B0\uF3B1\uF3B2"+ 384 "\uF3B3\uF3B4\uF3A1\uF3A2\uF3A3\uF3A4\uF3A5\uF3A6\uF3A7\uF3A8"+ 385 "\uF3A9\uF3AA\uF3B7\uF4A2\uF4A3\uF4A4\uF4A5\uF4A6\uF4A8\uF4A9"+ 386 "\uF4AC\uF4AE\uF4AF\uF4B0\uF4B2\uF4B3\uF4B4\uF4B5\uF4B6\uF4B7"+ 387 "\uF4BA\uF4BD\uF4BE\uF4C0\uF4BF\uF4C2\uF4A1\uF4C6\uF4C7\uF4C8"+ 388 "\uF4CB\uF4D0\uF4D4\uF4D5\uF4D7\uF4D9\uF4DC\uF4DF\uF4E0\uF4E1"+ 389 "\uF4E5\uF4E7\uF4EA\uF4ED\uF4EE\uF4EF\uF4F4\uF4F5\uF4F6\uF4F8"+ 390 "\uF3B8\uF4B9\uF4EB\uF4A7\uF4AA\uF4AB\uF4B1\uF4B8\uF4BB\uF4BC"+ 391 "\uF4C4\uF4C5\uF4C9\uF4CC\uF4CD\uF4CE\uF4CF\uF4D1\uF4D3\uF4D6"+ 392 "\uF4D8\uF4DA\uF4DB\uF4DE\uF4E2\uF4E3\uF4E4\uF4E6\uF4E8\uF4E9"+ 393 "\uF4EC\uF4F1\uF4F2\uF4F3\uF4F7\uF3B6\uF3B5\uA2C3"; 394 395 protected Encoder(Charset cs) { 396 this(cs, 3.0f, 3.0f, ENC0201, ENC0208, ENC0212); 397 } 398 399 protected Encoder(Charset cs, float avgBpc, float maxBpc, 400 SingleByte.Encoder enc0201, 401 DoubleByte.Encoder enc0208, 402 DoubleByte.Encoder enc0212) { 403 super(cs, avgBpc, maxBpc); 404 this.enc0201 = enc0201; 405 this.enc0208 = enc0208; 406 this.enc0212 = enc0212; 407 } 408 409 public boolean canEncode(char c) { 410 byte[] encodedBytes = new byte[3]; 411 return encodeSingle(c, encodedBytes) != 0 || 412 encodeDouble(c) != UNMAPPABLE_ENCODING; 413 } 414 415 private final static String G1_c = "\u00A2\u00A3\u00AC"; 416 417 protected int encodeSingle(char inputChar, byte[] outputByte) { 418 if (inputChar >= 0x80 && inputChar < 0x8e) { 419 outputByte[0] = (byte)inputChar; 420 return 1; 421 } 422 if (inputChar >= 0x90 && inputChar < 0xa0) { 423 outputByte[0] = (byte)inputChar; 424 return 1; 425 } 426 int b = enc0201.encode(inputChar); 427 if (b == UNMAPPABLE_ENCODING) { 428 int idx = G1_c.indexOf(inputChar); 429 if (idx > -1) 430 b = 0xe0 + idx; 431 } 432 if (b == UNMAPPABLE_ENCODING) 433 return 0; 434 if (b >= 0 && b < 128) { 435 outputByte[0] = (byte)b; 436 return 1; 437 } 438 outputByte[0] = (byte)0x8e; 439 outputByte[1] = (byte)b; 440 return 2; 441 } 442 443 protected int encodeUDC(char ch) { 444 if (ch >= '\ue000' && ch <= '\ue757') { 445 if (ch < '\ue3ac') { 446 int offset = (int)ch - 0xe000; 447 int b = ((offset / 94) << 8) + (offset % 94); 448 return b + 0xf5a1; 449 } else { 450 int offset = (int)ch - 0xe3ac; 451 int b = ((offset / 94) << 8) + (offset % 94); 452 return b + 0x8ff5a1; 453 } 454 } 455 return UNMAPPABLE_ENCODING; 456 } 457 458 protected int encodeDouble(char ch) { 459 int idx = G2_c.indexOf(ch); 460 if (idx > -1) 461 return (int)G2_b.charAt(idx); 462 idx = G3_c.indexOf(ch); 463 if (idx > -1) 464 return (int)G3_b.charAt(idx) + 0x8f0000; 465 int b = enc0208.encodeChar(ch); 466 if (b != UNMAPPABLE_ENCODING) 467 return b + 0x8080; 468 b = encodeUDC(ch); 469 if (b != UNMAPPABLE_ENCODING) 470 return b; 471 if (ibm943.canEncode(ch)) { 472 b = enc0212.encodeChar(ch); 473 if (b != UNMAPPABLE_ENCODING) { 474 b += 0x8F8080; 475 return b; 476 } 477 } 478 return b; 479 } 480 481 private CoderResult encodeArrayLoop(CharBuffer src, 482 ByteBuffer dst) 483 { 484 char[] sa = src.array(); 485 int sp = src.arrayOffset() + src.position(); 486 int sl = src.arrayOffset() + src.limit(); 487 assert (sp <= sl); 488 sp = (sp <= sl ? sp : sl); 489 byte[] da = dst.array(); 490 int dp = dst.arrayOffset() + dst.position(); 491 int dl = dst.arrayOffset() + dst.limit(); 492 assert (dp <= dl); 493 dp = (dp <= dl ? dp : dl); 494 495 int outputSize = 0; 496 byte[] outputByte; |