Path: blob/master/src/java.base/share/classes/sun/nio/cs/UnicodeDecoder.java
41159 views
/*1* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.cs;2627import java.nio.ByteBuffer;28import java.nio.CharBuffer;29import java.nio.charset.Charset;30import java.nio.charset.CharsetDecoder;31import java.nio.charset.CoderResult;32import java.nio.charset.CharacterCodingException;33import java.nio.charset.MalformedInputException;343536abstract class UnicodeDecoder extends CharsetDecoder {3738protected static final char BYTE_ORDER_MARK = (char) 0xfeff;39protected static final char REVERSED_MARK = (char) 0xfffe;4041protected static final int NONE = 0;42protected static final int BIG = 1;43protected static final int LITTLE = 2;4445private final int expectedByteOrder;46private int currentByteOrder;47private int defaultByteOrder = BIG;4849public UnicodeDecoder(Charset cs, int bo) {50super(cs, 0.5f, 1.0f);51expectedByteOrder = currentByteOrder = bo;52}5354public UnicodeDecoder(Charset cs, int bo, int defaultBO) {55this(cs, bo);56defaultByteOrder = defaultBO;57}5859private char decode(int b1, int b2) {60if (currentByteOrder == BIG)61return (char)((b1 << 8) | b2);62else63return (char)((b2 << 8) | b1);64}6566protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) {67int mark = src.position();6869try {70while (src.remaining() > 1) {71int b1 = src.get() & 0xff;72int b2 = src.get() & 0xff;7374// Byte Order Mark interpretation75if (currentByteOrder == NONE) {76char c = (char)((b1 << 8) | b2);77if (c == BYTE_ORDER_MARK) {78currentByteOrder = BIG;79mark += 2;80continue;81} else if (c == REVERSED_MARK) {82currentByteOrder = LITTLE;83mark += 2;84continue;85} else {86currentByteOrder = defaultByteOrder;87// FALL THROUGH to process b1, b2 normally88}89}9091char c = decode(b1, b2);9293// Surrogates94if (Character.isSurrogate(c)) {95if (Character.isHighSurrogate(c)) {96if (src.remaining() < 2)97return CoderResult.UNDERFLOW;98char c2 = decode(src.get() & 0xff, src.get() & 0xff);99if (!Character.isLowSurrogate(c2))100return CoderResult.malformedForLength(4);101if (dst.remaining() < 2)102return CoderResult.OVERFLOW;103mark += 4;104dst.put(c);105dst.put(c2);106continue;107}108// Unpaired low surrogate109return CoderResult.malformedForLength(2);110}111112if (!dst.hasRemaining())113return CoderResult.OVERFLOW;114mark += 2;115dst.put(c);116117}118return CoderResult.UNDERFLOW;119120} finally {121src.position(mark);122}123}124125protected void implReset() {126currentByteOrder = expectedByteOrder;127}128129}130131132