package java.nio.charset;
import java.lang.ref.WeakReference;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.util.HashMap;
public class CoderResult
{
private static final int TYPE_MALFORMED = 0;
private static final int TYPE_OVERFLOW = 1;
private static final int TYPE_UNDERFLOW = 2;
private static final int TYPE_UNMAPPABLE = 3;
public static final CoderResult OVERFLOW
= new CoderResult (TYPE_OVERFLOW, 0);
public static final CoderResult UNDERFLOW
= new CoderResult (TYPE_UNDERFLOW, 0);
private static final String[] names
= { "MALFORMED", "OVERFLOW", "UNDERFLOW", "UNMAPPABLE" };
private static final Cache malformedCache
= new Cache ()
{
protected CoderResult make (int length)
{
return new CoderResult (TYPE_MALFORMED, length);
}
};
private static final Cache unmappableCache
= new Cache ()
{
protected CoderResult make (int length)
{
return new CoderResult (TYPE_UNMAPPABLE, length);
}
};
private final int type;
private final int length;
CoderResult (int type, int length)
{
this.type = type;
this.length = length;
}
public boolean isError ()
{
return length > 0;
}
public boolean isMalformed ()
{
return type == TYPE_MALFORMED;
}
public boolean isOverflow ()
{
return type == TYPE_OVERFLOW;
}
public boolean isUnderflow ()
{
return type == TYPE_UNDERFLOW;
}
public boolean isUnmappable ()
{
return type == TYPE_UNMAPPABLE;
}
public int length ()
{
if (length <= 0)
throw new UnsupportedOperationException ();
else
return length;
}
public static CoderResult malformedForLength (int length)
{
return malformedCache.get (length);
}
public void throwException ()
throws CharacterCodingException
{
switch (type)
{
case TYPE_MALFORMED:
throw new MalformedInputException (length);
case TYPE_OVERFLOW:
throw new BufferOverflowException ();
case TYPE_UNDERFLOW:
throw new BufferUnderflowException ();
case TYPE_UNMAPPABLE:
throw new UnmappableCharacterException (length);
}
}
public String toString ()
{
String name = names[type];
return (length > 0) ? name + '[' + length + ']' : name;
}
public static CoderResult unmappableForLength (int length)
{
return unmappableCache.get (length);
}
private abstract static class Cache
{
private final HashMap cache;
Cache ()
{
cache = new HashMap ();
}
synchronized CoderResult get (int length)
{
if (length <= 0)
throw new IllegalArgumentException ("Non-positive length");
Integer len = new Integer (length);
CoderResult cr = null;
Object o;
if ((o = cache.get (len)) != null)
cr = (CoderResult) ((WeakReference) o).get ();
if (cr == null)
{
cr = make (length);
cache.put (len, new WeakReference (cr));
}
return cr;
}
protected abstract CoderResult make (int length);
}
}