src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM29626C.java.template
changeset 53474 1262a93634c2
equal deleted inserted replaced
53473:9366628d727b 53474:1262a93634c2
       
     1 /*
       
     2  * Copyright (c) 2002, 2019, 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             }
       
   305         }
       
   306 
       
   307         // Make some protected methods public for use by JISAutoDetect
       
   308         public CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {
       
   309             if (src.hasArray() && dst.hasArray())
       
   310                 return decodeArrayLoop(src, dst);
       
   311             else
       
   312                 return decodeBufferLoop(src, dst);
       
   313         }
       
   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;
       
   497             int     inputSize = 0;                 // Size of input
       
   498             byte[]  tmpBuf = new byte[3];
       
   499 
       
   500             try {
       
   501                 while (sp < sl) {
       
   502                     outputByte = tmpBuf;
       
   503                     char c = sa[sp];
       
   504                     if (Character.isSurrogate(c)) {
       
   505                         if (sgp.parse(c, sa, sp, sl) < 0)
       
   506                             return sgp.error();
       
   507                         return sgp.unmappableResult();
       
   508                     }
       
   509                     outputSize = encodeSingle(c, outputByte);
       
   510                     if (outputSize == 0) { // DoubleByte
       
   511                         int ncode = encodeDouble(c);
       
   512                         if (ncode != UNMAPPABLE_ENCODING) {
       
   513                             if ((ncode & 0xFF0000) == 0) {
       
   514                                 outputByte[0] = (byte) ((ncode & 0xff00) >> 8);
       
   515                                 outputByte[1] = (byte) (ncode & 0xff);
       
   516                                 outputSize = 2;
       
   517                             } else {
       
   518                                 outputByte[0] = (byte) 0x8f;
       
   519                                 outputByte[1] = (byte) ((ncode & 0xff00) >> 8);
       
   520                                 outputByte[2] = (byte) (ncode & 0xff);
       
   521                                 outputSize = 3;
       
   522                             }
       
   523                         } else {
       
   524                             return CoderResult.unmappableForLength(1);
       
   525                         }
       
   526                     }
       
   527                     if (dl - dp < outputSize)
       
   528                         return CoderResult.OVERFLOW;
       
   529                     // Put the byte in the output buffer
       
   530                     for (int i = 0; i < outputSize; i++) {
       
   531                         da[dp++] = outputByte[i];
       
   532                     }
       
   533                     sp++;
       
   534                 }
       
   535                 return CoderResult.UNDERFLOW;
       
   536             } finally {
       
   537                 src.position(sp - src.arrayOffset());
       
   538                 dst.position(dp - dst.arrayOffset());
       
   539             }
       
   540         }
       
   541 
       
   542         private CoderResult encodeBufferLoop(CharBuffer src,
       
   543                                              ByteBuffer dst)
       
   544         {
       
   545             int outputSize = 0;
       
   546             byte[]  outputByte;
       
   547             int     inputSize = 0;                 // Size of input
       
   548             byte[]  tmpBuf = new byte[3];
       
   549 
       
   550             int mark = src.position();
       
   551 
       
   552             try {
       
   553                 while (src.hasRemaining()) {
       
   554                     outputByte = tmpBuf;
       
   555                     char c = src.get();
       
   556                     if (Character.isSurrogate(c)) {
       
   557                         if (sgp.parse(c, src) < 0)
       
   558                             return sgp.error();
       
   559                         return sgp.unmappableResult();
       
   560                     }
       
   561                     outputSize = encodeSingle(c, outputByte);
       
   562                     if (outputSize == 0) { // DoubleByte
       
   563                         int ncode = encodeDouble(c);
       
   564                         if (ncode != UNMAPPABLE_ENCODING) {
       
   565                             if ((ncode & 0xFF0000) == 0) {
       
   566                                 outputByte[0] = (byte) ((ncode & 0xff00) >> 8);
       
   567                                 outputByte[1] = (byte) (ncode & 0xff);
       
   568                                 outputSize = 2;
       
   569                             } else {
       
   570                                 outputByte[0] = (byte) 0x8f;
       
   571                                 outputByte[1] = (byte) ((ncode & 0xff00) >> 8);
       
   572                                 outputByte[2] = (byte) (ncode & 0xff);
       
   573                                 outputSize = 3;
       
   574                             }
       
   575                         } else {
       
   576                             return CoderResult.unmappableForLength(1);
       
   577                         }
       
   578                     }
       
   579                     if (dst.remaining() < outputSize)
       
   580                         return CoderResult.OVERFLOW;
       
   581                     // Put the byte in the output buffer
       
   582                     for (int i = 0; i < outputSize; i++) {
       
   583                         dst.put(outputByte[i]);
       
   584                     }
       
   585                     mark++;
       
   586                 }
       
   587                 return CoderResult.UNDERFLOW;
       
   588             } finally {
       
   589                 src.position(mark);
       
   590             }
       
   591         }
       
   592 
       
   593         protected CoderResult encodeLoop(CharBuffer src,
       
   594                                          ByteBuffer dst)
       
   595         {
       
   596             if (src.hasArray() && dst.hasArray())
       
   597                 return encodeArrayLoop(src, dst);
       
   598             else
       
   599                 return encodeBufferLoop(src, dst);
       
   600         }
       
   601     }
       
   602 }