/* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* */ package sun.nio.cs.ext; import java.nio.CharBuffer;import java.nio.ByteBuffer;import java.nio.charset.Charset;import java.nio.charset.CharsetDecoder;import java.nio.charset.CharsetEncoder;import java.nio.charset.CoderResult;import sun.nio.cs.HistoricallyNamedCharset; public class IBM33722 extends Charset implements HistoricallyNamedCharset{ public IBM33722() { super("x-IBM33722", ExtendedCharsets.aliasesFor("x-IBM33722")); } public String historicalName() { return "Cp33722"; } public boolean contains(Charset cs) { return (cs instanceof IBM33722); } public CharsetDecoder newDecoder() { return new Decoder(this); } public CharsetEncoder newEncoder() { return new Encoder(this); } /** * These accessors are temporarily supplied while sun.io * converters co-exist with the sun.nio.cs.{ext} charset coders * These facilitate sharing of conversion tables between the * two co-existing implementations. When sun.io converters * are made extinct these will be unncessary and should be removed */ public String getDecoderSingleByteMappings() { return Decoder.byteToCharTable; } public String getDecoderMappingTableG1() { return Decoder.mappingTableG1; } public String getDecoderMappingTableG2() { return Decoder.mappingTableG2; } public String getDecoderMappingTableG3() { return Decoder.mappingTableG3; } public short[] getEncoderIndex1() { return Encoder.index1; } public String getEncoderIndex2() { return Encoder.index2; } public String getEncoderIndex2a() { return Encoder.index2a; } public String getEncoderIndex2b() { return Encoder.index2b; } protected static class Decoder extends CharsetDecoder { private final int G0 = 0; private final int G1 = 1; private final int G2 = 2; private final int G3 = 3; private final int G4 = 4; private final int SS2 = 0x8E; private final int SS3 = 0x8F; private int firstByte, state; public Decoder(Charset cs) { super(cs, 1.0f, 1.0f); } private CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) { byte[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); assert (sp <= sl); sp = (sp <= sl ? sp : sl); char[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); assert (dp <= dl); dp = (dp <= dl ? dp : dl); try { while (sp < sl) { int byte1, byte2; int inputSize = 1; char outputChar = '\uFFFD'; byte1 = sa[sp] & 0xff; if (byte1 == SS2) { if (sl - sp < 2) { return CoderResult.UNDERFLOW; } byte1 = sa[sp + 1] & 0xff; inputSize = 2; if ( byte1 < 0xa1 || byte1 > 0xfe) { //valid first byte for G2 return CoderResult.malformedForLength(2); } outputChar = mappingTableG2.charAt(byte1 - 0xa1); } else if(byte1 == SS3 ) { //G3 if (sl - sp < 3) { return CoderResult.UNDERFLOW; } byte1 = sa[sp + 1] & 0xff; byte2 = sa[sp + 2] & 0xff; inputSize = 3; if ( byte1 < 0xa1 || byte1 > 0xfe) { return CoderResult.malformedForLength(2); } if ( byte2 < 0xa1 || byte2 > 0xfe) { return CoderResult.malformedForLength(3); } outputChar = mappingTableG3.charAt(((byte1 - 0xa1) * 94) + byte2 - 0xa1); } else if ( byte1 <= 0x9f ) { // valid single byte outputChar = byteToCharTable.charAt(byte1); } else if (byte1 < 0xa1 || byte1 > 0xfe) { // invalid range? return CoderResult.malformedForLength(1); } else { // G1 if (sl - sp < 2) { return CoderResult.UNDERFLOW; } byte2 = sa[sp + 1] & 0xff; inputSize = 2; if ( byte2 < 0xa1 || byte2 > 0xfe) { return CoderResult.malformedForLength(2); } outputChar = mappingTableG1.charAt(((byte1 - 0xa1) * 94) + byte2 - 0xa1); } if (outputChar == '\uFFFD') return CoderResult.unmappableForLength(inputSize); if (dl - dp < 1) return CoderResult.OVERFLOW; da[dp++] = outputChar; sp += inputSize; } return CoderResult.UNDERFLOW; } finally { src.position(sp - src.arrayOffset()); dst.position(dp - dst.arrayOffset()); } } private CoderResult decodeBufferLoop(ByteBuffer src, CharBuffer dst) { int mark = src.position(); try { while (src.hasRemaining()) { int byte1, byte2; int inputSize = 1; char outputChar = '\uFFFD'; byte1 = src.get() & 0xff; if (byte1 == SS2) { if (!src.hasRemaining()) return CoderResult.UNDERFLOW; byte1 = src.get() & 0xff; inputSize = 2; if ( byte1 < 0xa1 || byte1 > 0xfe) { //valid first byte for G2 return CoderResult.malformedForLength(2); } outputChar = mappingTableG2.charAt(byte1 - 0xa1); } else if (byte1 == SS3 ) { //G3 if (src.remaining() < 2) return CoderResult.UNDERFLOW; byte1 = src.get() & 0xff; if ( byte1 < 0xa1 || byte1 > 0xfe) { return CoderResult.malformedForLength(2); } byte2 = src.get() & 0xff; if ( byte2 < 0xa1 || byte2 > 0xfe) { return CoderResult.malformedForLength(3); } inputSize = 3; outputChar = mappingTableG3.charAt(((byte1 - 0xa1) * 94) + byte2 - 0xa1); } else if ( byte1 <= 0x9f ) { // valid single byte outputChar = byteToCharTable.charAt(byte1); } else if (byte1 < 0xa1 || byte1 > 0xfe) { // invalid range? return CoderResult.malformedForLength(1); } else { // G1 if (src.remaining() < 1) return CoderResult.UNDERFLOW; byte2 = src.get() & 0xff; if ( byte2 < 0xa1 || byte2 > 0xfe) { return CoderResult.malformedForLength(2); } inputSize = 2; outputChar = mappingTableG1.charAt(((byte1 - 0xa1) * 94) + byte2 - 0xa1); } if (outputChar == '\uFFFD') return CoderResult.unmappableForLength(inputSize); if (!dst.hasRemaining()) return CoderResult.OVERFLOW; dst.put(outputChar); mark += inputSize; } return CoderResult.UNDERFLOW; } finally { src.position(mark); } } protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) { if (true && src.hasArray() && dst.hasArray()) return decodeArrayLoop(src, dst); else return decodeBufferLoop(src, dst); } private final static String byteToCharTable; private final static String mappingTableG1; private final static String mappingTableG2; private final static String mappingTableG3; static { byteToCharTable = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007" + "\u0008\u0009\n\u000B\u000C\r\u000E\u000F" + "\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017" + "\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F" + "\u0020\u0021\"\u0023\u0024\u0025\u0026\u0027" + "\u0028\u0029\u002A\u002B\u002C\u002D\u002E\u002F" + "\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037" + "\u0038\u0039\u003A\u003B\u003C\u003D\u003E\u003F" + "\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047" + "\u0048\u0049\u004A\u004B\u004C\u004D\u004E\u004F" + "\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057" + "\u0058\u0059\u005A\u005B\u00A5\u005D\u005E\u005F" + "\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067" + "\u0068\u0069\u006A\u006B\u006C\u006D\u006E\u006F" + "\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077" + "\u0078\u0079\u007A\u007B\u007C\u007D\u203E\u007F" + "\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087" + "\u0088\u0089\u008A\u008B\u008C\u008D\uFFFD\uFFFD" + "\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097" + "\u0098\u0099\u009A\u009B\u009C\u009D\u009E\u009F" ; mappingTableG1 = "\u3000\u3001\u3002\uFF0C\uFF0E\u30FB\uFF1A\uFF1B" + "\uFF1F\uFF01\u309B\u309C\u00B4\uFF40\u00A8\uFF3E" + "\uFFE3\uFF3F\u30FD\u30FE\u309D\u309E\u3003\u4EDD" + "\u3005\u3006\u3007\u30FC\u2014\u2010\uFF0F\uFF3C" + "\u301C\u2016\uFF5C\u2026\u2025\u2018\u2019\u201C" + "\u201D\uFF08\uFF09\u3014\u3015\uFF3B\uFF3D\uFF5B" + "\uFF5D\u3008\u3009\u300A\u300B\u300C\u300D\u300E" + "\u300F\u3010\u3011\uFF0B\u2212\u00B1\u00D7\u00F7" + "\uFF1D\u2260\uFF1C\uFF1E\u2266\u2267\u221E\u2234" + "\u2642\u2640\u00B0\u2032\u2033\u2103\uFFE5\uFF04" + "\uFFE0\uFFE1\uFF05\uFF03\uFF06\uFF0A\uFF20\u00A7" + "\u2606\u2605\u25CB\u25CF\u25CE\u25C7\u25C6\u25A1" + "\u25A0\u25B3\u25B2\u25BD\u25BC\u203B\u3012\u2192" + "\u2190\u2191\u2193\u3013\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u2208" + "\u220B\u2286\u2287\u2282\u2283\u222A\u2229\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u2227" + "\u2228\uFFE2\u21D2\u21D4\u2200\u2203\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\u2220\u22A5\u2312\u2202\u2207\u2261\u2252" + "\u226A\u226B\u221A\u223D\u221D\u2235\u222B\u222C" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u212B" + "\u2030\u266F\u266D\u266A\u2020\u2021\u00B6\uFFFD" + "\uFFFD\uFFFD\uFFFD\u25EF\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFF10\uFF11\uFF12\uFF13\uFF14" + "\uFF15\uFF16\uFF17\uFF18\uFF19\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFF21\uFF22\uFF23\uFF24" + "\uFF25\uFF26\uFF27\uFF28\uFF29\uFF2A\uFF2B\uFF2C" + "\uFF2D\uFF2E\uFF2F\uFF30\uFF31\uFF32\uFF33\uFF34" + "\uFF35\uFF36\uFF37\uFF38\uFF39\uFF3A\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFF41\uFF42\uFF43\uFF44" + "\uFF45\uFF46\uFF47\uFF48\uFF49\uFF4A\uFF4B\uFF4C" + "\uFF4D\uFF4E\uFF4F\uFF50\uFF51\uFF52\uFF53\uFF54" + "\uFF55\uFF56\uFF57\uFF58\uFF59\uFF5A\uFFFD\uFFFD" + "\uFFFD\uFFFD\u3041\u3042\u3043\u3044\u3045\u3046" + "\u3047\u3048\u3049\u304A\u304B\u304C\u304D\u304E" + "\u304F\u3050\u3051\u3052\u3053\u3054\u3055\u3056" + "\u3057\u3058\u3059\u305A\u305B\u305C\u305D\u305E" + "\u305F\u3060\u3061\u3062\u3063\u3064\u3065\u3066" + "\u3067\u3068\u3069\u306A\u306B\u306C\u306D\u306E" + "\u306F\u3070\u3071\u3072\u3073\u3074\u3075\u3076" + "\u3077\u3078\u3079\u307A\u307B\u307C\u307D\u307E" + "\u307F\u3080\u3081\u3082\u3083\u3084\u3085\u3086" + "\u3087\u3088\u3089\u308A\u308B\u308C\u308D\u308E" + "\u308F\u3090\u3091\u3092\u3093\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\u30A1\u30A2\u30A3\u30A4\u30A5\u30A6\u30A7\u30A8" + "\u30A9\u30AA\u30AB\u30AC\u30AD\u30AE\u30AF\u30B0" + "\u30B1\u30B2\u30B3\u30B4\u30B5\u30B6\u30B7\u30B8" + "\u30B9\u30BA\u30BB\u30BC\u30BD\u30BE\u30BF\u30C0" + "\u30C1\u30C2\u30C3\u30C4\u30C5\u30C6\u30C7\u30C8" + "\u30C9\u30CA\u30CB\u30CC\u30CD\u30CE\u30CF\u30D0" + "\u30D1\u30D2\u30D3\u30D4\u30D5\u30D6\u30D7\u30D8" + "\u30D9\u30DA\u30DB\u30DC\u30DD\u30DE\u30DF\u30E0" + "\u30E1\u30E2\u30E3\u30E4\u30E5\u30E6\u30E7\u30E8" + "\u30E9\u30EA\u30EB\u30EC\u30ED\u30EE\u30EF\u30F0" + "\u30F1\u30F2\u30F3\u30F4\u30F5\u30F6\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0391\u0392" + "\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039A" + "\u039B\u039C\u039D\u039E\u039F\u03A0\u03A1\u03A3" + "\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u03B1\u03B2" + "\u03B3\u03B4\u03B5\u03B6\u03B7\u03B8\u03B9\u03BA" + "\u03BB\u03BC\u03BD\u03BE\u03BF\u03C0\u03C1\u03C3" + "\u03C4\u03C5\u03C6\u03C7\u03C8\u03C9\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\u0410\u0411\u0412\u0413" + "\u0414\u0415\u0401\u0416\u0417\u0418\u0419\u041A" + "\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422" + "\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A" + "\u042B\u042C\u042D\u042E\u042F\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\u0430\u0431\u0432\u0433" + "\u0434\u0435\u0451\u0436\u0437\u0438\u0439\u043A" + "\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442" + "\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A" + "\u044B\u044C\u044D\u044E\u044F\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\u2500\u2502\u250C\u2510\u2518\u2514" + "\u251C\u252C\u2524\u2534\u253C\u2501\u2503\u250F" + "\u2513\u251B\u2517\u2523\u2533\u252B\u253B\u254B" + "\u2520\u252F\u2528\u2537\u253F\u251D\u2530\u2525" + "\u2538\u2542\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\u4E9C\u5516\u5A03\u963F\u54C0\u611B" + "\u6328\u59F6\u9022\u8475\u831C\u7A50\u60AA\u63E1" + "\u6E25\u65ED\u8466\u82A6\u9BF5\u6893\u5727\u65A1" + "\u6271\u5B9B\u59D0\u867B\u98F4\u7D62\u7DBE\u9B8E" + "\u6216\u7C9F\u88B7\u5B89\u5EB5\u6309\u6697\u6848" + "\u95C7\u978D\u674F\u4EE5\u4F0A\u4F4D\u4F9D\u5049" + "\u56F2\u5937\u59D4\u5A01\u5C09\u60DF\u610F\u6170" + "\u6613\u6905\u70BA\u754F\u7570\u79FB\u7DAD\u7DEF" + "\u80C3\u840E\u8863\u8B02\u9055\u907A\u533B\u4E95" + "\u4EA5\u57DF\u80B2\u90C1\u78EF\u4E00\u58F1\u6EA2" + "\u9038\u7A32\u8328\u828B\u9C2F\u5141\u5370\u54BD" + "\u54E1\u56E0\u59FB\u5F15\u98F2\u6DEB\u80E4\u852D" + "\u9662\u9670\u96A0\u97FB\u540B\u53F3\u5B87\u70CF" + "\u7FBD\u8FC2\u96E8\u536F\u9D5C\u7ABA\u4E11\u7893" + "\u81FC\u6E26\u5618\u5504\u6B1D\u851A\u9C3B\u59E5" + "\u53A9\u6D66\u74DC\u958F\u5642\u4E91\u904B\u96F2" + "\u834F\u990C\u53E1\u55B6\u5B30\u5F71\u6620\u66F3" + "\u6804\u6C38\u6CF3\u6D29\u745B\u76C8\u7A4E\u9834" + "\u82F1\u885B\u8A60\u92ED\u6DB2\u75AB\u76CA\u99C5" + "\u60A6\u8B01\u8D8A\u95B2\u698E\u53AD\u5186\u5712" + "\u5830\u5944\u5BB4\u5EF6\u6028\u63A9\u63F4\u6CBF" + "\u6F14\u708E\u7114\u7159\u71D5\u733F\u7E01\u8276" + "\u82D1\u8597\u9060\u925B\u9D1B\u5869\u65BC\u6C5A" + "\u7525\u51F9\u592E\u5965\u5F80\u5FDC\u62BC\u65FA" + "\u6A2A\u6B27\u6BB4\u738B\u7FC1\u8956\u9D2C\u9D0E" + "\u9EC4\u5CA1\u6C96\u837B\u5104\u5C4B\u61B6\u81C6" + "\u6876\u7261\u4E59\u4FFA\u5378\u6069\u6E29\u7A4F" + "\u97F3\u4E0B\u5316\u4EEE\u4F55\u4F3D\u4FA1\u4F73" + "\u52A0\u53EF\u5609\u590F\u5AC1\u5BB6\u5BE1\u79D1" + "\u6687\u679C\u67B6\u6B4C\u6CB3\u706B\u73C2\u798D" + "\u79BE\u7A3C\u7B87\u82B1\u82DB\u8304\u8377\u83EF" + "\u83D3\u8766\u8AB2\u5629\u8CA8\u8FE6\u904E\u971E" + "\u868A\u4FC4\u5CE8\u6211\u7259\u753B\u81E5\u82BD" + "\u86FE\u8CC0\u96C5\u9913\u99D5\u4ECB\u4F1A\u89E3" + "\u56DE\u584A\u58CA\u5EFB\u5FEB\u602A\u6094\u6062" + "\u61D0\u6212\u62D0\u6539\u9B41\u6666\u68B0\u6D77" +Lines 1–500 of 7178. Load more
/* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* */ package sun.nio.cs.ext; import java.nio.CharBuffer; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; import sun.nio.cs.HistoricallyNamedCharset; public class IBM33722 extends Charset implements HistoricallyNamedCharset { public IBM33722() { super("x-IBM33722", ExtendedCharsets.aliasesFor("x-IBM33722")); } public String historicalName() { return "Cp33722"; } public boolean contains(Charset cs) { return (cs instanceof IBM33722); } public CharsetDecoder newDecoder() { return new Decoder(this); } public CharsetEncoder newEncoder() { return new Encoder(this); } /** * These accessors are temporarily supplied while sun.io * converters co-exist with the sun.nio.cs.{ext} charset coders * These facilitate sharing of conversion tables between the * two co-existing implementations. When sun.io converters * are made extinct these will be unncessary and should be removed */ public String getDecoderSingleByteMappings() { return Decoder.byteToCharTable; } public String getDecoderMappingTableG1() { return Decoder.mappingTableG1; } public String getDecoderMappingTableG2() { return Decoder.mappingTableG2; } public String getDecoderMappingTableG3() { return Decoder.mappingTableG3; } public short[] getEncoderIndex1() { return Encoder.index1; } public String getEncoderIndex2() { return Encoder.index2; } public String getEncoderIndex2a() { return Encoder.index2a; } public String getEncoderIndex2b() { return Encoder.index2b; } protected static class Decoder extends CharsetDecoder { private final int G0 = 0; private final int G1 = 1; private final int G2 = 2; private final int G3 = 3; private final int G4 = 4; private final int SS2 = 0x8E; private final int SS3 = 0x8F; private int firstByte, state; public Decoder(Charset cs) { super(cs, 1.0f, 1.0f); } private CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) { byte[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); assert (sp <= sl); sp = (sp <= sl ? sp : sl); char[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); assert (dp <= dl); dp = (dp <= dl ? dp : dl); try { while (sp < sl) { int byte1, byte2; int inputSize = 1; char outputChar = '\uFFFD'; byte1 = sa[sp] & 0xff; if (byte1 == SS2) { if (sl - sp < 2) { return CoderResult.UNDERFLOW; } byte1 = sa[sp + 1] & 0xff; inputSize = 2; if ( byte1 < 0xa1 || byte1 > 0xfe) { //valid first byte for G2 return CoderResult.malformedForLength(2); } outputChar = mappingTableG2.charAt(byte1 - 0xa1); } else if(byte1 == SS3 ) { //G3 if (sl - sp < 3) { return CoderResult.UNDERFLOW; } byte1 = sa[sp + 1] & 0xff; byte2 = sa[sp + 2] & 0xff; inputSize = 3; if ( byte1 < 0xa1 || byte1 > 0xfe) { return CoderResult.malformedForLength(2); } if ( byte2 < 0xa1 || byte2 > 0xfe) { return CoderResult.malformedForLength(3); } outputChar = mappingTableG3.charAt(((byte1 - 0xa1) * 94) + byte2 - 0xa1); } else if ( byte1 <= 0x9f ) { // valid single byte outputChar = byteToCharTable.charAt(byte1); } else if (byte1 < 0xa1 || byte1 > 0xfe) { // invalid range? return CoderResult.malformedForLength(1); } else { // G1 if (sl - sp < 2) { return CoderResult.UNDERFLOW; } byte2 = sa[sp + 1] & 0xff; inputSize = 2; if ( byte2 < 0xa1 || byte2 > 0xfe) { return CoderResult.malformedForLength(2); } outputChar = mappingTableG1.charAt(((byte1 - 0xa1) * 94) + byte2 - 0xa1); } if (outputChar == '\uFFFD') return CoderResult.unmappableForLength(inputSize); if (dl - dp < 1) return CoderResult.OVERFLOW; da[dp++] = outputChar; sp += inputSize; } return CoderResult.UNDERFLOW; } finally { src.position(sp - src.arrayOffset()); dst.position(dp - dst.arrayOffset()); } } private CoderResult decodeBufferLoop(ByteBuffer src, CharBuffer dst) { int mark = src.position(); try { while (src.hasRemaining()) { int byte1, byte2; int inputSize = 1; char outputChar = '\uFFFD'; byte1 = src.get() & 0xff; if (byte1 == SS2) { if (!src.hasRemaining()) return CoderResult.UNDERFLOW; byte1 = src.get() & 0xff; inputSize = 2; if ( byte1 < 0xa1 || byte1 > 0xfe) { //valid first byte for G2 return CoderResult.malformedForLength(2); } outputChar = mappingTableG2.charAt(byte1 - 0xa1); } else if (byte1 == SS3 ) { //G3 if (src.remaining() < 2) return CoderResult.UNDERFLOW; byte1 = src.get() & 0xff; if ( byte1 < 0xa1 || byte1 > 0xfe) { return CoderResult.malformedForLength(2); } byte2 = src.get() & 0xff; if ( byte2 < 0xa1 || byte2 > 0xfe) { return CoderResult.malformedForLength(3); } inputSize = 3; outputChar = mappingTableG3.charAt(((byte1 - 0xa1) * 94) + byte2 - 0xa1); } else if ( byte1 <= 0x9f ) { // valid single byte outputChar = byteToCharTable.charAt(byte1); } else if (byte1 < 0xa1 || byte1 > 0xfe) { // invalid range? return CoderResult.malformedForLength(1); } else { // G1 if (src.remaining() < 1) return CoderResult.UNDERFLOW; byte2 = src.get() & 0xff; if ( byte2 < 0xa1 || byte2 > 0xfe) { return CoderResult.malformedForLength(2); } inputSize = 2; outputChar = mappingTableG1.charAt(((byte1 - 0xa1) * 94) + byte2 - 0xa1); } if (outputChar == '\uFFFD') return CoderResult.unmappableForLength(inputSize); if (!dst.hasRemaining()) return CoderResult.OVERFLOW; dst.put(outputChar); mark += inputSize; } return CoderResult.UNDERFLOW; } finally { src.position(mark); } } protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) { if (true && src.hasArray() && dst.hasArray()) return decodeArrayLoop(src, dst); else return decodeBufferLoop(src, dst); } private final static String byteToCharTable; private final static String mappingTableG1; private final static String mappingTableG2; private final static String mappingTableG3; static { byteToCharTable = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007" + "\u0008\u0009\n\u000B\u000C\r\u000E\u000F" + "\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017" + "\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F" + "\u0020\u0021\"\u0023\u0024\u0025\u0026\u0027" + "\u0028\u0029\u002A\u002B\u002C\u002D\u002E\u002F" + "\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037" + "\u0038\u0039\u003A\u003B\u003C\u003D\u003E\u003F" + "\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047" + "\u0048\u0049\u004A\u004B\u004C\u004D\u004E\u004F" + "\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057" + "\u0058\u0059\u005A\u005B\u00A5\u005D\u005E\u005F" + "\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067" + "\u0068\u0069\u006A\u006B\u006C\u006D\u006E\u006F" + "\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077" + "\u0078\u0079\u007A\u007B\u007C\u007D\u203E\u007F" + "\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087" + "\u0088\u0089\u008A\u008B\u008C\u008D\uFFFD\uFFFD" + "\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097" + "\u0098\u0099\u009A\u009B\u009C\u009D\u009E\u009F" ; mappingTableG1 = "\u3000\u3001\u3002\uFF0C\uFF0E\u30FB\uFF1A\uFF1B" + "\uFF1F\uFF01\u309B\u309C\u00B4\uFF40\u00A8\uFF3E" + "\uFFE3\uFF3F\u30FD\u30FE\u309D\u309E\u3003\u4EDD" + "\u3005\u3006\u3007\u30FC\u2014\u2010\uFF0F\uFF3C" + "\u301C\u2016\uFF5C\u2026\u2025\u2018\u2019\u201C" + "\u201D\uFF08\uFF09\u3014\u3015\uFF3B\uFF3D\uFF5B" + "\uFF5D\u3008\u3009\u300A\u300B\u300C\u300D\u300E" + "\u300F\u3010\u3011\uFF0B\u2212\u00B1\u00D7\u00F7" + "\uFF1D\u2260\uFF1C\uFF1E\u2266\u2267\u221E\u2234" + "\u2642\u2640\u00B0\u2032\u2033\u2103\uFFE5\uFF04" + "\uFFE0\uFFE1\uFF05\uFF03\uFF06\uFF0A\uFF20\u00A7" + "\u2606\u2605\u25CB\u25CF\u25CE\u25C7\u25C6\u25A1" + "\u25A0\u25B3\u25B2\u25BD\u25BC\u203B\u3012\u2192" + "\u2190\u2191\u2193\u3013\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u2208" + "\u220B\u2286\u2287\u2282\u2283\u222A\u2229\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u2227" + "\u2228\uFFE2\u21D2\u21D4\u2200\u2203\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\u2220\u22A5\u2312\u2202\u2207\u2261\u2252" + "\u226A\u226B\u221A\u223D\u221D\u2235\u222B\u222C" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u212B" + "\u2030\u266F\u266D\u266A\u2020\u2021\u00B6\uFFFD" + "\uFFFD\uFFFD\uFFFD\u25EF\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFF10\uFF11\uFF12\uFF13\uFF14" + "\uFF15\uFF16\uFF17\uFF18\uFF19\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFF21\uFF22\uFF23\uFF24" + "\uFF25\uFF26\uFF27\uFF28\uFF29\uFF2A\uFF2B\uFF2C" + "\uFF2D\uFF2E\uFF2F\uFF30\uFF31\uFF32\uFF33\uFF34" + "\uFF35\uFF36\uFF37\uFF38\uFF39\uFF3A\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFF41\uFF42\uFF43\uFF44" + "\uFF45\uFF46\uFF47\uFF48\uFF49\uFF4A\uFF4B\uFF4C" + "\uFF4D\uFF4E\uFF4F\uFF50\uFF51\uFF52\uFF53\uFF54" + "\uFF55\uFF56\uFF57\uFF58\uFF59\uFF5A\uFFFD\uFFFD" + "\uFFFD\uFFFD\u3041\u3042\u3043\u3044\u3045\u3046" + "\u3047\u3048\u3049\u304A\u304B\u304C\u304D\u304E" + "\u304F\u3050\u3051\u3052\u3053\u3054\u3055\u3056" + "\u3057\u3058\u3059\u305A\u305B\u305C\u305D\u305E" + "\u305F\u3060\u3061\u3062\u3063\u3064\u3065\u3066" + "\u3067\u3068\u3069\u306A\u306B\u306C\u306D\u306E" + "\u306F\u3070\u3071\u3072\u3073\u3074\u3075\u3076" + "\u3077\u3078\u3079\u307A\u307B\u307C\u307D\u307E" + "\u307F\u3080\u3081\u3082\u3083\u3084\u3085\u3086" + "\u3087\u3088\u3089\u308A\u308B\u308C\u308D\u308E" + "\u308F\u3090\u3091\u3092\u3093\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\u30A1\u30A2\u30A3\u30A4\u30A5\u30A6\u30A7\u30A8" + "\u30A9\u30AA\u30AB\u30AC\u30AD\u30AE\u30AF\u30B0" + "\u30B1\u30B2\u30B3\u30B4\u30B5\u30B6\u30B7\u30B8" + "\u30B9\u30BA\u30BB\u30BC\u30BD\u30BE\u30BF\u30C0" + "\u30C1\u30C2\u30C3\u30C4\u30C5\u30C6\u30C7\u30C8" + "\u30C9\u30CA\u30CB\u30CC\u30CD\u30CE\u30CF\u30D0" + "\u30D1\u30D2\u30D3\u30D4\u30D5\u30D6\u30D7\u30D8" + "\u30D9\u30DA\u30DB\u30DC\u30DD\u30DE\u30DF\u30E0" + "\u30E1\u30E2\u30E3\u30E4\u30E5\u30E6\u30E7\u30E8" + "\u30E9\u30EA\u30EB\u30EC\u30ED\u30EE\u30EF\u30F0" + "\u30F1\u30F2\u30F3\u30F4\u30F5\u30F6\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0391\u0392" + "\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039A" + "\u039B\u039C\u039D\u039E\u039F\u03A0\u03A1\u03A3" + "\u03A4\u03A5\u03A6\u03A7\u03A8\u03A9\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u03B1\u03B2" + "\u03B3\u03B4\u03B5\u03B6\u03B7\u03B8\u03B9\u03BA" + "\u03BB\u03BC\u03BD\u03BE\u03BF\u03C0\u03C1\u03C3" + "\u03C4\u03C5\u03C6\u03C7\u03C8\u03C9\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\u0410\u0411\u0412\u0413" + "\u0414\u0415\u0401\u0416\u0417\u0418\u0419\u041A" + "\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422" + "\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A" + "\u042B\u042C\u042D\u042E\u042F\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\u0430\u0431\u0432\u0433" + "\u0434\u0435\u0451\u0436\u0437\u0438\u0439\u043A" + "\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442" + "\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A" + "\u044B\u044C\u044D\u044E\u044F\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\u2500\u2502\u250C\u2510\u2518\u2514" + "\u251C\u252C\u2524\u2534\u253C\u2501\u2503\u250F" + "\u2513\u251B\u2517\u2523\u2533\u252B\u253B\u254B" + "\u2520\u252F\u2528\u2537\u253F\u251D\u2530\u2525" + "\u2538\u2542\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD" + "\uFFFD\uFFFD\u4E9C\u5516\u5A03\u963F\u54C0\u611B" + "\u6328\u59F6\u9022\u8475\u831C\u7A50\u60AA\u63E1" + "\u6E25\u65ED\u8466\u82A6\u9BF5\u6893\u5727\u65A1" + "\u6271\u5B9B\u59D0\u867B\u98F4\u7D62\u7DBE\u9B8E" + "\u6216\u7C9F\u88B7\u5B89\u5EB5\u6309\u6697\u6848" + "\u95C7\u978D\u674F\u4EE5\u4F0A\u4F4D\u4F9D\u5049" + "\u56F2\u5937\u59D4\u5A01\u5C09\u60DF\u610F\u6170" + "\u6613\u6905\u70BA\u754F\u7570\u79FB\u7DAD\u7DEF" + "\u80C3\u840E\u8863\u8B02\u9055\u907A\u533B\u4E95" + "\u4EA5\u57DF\u80B2\u90C1\u78EF\u4E00\u58F1\u6EA2" + "\u9038\u7A32\u8328\u828B\u9C2F\u5141\u5370\u54BD" + "\u54E1\u56E0\u59FB\u5F15\u98F2\u6DEB\u80E4\u852D" + "\u9662\u9670\u96A0\u97FB\u540B\u53F3\u5B87\u70CF" + "\u7FBD\u8FC2\u96E8\u536F\u9D5C\u7ABA\u4E11\u7893" + "\u81FC\u6E26\u5618\u5504\u6B1D\u851A\u9C3B\u59E5" + "\u53A9\u6D66\u74DC\u958F\u5642\u4E91\u904B\u96F2" + "\u834F\u990C\u53E1\u55B6\u5B30\u5F71\u6620\u66F3" + "\u6804\u6C38\u6CF3\u6D29\u745B\u76C8\u7A4E\u9834" + "\u82F1\u885B\u8A60\u92ED\u6DB2\u75AB\u76CA\u99C5" + "\u60A6\u8B01\u8D8A\u95B2\u698E\u53AD\u5186\u5712" + "\u5830\u5944\u5BB4\u5EF6\u6028\u63A9\u63F4\u6CBF" + "\u6F14\u708E\u7114\u7159\u71D5\u733F\u7E01\u8276" + "\u82D1\u8597\u9060\u925B\u9D1B\u5869\u65BC\u6C5A" + "\u7525\u51F9\u592E\u5965\u5F80\u5FDC\u62BC\u65FA" + "\u6A2A\u6B27\u6BB4\u738B\u7FC1\u8956\u9D2C\u9D0E" + "\u9EC4\u5CA1\u6C96\u837B\u5104\u5C4B\u61B6\u81C6" + "\u6876\u7261\u4E59\u4FFA\u5378\u6069\u6E29\u7A4F" + "\u97F3\u4E0B\u5316\u4EEE\u4F55\u4F3D\u4FA1\u4F73" + "\u52A0\u53EF\u5609\u590F\u5AC1\u5BB6\u5BE1\u79D1" + "\u6687\u679C\u67B6\u6B4C\u6CB3\u706B\u73C2\u798D" + "\u79BE\u7A3C\u7B87\u82B1\u82DB\u8304\u8377\u83EF" + "\u83D3\u8766\u8AB2\u5629\u8CA8\u8FE6\u904E\u971E" + "\u868A\u4FC4\u5CE8\u6211\u7259\u753B\u81E5\u82BD" + "\u86FE\u8CC0\u96C5\u9913\u99D5\u4ECB\u4F1A\u89E3" + "\u56DE\u584A\u58CA\u5EFB\u5FEB\u602A\u6094\u6062" + "\u61D0\u6212\u62D0\u6539\u9B41\u6666\u68B0\u6D77" +