jdk/src/share/classes/sun/io/ByteToCharISO2022CN.java
changeset 10372 2f6d68f22eae
parent 10321 64f7ee2f31dd
parent 10371 7da2112e4236
child 10373 d4c5e59b82f8
equal deleted inserted replaced
10321:64f7ee2f31dd 10372:2f6d68f22eae
     1 /*
       
     2  * Copyright (c) 1997, 2001, 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 sun.io;
       
    27 
       
    28 /**
       
    29  * @author Tom Zhou
       
    30  */
       
    31 public class ByteToCharISO2022CN extends ByteToCharConverter
       
    32 {
       
    33     private String SODesignator[];
       
    34     private String SS2Designator[] = null;
       
    35     private String SS3Designator[] = null;
       
    36     private ByteToCharConverter SOConverter[];
       
    37     private ByteToCharConverter SS2Converter[] = null;
       
    38     private ByteToCharConverter SS3Converter[] = null;
       
    39 
       
    40     private static final byte ISO_ESC = 0x1b;
       
    41     private static final byte ISO_SI = 0x0f;
       
    42     private static final byte ISO_SO = 0x0e;
       
    43     private static final byte ISO_SS2_7 = 0x4e;
       
    44     private static final byte ISO_SS3_7 = 0x4f;
       
    45     private static final byte MSB = (byte)0x80;
       
    46     private static final char REPLACE_CHAR = '\uFFFD';
       
    47     private static final byte maximumDesignatorLength = 3;
       
    48 
       
    49     private static final byte SOFlag = 0;
       
    50     private static final byte SS2Flag = 1;
       
    51     private static final byte SS3Flag = 2;
       
    52     private static final byte G0 = 0;
       
    53     private static final byte G1 = 1;
       
    54 
       
    55     private ByteToCharConverter tmpConverter[];
       
    56 
       
    57     private int curSODes, curSS2Des, curSS3Des;
       
    58     private boolean shiftout;
       
    59 
       
    60     private byte remainByte[] = new byte[10];
       
    61     private int remainIndex = -1;
       
    62     private byte state, firstByte;
       
    63 
       
    64     public void reset()
       
    65     {
       
    66         int i = 0;
       
    67 
       
    68         shiftout = false;
       
    69         state = G0;
       
    70         firstByte = 0;
       
    71 
       
    72         curSODes = 0;
       
    73         curSS2Des = 0;
       
    74         curSS3Des = 0;
       
    75 
       
    76         charOff = byteOff = 0;
       
    77         remainIndex = -1;
       
    78 
       
    79         for(i = 0; i < remainByte.length; i++)
       
    80             remainByte[i] = 0;
       
    81     }
       
    82 
       
    83     public int flush(char[] output, int outStart, int outEnd)
       
    84         throws MalformedInputException
       
    85     {
       
    86         int i;
       
    87         if (state != G0) {
       
    88             badInputLength = 0;
       
    89             throw new MalformedInputException();
       
    90         }
       
    91         reset();
       
    92         return 0;
       
    93     }
       
    94 
       
    95     private byte[] savetyGetSrc(byte[] input, int inOff, int inEnd, int nbytes)
       
    96     {
       
    97         int i;
       
    98         byte tmp[];
       
    99 
       
   100         if(inOff <= (inEnd-nbytes+1))
       
   101             tmp = new byte[nbytes];
       
   102         else
       
   103             tmp = new byte[inEnd-inOff];
       
   104 
       
   105         for(i = 0; i < tmp.length; i++)
       
   106             tmp[i] = input[inOff+i];
       
   107         return tmp;
       
   108     }
       
   109 
       
   110     private char getUnicode(byte byte1, byte byte2, byte shiftFlag)
       
   111     {
       
   112         byte1 |= MSB;
       
   113         byte2 |= MSB;
       
   114         char[] tmpChar = new char[1];
       
   115 
       
   116         switch(shiftFlag) {
       
   117         case SOFlag:
       
   118             try {
       
   119                 byte[] tmpByte = {byte1,byte2};
       
   120                 SOConverter[curSODes].convert(tmpByte, 0, 2, tmpChar, 0, 1);
       
   121             }
       
   122             catch (Exception e) {}
       
   123             break;
       
   124         case SS2Flag:
       
   125             try {
       
   126                 byte[] tmpByte = {(byte)0x8e, (byte)0xa2, byte1, byte2};
       
   127                 SS2Converter[curSS2Des].convert(tmpByte, 0, 4, tmpChar, 0, 1);
       
   128             }
       
   129             catch (Exception e){}
       
   130             break;
       
   131         case SS3Flag:
       
   132             try {
       
   133                 byte[] tmpByte = {(byte)0x8e, (byte)0xa3, byte1,byte2};
       
   134                 SS3Converter[curSS3Des].convert(tmpByte, 0, 4, tmpChar, 0, 1);
       
   135             }
       
   136             catch (Exception e){}
       
   137             break;
       
   138         default:
       
   139             tmpChar[0] = REPLACE_CHAR;
       
   140         }
       
   141         return tmpChar[0];
       
   142     }
       
   143 
       
   144     public final int convert(byte[] input, int inOff, int inEnd,
       
   145                              char[] output, int outOff, int outEnd)
       
   146                              throws ConversionBufferFullException,
       
   147                                     MalformedInputException
       
   148     {
       
   149         int i;
       
   150         int DesignatorLength = 0;
       
   151         charOff  =  outOff;
       
   152         byteOff  =  inOff;
       
   153 
       
   154         // Loop until we hit the end of the input
       
   155         while (byteOff < inEnd) {
       
   156             // If we don't have room for the output, throw an exception
       
   157             if (charOff >= outEnd)
       
   158                 throw new ConversionBufferFullException();
       
   159             if(remainIndex < 0) {
       
   160                 remainByte[0] = input[byteOff];
       
   161                 remainIndex = 0;
       
   162                 byteOff++;
       
   163             }
       
   164             switch (remainByte[0]) {
       
   165             case ISO_SO:
       
   166                 shiftout = true;
       
   167                 if(remainIndex > 0)
       
   168                     System.arraycopy(remainByte, 1, remainByte, 0, remainIndex);
       
   169                 remainIndex--;
       
   170                 break;
       
   171             case ISO_SI:
       
   172                 shiftout = false;
       
   173                 if(remainIndex > 0)
       
   174                     System.arraycopy(remainByte, 1, remainByte, 0, remainIndex);
       
   175                 remainIndex--;
       
   176                 break;
       
   177              case ISO_ESC:
       
   178                 byte tmp[] = savetyGetSrc(input, byteOff, inEnd,
       
   179                                (maximumDesignatorLength-remainIndex));
       
   180                 System.arraycopy(tmp, 0, remainByte, remainIndex+1, tmp.length);
       
   181 
       
   182                 remainIndex += tmp.length;
       
   183                 byteOff += tmp.length;
       
   184                 if(tmp.length<(maximumDesignatorLength-remainIndex))
       
   185                     break;
       
   186                 String tmpString = new String(remainByte, 1, remainIndex);
       
   187                 for (i = 0; i < SODesignator.length; i++) {
       
   188                     if(tmpString.indexOf(SODesignator[i]) == 0) {
       
   189                         curSODes = i;
       
   190                         DesignatorLength = SODesignator[i].length();
       
   191                         break;
       
   192                     }
       
   193                 }
       
   194 
       
   195                 if (DesignatorLength == 0) { // designator not recognized
       
   196                    badInputLength = tmp.length;
       
   197                    throw new MalformedInputException();
       
   198                 }
       
   199 
       
   200                 if (i == SODesignator.length) {
       
   201                     for (i = 0; i < SS2Designator.length; i++) {
       
   202                         if(tmpString.indexOf(SS2Designator[i]) == 0) {
       
   203                             curSS2Des = i;
       
   204                             DesignatorLength = SS2Designator[i].length();
       
   205                             break;
       
   206                         }
       
   207                     }
       
   208                     if(i == SS2Designator.length) {
       
   209                         for(i = 0; i < SS3Designator.length; i++) {
       
   210                             if (tmpString.indexOf(SS3Designator[i]) == 0) {
       
   211                                 curSS3Des = i;
       
   212                                 DesignatorLength = SS3Designator[i].length();
       
   213                                 break;
       
   214                             }
       
   215                         }
       
   216                         if (i == SS3Designator.length) {
       
   217                             switch(remainByte[1]) {
       
   218                             case ISO_SS2_7:
       
   219                                 output[charOff] = getUnicode(remainByte[2],
       
   220                                                           remainByte[3],
       
   221                                                           SS2Flag);
       
   222                                 charOff++;
       
   223                                 DesignatorLength = 3;
       
   224                                 break;
       
   225                             case ISO_SS3_7:
       
   226                                 output[charOff] = getUnicode(remainByte[2],
       
   227                                                           remainByte[3],
       
   228                                                           SS3Flag);
       
   229                                 charOff++;
       
   230                                 DesignatorLength = 3;
       
   231                                 break;
       
   232                             default:
       
   233                                 DesignatorLength = 0;
       
   234                             }
       
   235                         }
       
   236                     }
       
   237                 }
       
   238                 if (remainIndex > DesignatorLength) {
       
   239                     for(i = 0; i < remainIndex-DesignatorLength; i++)
       
   240                         remainByte[i] = remainByte[DesignatorLength+1+i];
       
   241                     remainIndex = i-1;
       
   242                 } else {
       
   243                     remainIndex = -1;
       
   244                 }
       
   245                 break;
       
   246             default:
       
   247                 if (!shiftout) {
       
   248                     output[charOff] = (char)remainByte[0];
       
   249                     charOff++;
       
   250                 } else {
       
   251                     switch (state) {
       
   252                     case G0:
       
   253                         firstByte = remainByte[0];
       
   254                         state = G1;
       
   255                         break;
       
   256                     case G1:
       
   257                         output[charOff] = getUnicode(firstByte, remainByte[0],
       
   258                                                   SOFlag);
       
   259                         charOff++;
       
   260                         state = G0;
       
   261                         break;
       
   262                     }
       
   263                 }
       
   264                 if (remainIndex > 0)
       
   265                     System.arraycopy(remainByte, 1, remainByte, 0, remainIndex);
       
   266                 remainIndex--;
       
   267             }
       
   268         }
       
   269         return charOff - outOff;
       
   270     }
       
   271 
       
   272     public ByteToCharISO2022CN()
       
   273     {
       
   274         SODesignator = new String[3];
       
   275         SODesignator[0] = "$A";
       
   276         SODesignator[1] = "$)A";
       
   277         SODesignator[2] = "$)G";
       
   278         SS2Designator = new String[1];
       
   279         SS2Designator[0] = "$*H";
       
   280         SS3Designator = new String[1];
       
   281         SS3Designator[0] = "$+I";
       
   282 
       
   283         SOConverter = new ByteToCharConverter[3];
       
   284         SS2Converter = new ByteToCharConverter[1];
       
   285         SS3Converter = new ByteToCharConverter[1];
       
   286 
       
   287         try {
       
   288             SOConverter[0] = SOConverter[1]
       
   289                         = ByteToCharConverter.getConverter("GB2312");
       
   290             SOConverter[2] = SS2Converter[0] = SS3Converter[0]
       
   291                         = ByteToCharConverter.getConverter("CNS11643");
       
   292         } catch (Exception e) {};
       
   293     }
       
   294 
       
   295     // Return the character set id
       
   296     public String getCharacterEncoding()
       
   297     {
       
   298         return "ISO2022CN";
       
   299     }
       
   300 }