jdk/src/share/classes/sun/io/ByteToCharEUC_TW.java
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 2913 39a9cc073b84
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 1996-2004 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.io;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import sun.nio.cs.ext.EUC_TW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * @author Limin Shi
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
public class ByteToCharEUC_TW extends ByteToCharConverter
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
    private final byte G0 = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
    private final byte G1 = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
    private final byte G2 = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
    private final byte G3 = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
    private final byte G4 = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
    private final byte MSB = (byte) 0x80;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
    private final byte SS2 = (byte) 0x8E;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
    private final byte P2 = (byte) 0xA2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
    private final byte P3 = (byte) 0xA3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
    protected final char REPLACE_CHAR = '\uFFFD';
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    private byte firstByte = 0, state = G0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
    public static String unicodeCNS2, unicodeCNS3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    private static String unicodeCNS4, unicodeCNS5, unicodeCNS6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    private static String unicodeCNS7, unicodeCNS15;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    private int cnsPlane = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    private final static EUC_TW nioCoder = new EUC_TW();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    public static String unicodeCNS1 = nioCoder.getUnicodeCNS1();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
        static String[] cnsChars = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
            unicodeCNS2 = nioCoder.getUnicodeCNS2(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
            unicodeCNS3 = nioCoder.getUnicodeCNS3(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
            unicodeCNS4 = nioCoder.getUnicodeCNS4(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
            unicodeCNS5 = nioCoder.getUnicodeCNS5(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
            unicodeCNS6 = nioCoder.getUnicodeCNS6(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
            unicodeCNS7 = nioCoder.getUnicodeCNS7(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
            unicodeCNS15 = nioCoder.getUnicodeCNS15()
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
            };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    public ByteToCharEUC_TW() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    public int flush(char[] output, int outStart, int outEnd)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        throws MalformedInputException
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
        if (state != G0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
            state = G0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
            firstByte = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
            badInputLength = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
            throw new MalformedInputException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
        reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    public void reset() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
        state = G0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
        firstByte = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        byteOff = charOff = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
     * Character conversion
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    public int convert(byte[] input, int inOff, int inEnd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
                       char[] output, int outOff, int outEnd)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        throws UnknownCharacterException, MalformedInputException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
               ConversionBufferFullException
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        int inputSize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        char outputChar = (char) 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        byteOff = inOff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        charOff = outOff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        cnsPlane = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        while (byteOff < inEnd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
            if (charOff >= outEnd)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
                throw new ConversionBufferFullException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
            switch (state) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
            case G0:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
                if ( (input[byteOff] & MSB) == 0) {     // ASCII
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
                    outputChar = (char) input[byteOff];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
                } else if (input[byteOff] == SS2) {     // Codeset 2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                    state = G2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
                } else {                                // Codeset 1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
                    firstByte = input[byteOff];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
                    state = G1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
            case G1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
                inputSize = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
                if ( (input[byteOff] & MSB) != 0) {     // 2nd byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
                    cnsPlane = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
                    outputChar = convToUnicode(firstByte,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
                                        input[byteOff], unicodeCNS1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
                } else {                                // Error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
                    badInputLength = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
                    throw new MalformedInputException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
                firstByte = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
                state = G0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
            case G2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
                cnsPlane = (input[byteOff] & (byte)0x0f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
                // Adjust String array index for plan 15
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
                cnsPlane = (cnsPlane == 15)? 8 : cnsPlane;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                if (cnsPlane < 15) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
                     state = G3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
                    badInputLength = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
                    throw new MalformedInputException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            case G3:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
                if ( (input[byteOff] & MSB) != 0) {     // 1st byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
                    firstByte = input[byteOff];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
                    state = G4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                } else {                                // Error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
                    state = G0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
                    badInputLength = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
                    throw new MalformedInputException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            case G4:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                if ( (input[byteOff] & MSB) != 0) {     // 2nd byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
                        outputChar = convToUnicode(firstByte,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
                                                   input[byteOff],
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
                                                   cnsChars[cnsPlane - 2]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
                } else {                                // Error
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                    badInputLength = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                    throw new MalformedInputException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
                firstByte = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                state = G0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            byteOff++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
            if (outputChar != (char) 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                if (outputChar == REPLACE_CHAR) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
                    if (subMode)                // substitution enabled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
                        outputChar = subChars[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
                    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
                        badInputLength = inputSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
                        throw new UnknownCharacterException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
                output[charOff++] = outputChar;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
                outputChar = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        return charOff - outOff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * Return the character set ID
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    public String getCharacterEncoding() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        return "EUC_TW";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    protected char convToUnicode(byte byte1, byte byte2, String table)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        int index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        if ((byte1 & 0xff) < 0xa1 || (byte2 & 0xff) < 0xa1 ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
            (byte1 & 0xff) > 0xfe || (byte2 & 0xff) > 0xfe)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            return REPLACE_CHAR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        index = (((byte1 & 0xff) - 0xa1) * 94)  + (byte2 & 0xff) - 0xa1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        if (index < 0 || index >= table.length())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            return REPLACE_CHAR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        // Planes 3 and above containing zero value lead byte
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        // to accommodate surrogates for mappings which decode to a surrogate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        // pair
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        if (this.cnsPlane >= 3)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
           index = (index * 2) + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        return table.charAt(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
}