| Method from java.nio.charset.CharsetDecoder Detail: |
public final float averageCharsPerByte() {
return averageCharsPerByte;
}
|
public final Charset charset() {
return charset;
}
|
public final CharBuffer decode(ByteBuffer in) throws CharacterCodingException {
// XXX: Sun's Javadoc seems to contradict itself saying an
// IllegalStateException is thrown "if a decoding operation is already
// in progress" and also that "it resets this Decoder".
// Should we check to see that the state is reset, or should we
// call reset()?
if (state != STATE_RESET)
throw new IllegalStateException ();
// REVIEW: Using max instead of average may allocate a very large
// buffer. Maybe we should do something more efficient?
int remaining = in.remaining ();
int n = (int) (remaining * maxCharsPerByte ());
CharBuffer out = CharBuffer.allocate (n);
if (remaining == 0)
{
state = STATE_FLUSHED;
return out;
}
CoderResult cr = decode (in, out, true);
if (cr.isError ())
cr.throwException ();
cr = flush (out);
if (cr.isError ())
cr.throwException ();
reset();
out.flip ();
// Unfortunately, resizing the actual charbuffer array is required.
char[] resized = new char[out.remaining()];
out.get(resized);
return CharBuffer.wrap(resized);
}
|
public final CoderResult decode(ByteBuffer in,
CharBuffer out,
boolean endOfInput) {
int newState = endOfInput ? STATE_END : STATE_CODING;
// XXX: Need to check for "previous step was an invocation [not] of
// this method with a value of true for the endOfInput parameter but
// a return value indicating an incomplete decoding operation"
// XXX: We will not check the previous return value, just
// that the previous call passed true for endOfInput
if (state != STATE_RESET && state != STATE_CODING
&& !(endOfInput && state == STATE_END))
throw new IllegalStateException ();
state = newState;
for (;;)
{
CoderResult cr;
try
{
cr = decodeLoop (in, out);
}
catch (RuntimeException e)
{
throw new CoderMalfunctionError (e);
}
if (cr.isOverflow ())
return cr;
if (cr.isUnderflow ())
{
if (endOfInput && in.hasRemaining ())
cr = CoderResult.malformedForLength (in.remaining ());
else
return cr;
}
CodingErrorAction action = cr.isMalformed ()
? malformedInputAction
: unmappableCharacterAction;
if (action == CodingErrorAction.REPORT)
return cr;
if (action == CodingErrorAction.REPLACE)
{
if (out.remaining () < replacement.length ())
return CoderResult.OVERFLOW;
out.put (replacement);
}
in.position (in.position () + cr.length ());
}
}
|
abstract protected CoderResult decodeLoop(ByteBuffer in,
CharBuffer out)
|
public Charset detectedCharset() {
throw new UnsupportedOperationException ();
}
|
public final CoderResult flush(CharBuffer out) {
// It seems weird that you can flush after reset, but Sun's javadoc
// says an IllegalStateException is thrown "If the previous step of the
// current decoding operation was an invocation neither of the reset
// method nor ... of the three-argument decode method with a value of
// true for the endOfInput parameter."
// Further note that flush() only requires that there not be
// an IllegalStateException if the previous step was a call to
// decode with true as the last argument. It does not require
// that the call succeeded. decode() does require that it succeeded.
// XXX: test this to see if reality matches javadoc
if (state != STATE_RESET && state != STATE_END)
throw new IllegalStateException ();
state = STATE_FLUSHED;
return implFlush (out);
}
|
protected CoderResult implFlush(CharBuffer out) {
return CoderResult.UNDERFLOW;
}
|
protected void implOnMalformedInput(CodingErrorAction newAction) {
// default implementation does nothing
}
|
protected void implOnUnmappableCharacter(CodingErrorAction newAction) {
// default implementation does nothing
}
|
protected void implReplaceWith(String newReplacement) {
// default implementation does nothing
}
|
protected void implReset() {
// default implementation does nothing
}
|
public boolean isAutoDetecting() {
return false;
}
|
public boolean isCharsetDetected() {
throw new UnsupportedOperationException ();
}
|
public CodingErrorAction malformedInputAction() {
return malformedInputAction;
}
|
public final float maxCharsPerByte() {
return maxCharsPerByte;
}
|
public final CharsetDecoder onMalformedInput(CodingErrorAction newAction) {
if (newAction == null)
throw new IllegalArgumentException ("Null action");
malformedInputAction = newAction;
implOnMalformedInput (newAction);
return this;
}
|
public final CharsetDecoder onUnmappableCharacter(CodingErrorAction newAction) {
if (newAction == null)
throw new IllegalArgumentException ("Null action");
unmappableCharacterAction = newAction;
implOnUnmappableCharacter (newAction);
return this;
}
|
public final CharsetDecoder replaceWith(String newReplacement) {
if (newReplacement == null)
throw new IllegalArgumentException ("Null replacement");
if (newReplacement.length () == 0)
throw new IllegalArgumentException ("Empty replacement");
// XXX: what about maxCharsPerByte?
this.replacement = newReplacement;
implReplaceWith (newReplacement);
return this;
}
|
public final String replacement() {
return replacement;
}
|
public final CharsetDecoder reset() {
state = STATE_RESET;
implReset ();
return this;
}
|
public CodingErrorAction unmappableCharacterAction() {
return unmappableCharacterAction;
}
|