public abstract class CharsetDecoder extends Object
The input byte sequence is wrapped by a
ByteBuffer
and the output character sequence is a
CharBuffer
. A decoder instance should be used in
the following sequence, which is referred to as a decoding operation:
reset
method to reset the decoder if the
decoder has been used;decode
method until the additional input is not needed, the endOfInput
parameter must be set to false, the input buffer must be filled and the
output buffer must be flushed between invocations;decode
method for the last time, and then the endOfInput
parameter
must be set to true;flush
method to flush the
output.
The decode
method will
convert as many bytes as possible, and the process won't stop until the input
bytes have run out, the output buffer has been filled or some error has
happened. A CoderResult
instance will be returned to
indicate the stop reason, and the invoker can identify the result and choose
further action, which includes filling the input buffer, flushing the output
buffer or recovering from an error and trying again.
There are two common decoding errors. One is named malformed and it is returned when the input byte sequence is illegal for the current specific charset, the other is named unmappable character and it is returned when a problem occurs mapping a legal input byte sequence to its Unicode character equivalent.
Both errors can be handled in three ways, the default one is to report the
error to the invoker by a CoderResult
instance, and the
alternatives are to ignore it or to replace the erroneous input with the
replacement string. The replacement string is "?" by default and can be
changed by invoking replaceWith
method. The
invoker of this decoder can choose one way by specifying a
CodingErrorAction
instance for each error type via
onMalformedInput
method and
onUnmappableCharacter
method.
This is an abstract class and encapsulates many common operations of the
decoding process for all charsets. Decoders for a specific charset should
extend this class and need only to implement the
decodeLoop
method for the basic
decoding. If a subclass maintains an internal state, it should override the
implFlush
method and the
implReset
method in addition.
This class is not thread-safe.
Charset
,
CharsetEncoder
Modifier | Constructor and Description |
---|---|
protected |
CharsetDecoder(Charset charset,
float averageCharsPerByte,
float maxCharsPerByte)
Constructs a new
CharsetDecoder using the given
Charset , average number and maximum number of characters
created by this decoder for one input byte, and the default replacement
string "?". |
Modifier and Type | Method and Description |
---|---|
float |
averageCharsPerByte()
Returns the average number of characters created by this decoder for a
single input byte.
|
Charset |
charset()
Returns the
Charset which this decoder uses. |
CharBuffer |
decode(ByteBuffer in)
This is a facade method for the decoding operation.
|
CoderResult |
decode(ByteBuffer in,
CharBuffer out,
boolean endOfInput)
Decodes bytes starting at the current position of the given input buffer,
and writes the equivalent character sequence into the given output buffer
from its current position.
|
protected abstract CoderResult |
decodeLoop(ByteBuffer in,
CharBuffer out)
Decodes bytes into characters.
|
Charset |
detectedCharset()
Gets the charset detected by this decoder; this method is optional.
|
CoderResult |
flush(CharBuffer out)
Flushes this decoder.
|
protected CoderResult |
implFlush(CharBuffer out)
Flushes this decoder.
|
protected void |
implOnMalformedInput(CodingErrorAction newAction)
Notifies that this decoder's
CodingErrorAction specified
for malformed input error has been changed. |
protected void |
implOnUnmappableCharacter(CodingErrorAction newAction)
Notifies that this decoder's
CodingErrorAction specified
for unmappable character error has been changed. |
protected void |
implReplaceWith(String newReplacement)
Notifies that this decoder's replacement has been changed.
|
protected void |
implReset()
Reset this decoder's charset related state.
|
boolean |
isAutoDetecting()
Indicates whether this decoder implements an auto-detecting charset.
|
boolean |
isCharsetDetected()
Indicates whether this decoder has detected a charset; this method is
optional.
|
CodingErrorAction |
malformedInputAction()
Returns this decoder's
CodingErrorAction when malformed input
occurred during the decoding process. |
float |
maxCharsPerByte()
Returns the maximum number of characters which can be created by this
decoder for one input byte, must be positive.
|
CharsetDecoder |
onMalformedInput(CodingErrorAction newAction)
Sets this decoder's action on malformed input errors.
|
CharsetDecoder |
onUnmappableCharacter(CodingErrorAction newAction)
Sets this decoder's action on unmappable character errors.
|
String |
replacement()
Returns the replacement string, which is never null or empty.
|
CharsetDecoder |
replaceWith(String replacement)
Sets the new replacement string.
|
CharsetDecoder |
reset()
Resets this decoder.
|
CodingErrorAction |
unmappableCharacterAction()
Returns this decoder's
CodingErrorAction when an unmappable
character error occurred during the decoding process. |
protected CharsetDecoder(Charset charset, float averageCharsPerByte, float maxCharsPerByte)
CharsetDecoder
using the given
Charset
, average number and maximum number of characters
created by this decoder for one input byte, and the default replacement
string "?".charset
- the Charset
to be used by this decoder.averageCharsPerByte
- the average number of characters created by this decoder for
one input byte, must be positive.maxCharsPerByte
- the maximum number of characters created by this decoder for
one input byte, must be positive.IllegalArgumentException
- if averageCharsPerByte
or
maxCharsPerByte
is negative.public final float averageCharsPerByte()
public final CharBuffer decode(ByteBuffer in) throws CharacterCodingException
This method decodes the remaining byte sequence of the given byte buffer into a new character buffer. This method performs a complete decoding operation, resets at first, then decodes, and flushes at last.
This method should not be invoked while another decode
operation
is ongoing.
in
- the input buffer.CharBuffer
containing the the characters
produced by this decoding operation. The buffer's limit will be
the position of the last character in the buffer, and the
position will be zero.IllegalStateException
- if another decoding operation is ongoing.MalformedInputException
- if an illegal input byte sequence for this charset was
encountered, and the action for malformed error is
CodingErrorAction.REPORT
UnmappableCharacterException
- if a legal but unmappable input byte sequence for this
charset was encountered, and the action for unmappable
character error is
CodingErrorAction.REPORT
.
Unmappable means the byte sequence at the input buffer's
current position cannot be mapped to a Unicode character
sequence.CharacterCodingException
- if another exception happened during the decode operation.public final CoderResult decode(ByteBuffer in, CharBuffer out, boolean endOfInput)
The buffers' position will be changed with the reading and writing operation, but their limits and marks will be kept intact.
A CoderResult
instance will be returned according to
following rules:
CoderResult.OVERFLOW
indicates that
even though not all of the input has been processed, the buffer the
output is being written to has reached its capacity. In the event of this
code being returned this method should be called once more with an
out
argument that has not already been filled.CoderResult.UNDERFLOW
indicates that
as many bytes as possible in the input buffer have been decoded. If there
is no further input and no remaining bytes in the input buffer then this
operation may be regarded as complete. Otherwise, this method should be
called once more with additional input.malformed input
result
indicates that some malformed input error has been encountered, and the
erroneous bytes start at the input buffer's position and their number can
be got by result's length
. This kind of
result can be returned only if the malformed action is
CodingErrorAction.REPORT
. unmappable character
result indicates that some unmappable character error has been
encountered, and the erroneous bytes start at the input buffer's position
and their number can be got by result's
length
. This kind of result can be returned
only if the unmappable character action is
CodingErrorAction.REPORT
.
The endOfInput
parameter indicates that the invoker cannot
provide further input. This parameter is true if and only if the bytes in
current input buffer are all inputs for this decoding operation. Note
that it is common and won't cause an error if the invoker sets false and
then can't provide more input, while it may cause an error if the invoker
always sets true in several consecutive invocations. This would make the
remaining input to be treated as malformed input.
This method invokes the
decodeLoop
method to
implement the basic decode logic for a specific charset.
in
- the input buffer.out
- the output buffer.endOfInput
- true if all the input characters have been provided.CoderResult
instance which indicates the reason
of termination.IllegalStateException
- if decoding has started or no more input is needed in this
decoding progress.CoderMalfunctionError
- if the decodeLoop
method threw an BufferUnderflowException
or
BufferOverflowException
.protected abstract CoderResult decodeLoop(ByteBuffer in, CharBuffer out)
decode
method.
This method will implement the essential decoding operation, and it won't
stop decoding until either all the input bytes are read, the output
buffer is filled, or some exception is encountered. Then it will return a
CoderResult
object indicating the result of current
decoding operation. The rules to construct the CoderResult
are the same as for
decode
. When an
exception is encountered in the decoding operation, most implementations
of this method will return a relevant result object to the
decode
method, and some
performance optimized implementation may handle the exception and
implement the error action itself.
The buffers are scanned from their current positions, and their positions
will be modified accordingly, while their marks and limits will be
intact. At most in.remaining()
characters
will be read, and out.remaining()
bytes
will be written.
Note that some implementations may pre-scan the input buffer and return a
CoderResult.UNDERFLOW
until it receives sufficient input.
in
- the input buffer.out
- the output buffer.CoderResult
instance indicating the result.public Charset detectedCharset()
If implementing an auto-detecting charset, then this decoder returns the detected charset from this method when it is available. The returned charset will be the same for the rest of the decode operation.
If insufficient bytes have been read to determine the charset, an
IllegalStateException
will be thrown.
The default implementation always throws
UnsupportedOperationException
, so it should be overridden
by a subclass if needed.
UnsupportedOperationException
- if this decoder does not implement an auto-detecting charset.IllegalStateException
- if insufficient bytes have been read to determine the
charset.public final CoderResult flush(CharBuffer out)
implFlush
. Some
decoders may need to write some characters to the output buffer when they
have read all input bytes; subclasses can override
implFlush
to perform the writing operation.
The maximum number of written bytes won't be larger than
out.remaining()
. If some decoder wants to
write more bytes than an output buffer's remaining space allows, then a
CoderResult.OVERFLOW
will be returned, and this method
must be called again with a character buffer that has more remaining
space. Otherwise this method will return
CoderResult.UNDERFLOW
, which means one decoding process
has been completed successfully.
During the flush, the output buffer's position will be changed accordingly, while its mark and limit will be intact.
out
- the given output buffer.CoderResult.UNDERFLOW
or
CoderResult.OVERFLOW
.IllegalStateException
- if this decoder hasn't read all input bytes during one
decoding process, which means neither after calling
decode(ByteBuffer)
nor after
calling decode(ByteBuffer, CharBuffer, boolean)
with true as value
for the last boolean parameter.protected CoderResult implFlush(CharBuffer out)
CoderResult.UNDERFLOW
; this method can be
overridden if needed.out
- the output buffer.CoderResult.UNDERFLOW
or
CoderResult.OVERFLOW
.protected void implOnMalformedInput(CodingErrorAction newAction)
CodingErrorAction
specified
for malformed input error has been changed. The default implementation
does nothing; this method can be overridden if needed.newAction
- the new action.protected void implOnUnmappableCharacter(CodingErrorAction newAction)
CodingErrorAction
specified
for unmappable character error has been changed. The default
implementation does nothing; this method can be overridden if needed.newAction
- the new action.protected void implReplaceWith(String newReplacement)
newReplacement
- the new replacement string.protected void implReset()
public boolean isAutoDetecting()
true
if this decoder implements an auto-detecting
charset.public boolean isCharsetDetected()
If this decoder implements an auto-detecting charset, then this method
may start to return true during decoding operation to indicate that a
charset has been detected in the input bytes and that the charset can be
retrieved by invoking the detectedCharset
method.
Note that a decoder that implements an auto-detecting charset may still
succeed in decoding a portion of the given input even when it is unable
to detect the charset. For this reason users should be aware that a
false
return value does not indicate that no decoding took
place.
The default implementation always throws an
UnsupportedOperationException
; it should be overridden by
a subclass if needed.
true
if this decoder has detected a charset.UnsupportedOperationException
- if this decoder doesn't implement an auto-detecting charset.public CodingErrorAction malformedInputAction()
CodingErrorAction
when malformed input
occurred during the decoding process.public final float maxCharsPerByte()
public final CharsetDecoder onMalformedInput(CodingErrorAction newAction)
implOnMalformedInput
method with the given new action as argument.newAction
- the new action on malformed input error.IllegalArgumentException
- if newAction
is null
.public final CharsetDecoder onUnmappableCharacter(CodingErrorAction newAction)
implOnUnmappableCharacter
method with the given new action as argument.newAction
- the new action on unmappable character error.IllegalArgumentException
- if newAction
is null
.public final String replacement()
public final CharsetDecoder replaceWith(String replacement)
implReplaceWith
method with the given
new replacement as argument.replacement
- the replacement string, cannot be null or empty. Its length
cannot be larger than maxCharsPerByte()
.IllegalArgumentException
- if the given replacement cannot satisfy the requirement
mentioned above.public final CharsetDecoder reset()
implReset()
to reset any status related to the
specific charset.public CodingErrorAction unmappableCharacterAction()
CodingErrorAction
when an unmappable
character error occurred during the decoding process.