| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
package java.nio.charset;  | 
 | 
 | 
 | 
import java.lang.ref.WeakReference;  | 
 | 
import java.nio.*;  | 
 | 
import java.util.Map;  | 
 | 
import java.util.HashMap;  | 
 | 
 | 
 | 
 | 
 | 
/**  | 
 | 
 * A description of the result state of a coder.  | 
 | 
 *  | 
 | 
 * <p> A charset coder, that is, either a decoder or an encoder, consumes bytes  | 
 | 
 * (or characters) from an input buffer, translates them, and writes the  | 
 | 
 * resulting characters (or bytes) to an output buffer.  A coding process  | 
 | 
 * terminates for one of four categories of reasons, which are described by  | 
 | 
 * instances of this class:  | 
 | 
 *  | 
 | 
 * <ul>  | 
 | 
 *  | 
 | 
 *   <li><p> <i>Underflow</i> is reported when there is no more input to be  | 
 | 
 *   processed, or there is insufficient input and additional input is  | 
 | 
 *   required.  This condition is represented by the unique result object  | 
 | 
 *   {@link #UNDERFLOW}, whose {@link #isUnderflow() isUnderflow} method | 
 | 
 *   returns <tt>true</tt>.  </p></li>  | 
 | 
 *  | 
 | 
 *   <li><p> <i>Overflow</i> is reported when there is insufficient room  | 
 | 
 *   remaining in the output buffer.  This condition is represented by the  | 
 | 
 *   unique result object {@link #OVERFLOW}, whose {@link #isOverflow() | 
 | 
 *   isOverflow} method returns <tt>true</tt>.  </p></li>  | 
 | 
 *  | 
 | 
 *   <li><p> A <i>malformed-input error</i> is reported when a sequence of  | 
 | 
 *   input units is not well-formed.  Such errors are described by instances of  | 
 | 
 *   this class whose {@link #isMalformed() isMalformed} method returns | 
 | 
 *   <tt>true</tt> and whose {@link #length() length} method returns the length | 
 | 
 *   of the malformed sequence.  There is one unique instance of this class for  | 
 | 
 *   all malformed-input errors of a given length.  </p></li>  | 
 | 
 *  | 
 | 
 *   <li><p> An <i>unmappable-character error</i> is reported when a sequence  | 
 | 
 *   of input units denotes a character that cannot be represented in the  | 
 | 
 *   output charset.  Such errors are described by instances of this class  | 
 | 
 *   whose {@link #isUnmappable() isUnmappable} method returns <tt>true</tt> and | 
 | 
 *   whose {@link #length() length} method returns the length of the input | 
 | 
 *   sequence denoting the unmappable character.  There is one unique instance  | 
 | 
 *   of this class for all unmappable-character errors of a given length.  | 
 | 
 *   </p></li>  | 
 | 
 *  | 
 | 
 * </ul>  | 
 | 
 *  | 
 | 
 * <p> For convenience, the {@link #isError() isError} method returns <tt>true</tt> | 
 | 
 * for result objects that describe malformed-input and unmappable-character  | 
 | 
 * errors but <tt>false</tt> for those that describe underflow or overflow  | 
 | 
 * conditions.  </p>  | 
 | 
 *  | 
 | 
 *  | 
 | 
 * @author Mark Reinhold  | 
 | 
 * @author JSR-51 Expert Group  | 
 | 
 * @since 1.4  | 
 | 
 */  | 
 | 
 | 
 | 
public class CoderResult { | 
 | 
 | 
 | 
    private static final int CR_UNDERFLOW  = 0;  | 
 | 
    private static final int CR_OVERFLOW   = 1;  | 
 | 
    private static final int CR_ERROR_MIN  = 2;  | 
 | 
    private static final int CR_MALFORMED  = 2;  | 
 | 
    private static final int CR_UNMAPPABLE = 3;  | 
 | 
 | 
 | 
    private static final String[] names  | 
 | 
        = { "UNDERFLOW", "OVERFLOW", "MALFORMED", "UNMAPPABLE" }; | 
 | 
 | 
 | 
    private final int type;  | 
 | 
    private final int length;  | 
 | 
 | 
 | 
    private CoderResult(int type, int length) { | 
 | 
        this.type = type;  | 
 | 
        this.length = length;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public String toString() { | 
 | 
        String nm = names[type];  | 
 | 
        return isError() ? nm + "[" + length + "]" : nm;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public boolean isUnderflow() { | 
 | 
        return (type == CR_UNDERFLOW);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public boolean isOverflow() { | 
 | 
        return (type == CR_OVERFLOW);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public boolean isError() { | 
 | 
        return (type >= CR_ERROR_MIN);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public boolean isMalformed() { | 
 | 
        return (type == CR_MALFORMED);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public boolean isUnmappable() { | 
 | 
        return (type == CR_UNMAPPABLE);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public int length() { | 
 | 
        if (!isError())  | 
 | 
            throw new UnsupportedOperationException();  | 
 | 
        return length;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public static final CoderResult UNDERFLOW  | 
 | 
        = new CoderResult(CR_UNDERFLOW, 0);  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public static final CoderResult OVERFLOW  | 
 | 
        = new CoderResult(CR_OVERFLOW, 0);  | 
 | 
 | 
 | 
    private static abstract class Cache { | 
 | 
 | 
 | 
        private Map<Integer,WeakReference<CoderResult>> cache = null;  | 
 | 
 | 
 | 
        protected abstract CoderResult create(int len);  | 
 | 
 | 
 | 
        private synchronized CoderResult get(int len) { | 
 | 
            if (len <= 0)  | 
 | 
                throw new IllegalArgumentException("Non-positive length"); | 
 | 
            Integer k = new Integer(len);  | 
 | 
            WeakReference<CoderResult> w;  | 
 | 
            CoderResult e = null;  | 
 | 
            if (cache == null) { | 
 | 
                cache = new HashMap<Integer,WeakReference<CoderResult>>();  | 
 | 
            } else if ((w = cache.get(k)) != null) { | 
 | 
                e = w.get();  | 
 | 
            }  | 
 | 
            if (e == null) { | 
 | 
                e = create(len);  | 
 | 
                cache.put(k, new WeakReference<CoderResult>(e));  | 
 | 
            }  | 
 | 
            return e;  | 
 | 
        }  | 
 | 
 | 
 | 
    }  | 
 | 
 | 
 | 
    private static Cache malformedCache  | 
 | 
        = new Cache() { | 
 | 
                public CoderResult create(int len) { | 
 | 
                    return new CoderResult(CR_MALFORMED, len);  | 
 | 
                }};  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public static CoderResult malformedForLength(int length) { | 
 | 
        return malformedCache.get(length);  | 
 | 
    }  | 
 | 
 | 
 | 
    private static Cache unmappableCache  | 
 | 
        = new Cache() { | 
 | 
                public CoderResult create(int len) { | 
 | 
                    return new CoderResult(CR_UNMAPPABLE, len);  | 
 | 
                }};  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public static CoderResult unmappableForLength(int length) { | 
 | 
        return unmappableCache.get(length);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public void throwException()  | 
 | 
        throws CharacterCodingException  | 
 | 
    { | 
 | 
        switch (type) { | 
 | 
        case CR_UNDERFLOW:   throw new BufferUnderflowException();  | 
 | 
        case CR_OVERFLOW:    throw new BufferOverflowException();  | 
 | 
        case CR_MALFORMED:   throw new MalformedInputException(length);  | 
 | 
        case CR_UNMAPPABLE:  throw new UnmappableCharacterException(length);  | 
 | 
        default:  | 
 | 
            assert false;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
}  |