631 lines · 24.5 KB · Java
RawDownload
/* * Copyright (c) 2002, 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.ByteBuffer;import java.nio.CharBuffer;import java.nio.charset.Charset;import java.nio.charset.CharsetDecoder;import java.nio.charset.CharsetEncoder;import java.nio.charset.CoderResult;import sun.nio.cs.Surrogate; abstract class ISO2022    extends Charset{     private static final byte ISO_ESC = 0x1b;    private static final byte ISO_SI = 0x0f;    private static final byte ISO_SO = 0x0e;    private static final byte ISO_SS2_7 = 0x4e;    private static final byte ISO_SS3_7 = 0x4f;    private static final byte MSB = (byte)0x80;    private static final char REPLACE_CHAR = '\uFFFD';    private static final byte minDesignatorLength = 3;     public ISO2022(String csname, String[] aliases) {        super(csname, aliases);    }     public CharsetDecoder newDecoder() {        return new Decoder(this);    }     public CharsetEncoder newEncoder() {        return new Encoder(this);    }     protected static class Decoder extends CharsetDecoder {         // Value to be filled by subclass        protected byte SODesig[][];        protected byte SS2Desig[][] = null;        protected byte SS3Desig[][] = null;         protected CharsetDecoder SODecoder[];        protected CharsetDecoder SS2Decoder[] = null;        protected CharsetDecoder SS3Decoder[] = null;         private static final byte SOFlag = 0;        private static final byte SS2Flag = 1;        private static final byte SS3Flag = 2;         private int curSODes, curSS2Des, curSS3Des;        private boolean shiftout;        private CharsetDecoder tmpDecoder[];         protected Decoder(Charset cs) {            super(cs, 1.0f, 1.0f);        }         protected void implReset() {            curSODes = 0;            curSS2Des = 0;            curSS3Des = 0;            shiftout = false;        }         private char decode(byte byte1, byte byte2, byte shiftFlag)        {            byte1 |= MSB;            byte2 |= MSB;             byte[] tmpByte = { byte1,byte2 };            char[] tmpChar = new char[1];            int     i = 0,                    tmpIndex = 0;             switch(shiftFlag) {            case SOFlag:                tmpIndex = curSODes;                tmpDecoder = SODecoder;                break;            case SS2Flag:                tmpIndex = curSS2Des;                tmpDecoder = SS2Decoder;                break;            case SS3Flag:                tmpIndex = curSS3Des;                tmpDecoder = SS3Decoder;                break;            }             if (tmpDecoder != null) {                for(i = 0; i < tmpDecoder.length; i++) {                    if(tmpIndex == i) {                        try {                            ByteBuffer bb = ByteBuffer.wrap(tmpByte,0,2);                            CharBuffer cc = CharBuffer.wrap(tmpChar,0,1);                            tmpDecoder[i].decode(bb, cc, true);                            cc.flip();                            return cc.get();                        } catch (Exception e) {}                    }                }            }            return REPLACE_CHAR;        }         private int findDesig(byte[] in, int sp, int sl, byte[][] desigs) {            if (desigs == null) return -1;            int i = 0;            while (i < desigs.length) {                if (desigs[i] != null && sl - sp >= desigs[i].length) {                    int j = 0;                    while (j < desigs[i].length && in[sp+j] == desigs[i][j]) { j++; }                    if (j == desigs[i].length)                        return i;                }                i++;            }            return -1;        }         private int findDesigBuf(ByteBuffer in, byte[][] desigs) {            if (desigs == null) return -1;            int i = 0;            while (i < desigs.length) {                if (desigs[i] != null && in.remaining() >= desigs[i].length) {                    int j = 0;                    in.mark();                    while (j < desigs[i].length && in.get() == desigs[i][j]) { j++; }                    if (j == desigs[i].length)                        return i;                    in.reset();                }                i++;            }            return -1;        }         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);             int b1 = 0, b2 = 0, b3 = 0;             try {                while (sp < sl) {                    b1 = sa[sp] & 0xff;                    int inputSize = 1;                    switch (b1) {                        case ISO_SO:                            shiftout = true;                            inputSize = 1;                            break;                        case ISO_SI:                            shiftout = false;                            inputSize = 1;                            break;                        case ISO_ESC:                            if (sl - sp - 1 < minDesignatorLength)                                return CoderResult.UNDERFLOW;                             int desig = findDesig(sa, sp + 1, sl, SODesig);                            if (desig != -1) {                                curSODes = desig;                                inputSize = SODesig[desig].length + 1;                                break;                            }                            desig = findDesig(sa, sp + 1, sl, SS2Desig);                            if (desig != -1) {                                curSS2Des = desig;                                inputSize = SS2Desig[desig].length + 1;                                break;                            }                            desig = findDesig(sa, sp + 1, sl, SS3Desig);                            if (desig != -1) {                                curSS3Des = desig;                                inputSize = SS3Desig[desig].length + 1;                                break;                            }                            if (sl - sp < 2)                                return CoderResult.UNDERFLOW;                            b1 = sa[sp + 1];                            switch(b1) {                            case ISO_SS2_7:                                if (sl - sp < 4)                                    return CoderResult.UNDERFLOW;                                b2 = sa[sp +2];                                b3 = sa[sp +3];                                if (dl - dp <1)                                    return CoderResult.OVERFLOW;                                da[dp] = decode((byte)b2,                                                (byte)b3,                                                SS2Flag);                                dp++;                                inputSize = 4;                                break;                            case ISO_SS3_7:                                if (sl - sp < 4)                                    return CoderResult.UNDERFLOW;                                b2 = sa[sp + 2];                                b3 = sa[sp + 3];                                if (dl - dp <1)                                    return CoderResult.OVERFLOW;                                da[dp] = decode((byte)b2,                                                (byte)b3,                                                SS3Flag);                                dp++;                                inputSize = 4;                                break;                            default:                                return CoderResult.malformedForLength(2);                            }                            break;                        default:                            if (dl - dp < 1)                                return CoderResult.OVERFLOW;                            if (!shiftout) {                                da[dp++]=(char)(sa[sp] & 0xff);                            } else {                                if (dl - dp < 1)                                    return CoderResult.OVERFLOW;                                if (sl - sp < 2)                                    return CoderResult.UNDERFLOW;                                b2 = sa[sp+1] & 0xff;                                da[dp++] = decode((byte)b1,                                                  (byte)b2,                                                   SOFlag);                                inputSize = 2;                            }                            break;                    }                    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();            int b1 = 0, b2 = 0, b3 = 0;             try {                while (src.hasRemaining()) {                    b1 = src.get();                    int inputSize = 1;                    switch (b1) {                        case ISO_SO:                            shiftout = true;                            break;                        case ISO_SI:                            shiftout = false;                            break;                        case ISO_ESC:                            if (src.remaining() < minDesignatorLength)                                return CoderResult.UNDERFLOW;                             int desig = findDesigBuf(src, SODesig);                            if (desig != -1) {                                curSODes = desig;                                inputSize = SODesig[desig].length + 1;                                break;                            }                            desig = findDesigBuf(src, SS2Desig);                            if (desig != -1) {                                curSS2Des = desig;                                inputSize = SS2Desig[desig].length + 1;                                break;                            }                            desig = findDesigBuf(src, SS3Desig);                            if (desig != -1) {                                curSS3Des = desig;                                inputSize = SS3Desig[desig].length + 1;                                break;                            }                             if (src.remaining() < 1)                                return CoderResult.UNDERFLOW;                            b1 = src.get();                            switch(b1) {                                case ISO_SS2_7:                                    if (src.remaining() < 2)                                        return CoderResult.UNDERFLOW;                                    b2 = src.get();                                    b3 = src.get();                                    if (dst.remaining() < 1)                                        return CoderResult.OVERFLOW;                                    dst.put(decode((byte)b2,                                                   (byte)b3,                                                   SS2Flag));                                    inputSize = 4;                                    break;                                case ISO_SS3_7:                                    if (src.remaining() < 2)                                        return CoderResult.UNDERFLOW;                                    b2 = src.get();                                    b3 = src.get();                                    if (dst.remaining() < 1)                                        return CoderResult.OVERFLOW;                                    dst.put(decode((byte)b2,                                                   (byte)b3,                                                   SS3Flag));                                    inputSize = 4;                                    break;                                default:                                    return CoderResult.malformedForLength(2);                            }                            break;                        default:                            if (dst.remaining() < 1)                                return CoderResult.OVERFLOW;                            if (!shiftout) {                                dst.put((char)(b1 & 0xff));                            } else {                                if (dst.remaining() < 1)                                    return CoderResult.OVERFLOW;                                if (src.remaining() < 1)                                    return CoderResult.UNDERFLOW;                                b2 = src.get() & 0xff;                                dst.put(decode((byte)b1,                                                      (byte)b2,                                                        SOFlag));                                inputSize = 2;                            }                            break;                    }                    mark += inputSize;                }                return CoderResult.UNDERFLOW;            } catch (Exception e) { e.printStackTrace(); return CoderResult.OVERFLOW; }            finally {                src.position(mark);            }        }         protected CoderResult decodeLoop(ByteBuffer src,                                         CharBuffer dst)        {            if (src.hasArray() && dst.hasArray())                return decodeArrayLoop(src, dst);            else                return decodeBufferLoop(src, dst);        }    }     protected static class Encoder extends CharsetEncoder {        private final Surrogate.Parser sgp = new Surrogate.Parser();        public static final byte SS2 = (byte)0x8e;        public static final byte PLANE2 = (byte)0xA2;        public static final byte PLANE3 = (byte)0xA3;        private final byte MSB = (byte)0x80;         protected final byte maximumDesignatorLength = 4;         protected String SODesig,                         SS2Desig = null,                         SS3Desig = null;         protected CharsetEncoder ISOEncoder;         private boolean shiftout = false;        private boolean SODesDefined = false;        private boolean SS2DesDefined = false;        private boolean SS3DesDefined = false;         private boolean newshiftout = false;        private boolean newSODesDefined = false;        private boolean newSS2DesDefined = false;        private boolean newSS3DesDefined = false;         protected Encoder(Charset cs) {            super(cs, 4.0f, 8.0f);        }         public boolean canEncode(char c) {            return (ISOEncoder.canEncode(c));        }         protected void implReset() {            shiftout = false;            SODesDefined = false;            SS2DesDefined = false;            SS3DesDefined = false;        }         private int unicodeToNative(char unicode, byte ebyte[])        {            int index = 0;            byte        tmpByte[];            char        convChar[] = {unicode};            byte        convByte[] = new byte[4];            int         converted;             try{                CharBuffer cc = CharBuffer.wrap(convChar);                ByteBuffer bb = ByteBuffer.allocate(4);                ISOEncoder.encode(cc, bb, true);                bb.flip();                converted = bb.remaining();                bb.get(convByte,0,converted);            } catch(Exception e) {                return -1;            }             if (converted == 2) {                if (!SODesDefined) {                    newSODesDefined = true;                    ebyte[0] = ISO_ESC;                    tmpByte = SODesig.getBytes();                    System.arraycopy(tmpByte,0,ebyte,1,tmpByte.length);                    index = tmpByte.length+1;                }                if (!shiftout) {                    newshiftout = true;                    ebyte[index++] = ISO_SO;                }                ebyte[index++] = (byte)(convByte[0] & 0x7f);                ebyte[index++] = (byte)(convByte[1] & 0x7f);            } else {                if(convByte[0] == SS2) {                    if (convByte[1] == PLANE2) {                        if (!SS2DesDefined) {                            newSS2DesDefined = true;                            ebyte[0] = ISO_ESC;                            tmpByte = SS2Desig.getBytes();                            System.arraycopy(tmpByte, 0, ebyte, 1, tmpByte.length);                            index = tmpByte.length+1;                        }                        ebyte[index++] = ISO_ESC;                        ebyte[index++] = ISO_SS2_7;                        ebyte[index++] = (byte)(convByte[2] & 0x7f);                        ebyte[index++] = (byte)(convByte[3] & 0x7f);                    } else if (convByte[1] == PLANE3) {                        if(!SS3DesDefined){                            newSS3DesDefined = true;                            ebyte[0] = ISO_ESC;                            tmpByte = SS3Desig.getBytes();                            System.arraycopy(tmpByte, 0, ebyte, 1, tmpByte.length);                            index = tmpByte.length+1;                        }                        ebyte[index++] = ISO_ESC;                        ebyte[index++] = ISO_SS3_7;                        ebyte[index++] = (byte)(convByte[2] & 0x7f);                        ebyte[index++] = (byte)(convByte[3] & 0x7f);                    }                }            }            return index;        }         private CoderResult encodeArrayLoop(CharBuffer src,                                            ByteBuffer dst)        {            char[] sa = src.array();            int sp = src.arrayOffset() + src.position();            int sl = src.arrayOffset() + src.limit();            assert (sp <= sl);

Lines 1–500 of 631.