jdk/src/java.base/share/classes/java/nio/charset/CoderResult.java
changeset 25859 3317bb8137f4
parent 25522 10d789df41bb
child 29986 97167d851fc4
equal deleted inserted replaced
25858:836adbf7a2cd 25859:3317bb8137f4
       
     1 /*
       
     2  * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package java.nio.charset;
       
    27 
       
    28 import java.lang.ref.WeakReference;
       
    29 import java.nio.*;
       
    30 import java.util.Map;
       
    31 import java.util.HashMap;
       
    32 
       
    33 
       
    34 /**
       
    35  * A description of the result state of a coder.
       
    36  *
       
    37  * <p> A charset coder, that is, either a decoder or an encoder, consumes bytes
       
    38  * (or characters) from an input buffer, translates them, and writes the
       
    39  * resulting characters (or bytes) to an output buffer.  A coding process
       
    40  * terminates for one of four categories of reasons, which are described by
       
    41  * instances of this class:
       
    42  *
       
    43  * <ul>
       
    44  *
       
    45  *   <li><p> <i>Underflow</i> is reported when there is no more input to be
       
    46  *   processed, or there is insufficient input and additional input is
       
    47  *   required.  This condition is represented by the unique result object
       
    48  *   {@link #UNDERFLOW}, whose {@link #isUnderflow() isUnderflow} method
       
    49  *   returns <tt>true</tt>.  </p></li>
       
    50  *
       
    51  *   <li><p> <i>Overflow</i> is reported when there is insufficient room
       
    52  *   remaining in the output buffer.  This condition is represented by the
       
    53  *   unique result object {@link #OVERFLOW}, whose {@link #isOverflow()
       
    54  *   isOverflow} method returns <tt>true</tt>.  </p></li>
       
    55  *
       
    56  *   <li><p> A <i>malformed-input error</i> is reported when a sequence of
       
    57  *   input units is not well-formed.  Such errors are described by instances of
       
    58  *   this class whose {@link #isMalformed() isMalformed} method returns
       
    59  *   <tt>true</tt> and whose {@link #length() length} method returns the length
       
    60  *   of the malformed sequence.  There is one unique instance of this class for
       
    61  *   all malformed-input errors of a given length.  </p></li>
       
    62  *
       
    63  *   <li><p> An <i>unmappable-character error</i> is reported when a sequence
       
    64  *   of input units denotes a character that cannot be represented in the
       
    65  *   output charset.  Such errors are described by instances of this class
       
    66  *   whose {@link #isUnmappable() isUnmappable} method returns <tt>true</tt> and
       
    67  *   whose {@link #length() length} method returns the length of the input
       
    68  *   sequence denoting the unmappable character.  There is one unique instance
       
    69  *   of this class for all unmappable-character errors of a given length.
       
    70  *   </p></li>
       
    71  *
       
    72  * </ul>
       
    73  *
       
    74  * <p> For convenience, the {@link #isError() isError} method returns <tt>true</tt>
       
    75  * for result objects that describe malformed-input and unmappable-character
       
    76  * errors but <tt>false</tt> for those that describe underflow or overflow
       
    77  * conditions.  </p>
       
    78  *
       
    79  *
       
    80  * @author Mark Reinhold
       
    81  * @author JSR-51 Expert Group
       
    82  * @since 1.4
       
    83  */
       
    84 
       
    85 public class CoderResult {
       
    86 
       
    87     private static final int CR_UNDERFLOW  = 0;
       
    88     private static final int CR_OVERFLOW   = 1;
       
    89     private static final int CR_ERROR_MIN  = 2;
       
    90     private static final int CR_MALFORMED  = 2;
       
    91     private static final int CR_UNMAPPABLE = 3;
       
    92 
       
    93     private static final String[] names
       
    94         = { "UNDERFLOW", "OVERFLOW", "MALFORMED", "UNMAPPABLE" };
       
    95 
       
    96     private final int type;
       
    97     private final int length;
       
    98 
       
    99     private CoderResult(int type, int length) {
       
   100         this.type = type;
       
   101         this.length = length;
       
   102     }
       
   103 
       
   104     /**
       
   105      * Returns a string describing this coder result.
       
   106      *
       
   107      * @return  A descriptive string
       
   108      */
       
   109     public String toString() {
       
   110         String nm = names[type];
       
   111         return isError() ? nm + "[" + length + "]" : nm;
       
   112     }
       
   113 
       
   114     /**
       
   115      * Tells whether or not this object describes an underflow condition.
       
   116      *
       
   117      * @return  <tt>true</tt> if, and only if, this object denotes underflow
       
   118      */
       
   119     public boolean isUnderflow() {
       
   120         return (type == CR_UNDERFLOW);
       
   121     }
       
   122 
       
   123     /**
       
   124      * Tells whether or not this object describes an overflow condition.
       
   125      *
       
   126      * @return  <tt>true</tt> if, and only if, this object denotes overflow
       
   127      */
       
   128     public boolean isOverflow() {
       
   129         return (type == CR_OVERFLOW);
       
   130     }
       
   131 
       
   132     /**
       
   133      * Tells whether or not this object describes an error condition.
       
   134      *
       
   135      * @return  <tt>true</tt> if, and only if, this object denotes either a
       
   136      *          malformed-input error or an unmappable-character error
       
   137      */
       
   138     public boolean isError() {
       
   139         return (type >= CR_ERROR_MIN);
       
   140     }
       
   141 
       
   142     /**
       
   143      * Tells whether or not this object describes a malformed-input error.
       
   144      *
       
   145      * @return  <tt>true</tt> if, and only if, this object denotes a
       
   146      *          malformed-input error
       
   147      */
       
   148     public boolean isMalformed() {
       
   149         return (type == CR_MALFORMED);
       
   150     }
       
   151 
       
   152     /**
       
   153      * Tells whether or not this object describes an unmappable-character
       
   154      * error.
       
   155      *
       
   156      * @return  <tt>true</tt> if, and only if, this object denotes an
       
   157      *          unmappable-character error
       
   158      */
       
   159     public boolean isUnmappable() {
       
   160         return (type == CR_UNMAPPABLE);
       
   161     }
       
   162 
       
   163     /**
       
   164      * Returns the length of the erroneous input described by this
       
   165      * object&nbsp;&nbsp;<i>(optional operation)</i>.
       
   166      *
       
   167      * @return  The length of the erroneous input, a positive integer
       
   168      *
       
   169      * @throws  UnsupportedOperationException
       
   170      *          If this object does not describe an error condition, that is,
       
   171      *          if the {@link #isError() isError} does not return <tt>true</tt>
       
   172      */
       
   173     public int length() {
       
   174         if (!isError())
       
   175             throw new UnsupportedOperationException();
       
   176         return length;
       
   177     }
       
   178 
       
   179     /**
       
   180      * Result object indicating underflow, meaning that either the input buffer
       
   181      * has been completely consumed or, if the input buffer is not yet empty,
       
   182      * that additional input is required.
       
   183      */
       
   184     public static final CoderResult UNDERFLOW
       
   185         = new CoderResult(CR_UNDERFLOW, 0);
       
   186 
       
   187     /**
       
   188      * Result object indicating overflow, meaning that there is insufficient
       
   189      * room in the output buffer.
       
   190      */
       
   191     public static final CoderResult OVERFLOW
       
   192         = new CoderResult(CR_OVERFLOW, 0);
       
   193 
       
   194     private static abstract class Cache {
       
   195 
       
   196         private Map<Integer,WeakReference<CoderResult>> cache = null;
       
   197 
       
   198         protected abstract CoderResult create(int len);
       
   199 
       
   200         private synchronized CoderResult get(int len) {
       
   201             if (len <= 0)
       
   202                 throw new IllegalArgumentException("Non-positive length");
       
   203             Integer k = len;
       
   204             WeakReference<CoderResult> w;
       
   205             CoderResult e = null;
       
   206             if (cache == null) {
       
   207                 cache = new HashMap<Integer,WeakReference<CoderResult>>();
       
   208             } else if ((w = cache.get(k)) != null) {
       
   209                 e = w.get();
       
   210             }
       
   211             if (e == null) {
       
   212                 e = create(len);
       
   213                 cache.put(k, new WeakReference<CoderResult>(e));
       
   214             }
       
   215             return e;
       
   216         }
       
   217 
       
   218     }
       
   219 
       
   220     private static Cache malformedCache
       
   221         = new Cache() {
       
   222                 public CoderResult create(int len) {
       
   223                     return new CoderResult(CR_MALFORMED, len);
       
   224                 }};
       
   225 
       
   226     /**
       
   227      * Static factory method that returns the unique object describing a
       
   228      * malformed-input error of the given length.
       
   229      *
       
   230      * @param   length
       
   231      *          The given length
       
   232      *
       
   233      * @return  The requested coder-result object
       
   234      */
       
   235     public static CoderResult malformedForLength(int length) {
       
   236         return malformedCache.get(length);
       
   237     }
       
   238 
       
   239     private static Cache unmappableCache
       
   240         = new Cache() {
       
   241                 public CoderResult create(int len) {
       
   242                     return new CoderResult(CR_UNMAPPABLE, len);
       
   243                 }};
       
   244 
       
   245     /**
       
   246      * Static factory method that returns the unique result object describing
       
   247      * an unmappable-character error of the given length.
       
   248      *
       
   249      * @param   length
       
   250      *          The given length
       
   251      *
       
   252      * @return  The requested coder-result object
       
   253      */
       
   254     public static CoderResult unmappableForLength(int length) {
       
   255         return unmappableCache.get(length);
       
   256     }
       
   257 
       
   258     /**
       
   259      * Throws an exception appropriate to the result described by this object.
       
   260      *
       
   261      * @throws  BufferUnderflowException
       
   262      *          If this object is {@link #UNDERFLOW}
       
   263      *
       
   264      * @throws  BufferOverflowException
       
   265      *          If this object is {@link #OVERFLOW}
       
   266      *
       
   267      * @throws  MalformedInputException
       
   268      *          If this object represents a malformed-input error; the
       
   269      *          exception's length value will be that of this object
       
   270      *
       
   271      * @throws  UnmappableCharacterException
       
   272      *          If this object represents an unmappable-character error; the
       
   273      *          exceptions length value will be that of this object
       
   274      */
       
   275     public void throwException()
       
   276         throws CharacterCodingException
       
   277     {
       
   278         switch (type) {
       
   279         case CR_UNDERFLOW:   throw new BufferUnderflowException();
       
   280         case CR_OVERFLOW:    throw new BufferOverflowException();
       
   281         case CR_MALFORMED:   throw new MalformedInputException(length);
       
   282         case CR_UNMAPPABLE:  throw new UnmappableCharacterException(length);
       
   283         default:
       
   284             assert false;
       
   285         }
       
   286     }
       
   287 
       
   288 }