244 lines · 8.0 KB · Java
RawDownload
/* * Copyright (c) 2000, 2004, 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; 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 java.util.Arrays; class ISO_8859_1    extends Charset    implements HistoricallyNamedCharset{     public ISO_8859_1() {        super("ISO-8859-1", StandardCharsets.aliases_ISO_8859_1);    }     public String historicalName() {        return "ISO8859_1";    }     public boolean contains(Charset cs) {        return ((cs instanceof US_ASCII)                || (cs instanceof ISO_8859_1));    }     public CharsetDecoder newDecoder() {        return new Decoder(this);    }     public CharsetEncoder newEncoder() {        return new Encoder(this);    }     private static class Decoder extends CharsetDecoder                                 implements ArrayDecoder {        private 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) {                    byte b = sa[sp];                    if (dp >= dl)                        return CoderResult.OVERFLOW;                    da[dp++] = (char)(b & 0xff);                    sp++;                }                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()) {                    byte b = src.get();                    if (!dst.hasRemaining())                        return CoderResult.OVERFLOW;                    dst.put((char)(b & 0xff));                    mark++;                }                return CoderResult.UNDERFLOW;            } 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);        }         public int decode(byte[] src, int sp, int len, char[] dst) {            if (len > dst.length)                len = dst.length;            int dp = 0;            while (dp < len)                dst[dp++] = (char)(src[sp++] & 0xff);            return dp;        }    }     private static class Encoder extends CharsetEncoder                                 implements ArrayEncoder {        private Encoder(Charset cs) {            super(cs, 1.0f, 1.0f);        }         public boolean canEncode(char c) {            return c <= '\u00FF';        }         public boolean isLegalReplacement(byte[] repl) {            return true;  // we accept any byte value        }         private final Surrogate.Parser sgp = new Surrogate.Parser();         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);            sp = (sp <= sl ? sp : sl);            byte[] 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) {                    char c = sa[sp];                    if (c <= '\u00FF') {                        if (dp >= dl)                            return CoderResult.OVERFLOW;                        da[dp++] = (byte)c;                        sp++;                        continue;                    }                    if (sgp.parse(c, sa, sp, sl) < 0)                        return sgp.error();                    return sgp.unmappableResult();                }                return CoderResult.UNDERFLOW;            } finally {                src.position(sp - src.arrayOffset());                dst.position(dp - dst.arrayOffset());            }        }         private CoderResult encodeBufferLoop(CharBuffer src,                                             ByteBuffer dst)        {            int mark = src.position();            try {                while (src.hasRemaining()) {                    char c = src.get();                    if (c <= '\u00FF') {                        if (!dst.hasRemaining())                            return CoderResult.OVERFLOW;                        dst.put((byte)c);                        mark++;                        continue;                    }                    if (sgp.parse(c, src) < 0)                        return sgp.error();                    return sgp.unmappableResult();                }                return CoderResult.UNDERFLOW;            } finally {                src.position(mark);            }        }         protected CoderResult encodeLoop(CharBuffer src,                                         ByteBuffer dst)        {            if (src.hasArray() && dst.hasArray())                return encodeArrayLoop(src, dst);            else                return encodeBufferLoop(src, dst);        }         private byte repl = (byte)'?';        protected void implReplaceWith(byte[] newReplacement) {            repl = newReplacement[0];        }         public int encode(char[] src, int sp, int len, byte[] dst) {            int dp = 0;            int sl = sp + Math.min(len, dst.length);            while (sp < sl) {                char c = src[sp++];                if (c <= '\u00FF') {                    dst[dp++] = (byte)c;                    continue;                }                if (Character.isHighSurrogate(c) && sp < sl &&                    Character.isLowSurrogate(src[sp])) {                    if (len > dst.length) {                        sl++;                        len--;                    }                    sp++;                }                dst[dp++] = repl;            }            return dp;        }    }}