Path: blob/master/src/java.base/share/classes/java/nio/charset/CoderResult.java
41159 views
/*1* Copyright (c) 2001, 2018, 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 java.nio.charset;2627import java.nio.BufferOverflowException;28import java.nio.BufferUnderflowException;29import java.util.concurrent.ConcurrentHashMap;30import java.util.Map;3132/**33* A description of the result state of a coder.34*35* <p> A charset coder, that is, either a decoder or an encoder, consumes bytes36* (or characters) from an input buffer, translates them, and writes the37* resulting characters (or bytes) to an output buffer. A coding process38* terminates for one of four categories of reasons, which are described by39* instances of this class:40*41* <ul>42*43* <li><p> <i>Underflow</i> is reported when there is no more input to be44* processed, or there is insufficient input and additional input is45* required. This condition is represented by the unique result object46* {@link #UNDERFLOW}, whose {@link #isUnderflow() isUnderflow} method47* returns {@code true}. </p></li>48*49* <li><p> <i>Overflow</i> is reported when there is insufficient room50* remaining in the output buffer. This condition is represented by the51* unique result object {@link #OVERFLOW}, whose {@link #isOverflow()52* isOverflow} method returns {@code true}. </p></li>53*54* <li><p> A <i>malformed-input error</i> is reported when a sequence of55* input units is not well-formed. Such errors are described by instances of56* this class whose {@link #isMalformed() isMalformed} method returns57* {@code true} and whose {@link #length() length} method returns the length58* of the malformed sequence. There is one unique instance of this class for59* all malformed-input errors of a given length. </p></li>60*61* <li><p> An <i>unmappable-character error</i> is reported when a sequence62* of input units denotes a character that cannot be represented in the63* output charset. Such errors are described by instances of this class64* whose {@link #isUnmappable() isUnmappable} method returns {@code true} and65* whose {@link #length() length} method returns the length of the input66* sequence denoting the unmappable character. There is one unique instance67* of this class for all unmappable-character errors of a given length.68* </p></li>69*70* </ul>71*72* <p> For convenience, the {@link #isError() isError} method returns {@code true}73* for result objects that describe malformed-input and unmappable-character74* errors but {@code false} for those that describe underflow or overflow75* conditions. </p>76*77*78* @author Mark Reinhold79* @author JSR-51 Expert Group80* @since 1.481*/8283public class CoderResult {8485private static final int CR_UNDERFLOW = 0;86private static final int CR_OVERFLOW = 1;87private static final int CR_ERROR_MIN = 2;88private static final int CR_MALFORMED = 2;89private static final int CR_UNMAPPABLE = 3;9091private static final String[] names92= { "UNDERFLOW", "OVERFLOW", "MALFORMED", "UNMAPPABLE" };9394private final int type;95private final int length;9697private CoderResult(int type, int length) {98this.type = type;99this.length = length;100}101102/**103* Returns a string describing this coder result.104*105* @return A descriptive string106*/107public String toString() {108String nm = names[type];109return isError() ? nm + "[" + length + "]" : nm;110}111112/**113* Tells whether or not this object describes an underflow condition.114*115* @return {@code true} if, and only if, this object denotes underflow116*/117public boolean isUnderflow() {118return (type == CR_UNDERFLOW);119}120121/**122* Tells whether or not this object describes an overflow condition.123*124* @return {@code true} if, and only if, this object denotes overflow125*/126public boolean isOverflow() {127return (type == CR_OVERFLOW);128}129130/**131* Tells whether or not this object describes an error condition.132*133* @return {@code true} if, and only if, this object denotes either a134* malformed-input error or an unmappable-character error135*/136public boolean isError() {137return (type >= CR_ERROR_MIN);138}139140/**141* Tells whether or not this object describes a malformed-input error.142*143* @return {@code true} if, and only if, this object denotes a144* malformed-input error145*/146public boolean isMalformed() {147return (type == CR_MALFORMED);148}149150/**151* Tells whether or not this object describes an unmappable-character152* error.153*154* @return {@code true} if, and only if, this object denotes an155* unmappable-character error156*/157public boolean isUnmappable() {158return (type == CR_UNMAPPABLE);159}160161/**162* Returns the length of the erroneous input described by this163* object <i>(optional operation)</i>.164*165* @return The length of the erroneous input, a positive integer166*167* @throws UnsupportedOperationException168* If this object does not describe an error condition, that is,169* if the {@link #isError() isError} does not return {@code true}170*/171public int length() {172if (!isError())173throw new UnsupportedOperationException();174return length;175}176177/**178* Result object indicating underflow, meaning that either the input buffer179* has been completely consumed or, if the input buffer is not yet empty,180* that additional input is required.181*/182public static final CoderResult UNDERFLOW183= new CoderResult(CR_UNDERFLOW, 0);184185/**186* Result object indicating overflow, meaning that there is insufficient187* room in the output buffer.188*/189public static final CoderResult OVERFLOW190= new CoderResult(CR_OVERFLOW, 0);191192private static final class Cache {193static final Cache INSTANCE = new Cache();194private Cache() {}195196final Map<Integer, CoderResult> unmappable = new ConcurrentHashMap<>();197final Map<Integer, CoderResult> malformed = new ConcurrentHashMap<>();198}199200private static final CoderResult[] malformed4 = new CoderResult[] {201new CoderResult(CR_MALFORMED, 1),202new CoderResult(CR_MALFORMED, 2),203new CoderResult(CR_MALFORMED, 3),204new CoderResult(CR_MALFORMED, 4),205};206207/**208* Static factory method that returns the unique object describing a209* malformed-input error of the given length.210*211* @param length212* The given length213*214* @return The requested coder-result object215*/216public static CoderResult malformedForLength(int length) {217if (length <= 0)218throw new IllegalArgumentException("Non-positive length");219if (length <= 4)220return malformed4[length - 1];221return Cache.INSTANCE.malformed.computeIfAbsent(length,222n -> new CoderResult(CR_MALFORMED, n));223}224225private static final CoderResult[] unmappable4 = new CoderResult[] {226new CoderResult(CR_UNMAPPABLE, 1),227new CoderResult(CR_UNMAPPABLE, 2),228new CoderResult(CR_UNMAPPABLE, 3),229new CoderResult(CR_UNMAPPABLE, 4),230};231232/**233* Static factory method that returns the unique result object describing234* an unmappable-character error of the given length.235*236* @param length237* The given length238*239* @return The requested coder-result object240*/241public static CoderResult unmappableForLength(int length) {242if (length <= 0)243throw new IllegalArgumentException("Non-positive length");244if (length <= 4)245return unmappable4[length - 1];246return Cache.INSTANCE.unmappable.computeIfAbsent(length,247n -> new CoderResult(CR_UNMAPPABLE, n));248}249250/**251* Throws an exception appropriate to the result described by this object.252*253* @throws BufferUnderflowException254* If this object is {@link #UNDERFLOW}255*256* @throws BufferOverflowException257* If this object is {@link #OVERFLOW}258*259* @throws MalformedInputException260* If this object represents a malformed-input error; the261* exception's length value will be that of this object262*263* @throws UnmappableCharacterException264* If this object represents an unmappable-character error; the265* exceptions length value will be that of this object266*/267public void throwException()268throws CharacterCodingException269{270switch (type) {271case CR_UNDERFLOW: throw new BufferUnderflowException();272case CR_OVERFLOW: throw new BufferOverflowException();273case CR_MALFORMED: throw new MalformedInputException(length);274case CR_UNMAPPABLE: throw new UnmappableCharacterException(length);275default:276assert false;277}278}279280}281282283