📄 charsetencoder.java
字号:
/**
* Flushes this encoder.
*
* <p> The default implementation of this method does nothing, and always
* returns {@link CoderResult#UNDERFLOW}. This method should be overridden
* by encoders that may need to write final bytes to the output buffer
* once the entire input sequence has been read. </p>
*
* @param out
* The output byte buffer
*
* @return A coder-result object, either {@link CoderResult#UNDERFLOW} or
* {@link CoderResult#OVERFLOW}
*/
protected CoderResult implFlush(ByteBuffer out) {
return CoderResult.UNDERFLOW;
}
/**
* Resets this encoder, clearing any internal state.
*
* <p> This method resets charset-independent state and also invokes the
* {@link #implReset() implReset} method in order to perform any
* charset-specific reset actions. </p>
*
* @return This encoder
*
*/
public final CharsetEncoder reset() {
implReset();
state = ST_RESET;
return this;
}
/**
* Resets this encoder, clearing any charset-specific internal state.
*
* <p> The default implementation of this method does nothing. This method
* should be overridden by encoders that maintain internal state. </p>
*/
protected void implReset() { }
/**
* Encodes one or more characters into one or more bytes.
*
* <p> This method encapsulates the basic encoding loop, encoding as many
* characters as possible until it either runs out of input, runs out of room
* in the output buffer, or encounters a encoding error. This method is
* invoked by the {@link #encode encode} method, which handles result
* interpretation and error recovery.
*
* <p> The buffers are read from, and written to, starting at their current
* positions. At most {@link Buffer#remaining in.remaining()} characters
* will be read, and at most {@link Buffer#remaining out.remaining()}
* bytes will be written. The buffers' positions will be advanced to
* reflect the characters read and the bytes written, but their marks and
* limits will not be modified.
*
* <p> This method returns a {@link CoderResult} object to describe its
* reason for termination, in the same manner as the {@link #encode encode}
* method. Most implementations of this method will handle encoding errors
* by returning an appropriate result object for interpretation by the
* {@link #encode encode} method. An optimized implementation may instead
* examine the relevant error action and implement that action itself.
*
* <p> An implementation of this method may perform arbitrary lookahead by
* returning {@link CoderResult#UNDERFLOW} until it receives sufficient
* input. </p>
*
* @param in
* The input character buffer
*
* @param out
* The output byte buffer
*
* @return A coder-result object describing the reason for termination
*/
protected abstract CoderResult encodeLoop(CharBuffer in,
ByteBuffer out);
/**
* Convenience method that encodes the remaining content of a single input
* character buffer into a newly-allocated byte buffer.
*
* <p> This method implements an entire <a href="#steps">encoding
* operation</a>; that is, it resets this encoder, then it encodes the
* characters in the given character buffer, and finally it flushes this
* encoder. This method should therefore not be invoked if a encoding
* operation is already in progress. </p>
*
* @param in
* The input character buffer
*
* @return A newly-allocated byte buffer containing the result of the
* encoding operation. The buffer's position will be zero and its
* limit will follow the last byte written.
*
* @throws IllegalStateException
* If an encoding operation is already in progress
*
* @throws MalformedInputException
* If the character sequence starting at the input buffer's current
* position is not a legal sixteen-bit Unicode sequence and the current malformed-input action
* is {@link CodingErrorAction#REPORT}
*
* @throws UnmappableCharacterException
* If the character sequence starting at the input buffer's current
* position cannot be mapped to an equivalent byte sequence and
* the current unmappable-character action is {@link
* CodingErrorAction#REPORT}
*/
public final ByteBuffer encode(CharBuffer in)
throws CharacterCodingException
{
int n = (int)(in.remaining() * averageBytesPerChar());
ByteBuffer out = ByteBuffer.allocate(n);
if (n == 0)
return out;
reset();
for (;;) {
CoderResult cr;
if (in.hasRemaining())
cr = encode(in, out, true);
else
cr = flush(out);
if (cr.isUnderflow())
break;
if (cr.isOverflow()) {
n *= 2;
ByteBuffer o = ByteBuffer.allocate(n);
out.flip();
o.put(out);
out = o;
continue;
}
cr.throwException();
}
out.flip();
return out;
}
private boolean canEncode(CharBuffer cb) {
if (state == ST_FLUSHED)
reset();
else if (state != ST_RESET)
throwIllegalStateException(state, ST_CODING);
CodingErrorAction ma = malformedInputAction();
CodingErrorAction ua = unmappableCharacterAction();
try {
onMalformedInput(CodingErrorAction.REPORT);
onUnmappableCharacter(CodingErrorAction.REPORT);
encode(cb);
} catch (CharacterCodingException x) {
return false;
} finally {
onMalformedInput(ma);
onUnmappableCharacter(ua);
reset();
}
return true;
}
/**
* Tells whether or not this encoder can encode the given character.
*
* <p> This method returns <tt>false</tt> if the given character is a
* surrogate character; such characters can be interpreted only when they
* are members of a pair consisting of a high surrogate followed by a low
* surrogate. The {@link #canEncode(java.lang.CharSequence)
* canEncode(CharSequence)} method may be used to test whether or not a
* character sequence can be encoded.
*
* <p> This method may modify this encoder's state; it should therefore not
* be invoked if an <a href="#steps">encoding operation</a> is already in
* progress.
*
* <p> The default implementation of this method is not very efficient; it
* should generally be overridden to improve performance. </p>
*
* @return <tt>true</tt> if, and only if, this encoder can encode
* the given character
*
* @throws IllegalStateException
* If an encoding operation is already in progress
*/
public boolean canEncode(char c) {
CharBuffer cb = CharBuffer.allocate(1);
cb.put(c);
cb.flip();
return canEncode(cb);
}
/**
* Tells whether or not this encoder can encode the given character
* sequence.
*
* <p> If this method returns <tt>false</tt> for a particular character
* sequence then more information about why the sequence cannot be encoded
* may be obtained by performing a full <a href="#steps">encoding
* operation</a>.
*
* <p> This method may modify this encoder's state; it should therefore not
* be invoked if an encoding operation is already in progress.
*
* <p> The default implementation of this method is not very efficient; it
* should generally be overridden to improve performance. </p>
*
* @return <tt>true</tt> if, and only if, this encoder can encode
* the given character without throwing any exceptions and without
* performing any replacements
*
* @throws IllegalStateException
* If an encoding operation is already in progress
*/
public boolean canEncode(CharSequence cs) {
CharBuffer cb;
if (cs instanceof CharBuffer)
cb = ((CharBuffer)cs).duplicate();
else
cb = CharBuffer.wrap(cs.toString());
return canEncode(cb);
}
private void throwIllegalStateException(int from, int to) {
throw new IllegalStateException("Current state = " + stateNames[from]
+ ", new state = " + stateNames[to]);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -