Polishing DataBuffer::write(CharSequence, Charset)
See gh-29943
This commit is contained in:
parent
026be04b75
commit
79a1fcb099
|
@ -19,10 +19,8 @@ package org.springframework.core.io.buffer;
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.UncheckedIOException;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.CharBuffer;
|
import java.nio.CharBuffer;
|
||||||
import java.nio.charset.CharacterCodingException;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.CharsetEncoder;
|
import java.nio.charset.CharsetEncoder;
|
||||||
import java.nio.charset.CoderResult;
|
import java.nio.charset.CoderResult;
|
||||||
|
@ -265,32 +263,31 @@ public interface DataBuffer {
|
||||||
default DataBuffer write(CharSequence charSequence, Charset charset) {
|
default DataBuffer write(CharSequence charSequence, Charset charset) {
|
||||||
Assert.notNull(charSequence, "CharSequence must not be null");
|
Assert.notNull(charSequence, "CharSequence must not be null");
|
||||||
Assert.notNull(charset, "Charset must not be null");
|
Assert.notNull(charset, "Charset must not be null");
|
||||||
if (charSequence.length() != 0) {
|
if (charSequence.length() > 0) {
|
||||||
CharsetEncoder charsetEncoder = charset.newEncoder()
|
CharsetEncoder encoder = charset.newEncoder()
|
||||||
.onMalformedInput(CodingErrorAction.REPLACE)
|
.onMalformedInput(CodingErrorAction.REPLACE)
|
||||||
.onUnmappableCharacter(CodingErrorAction.REPLACE);
|
.onUnmappableCharacter(CodingErrorAction.REPLACE);
|
||||||
CharBuffer src = CharBuffer.wrap(charSequence);
|
CharBuffer src = CharBuffer.wrap(charSequence);
|
||||||
int length = (int) (src.remaining() * charsetEncoder.maxBytesPerChar());
|
int cap = (int) (src.remaining() * encoder.averageBytesPerChar());
|
||||||
ensureWritable(length);
|
while (true) {
|
||||||
try (ByteBufferIterator iterator = writableByteBuffers()) {
|
ensureWritable(cap);
|
||||||
Assert.state(iterator.hasNext(), "No ByteBuffer available");
|
CoderResult cr;
|
||||||
ByteBuffer dest = iterator.next();
|
try (ByteBufferIterator iterator = writableByteBuffers()) {
|
||||||
int pos = dest.position();
|
Assert.state(iterator.hasNext(), "No ByteBuffer available");
|
||||||
CoderResult cr = charsetEncoder.encode(src, dest, true);
|
ByteBuffer dest = iterator.next();
|
||||||
if (!cr.isUnderflow()) {
|
cr = encoder.encode(src, dest, true);
|
||||||
cr.throwException();
|
if (cr.isUnderflow()) {
|
||||||
|
cr = encoder.flush(dest);
|
||||||
|
}
|
||||||
|
writePosition(dest.position());
|
||||||
}
|
}
|
||||||
cr = charsetEncoder.flush(dest);
|
if (cr.isUnderflow()) {
|
||||||
if (!cr.isUnderflow()) {
|
break;
|
||||||
cr.throwException();
|
}
|
||||||
|
if (cr.isOverflow()) {
|
||||||
|
cap = 2 * cap + 1;
|
||||||
}
|
}
|
||||||
length = dest.position() - pos;
|
|
||||||
}
|
}
|
||||||
catch (CharacterCodingException ex) {
|
|
||||||
// should not happen, because the encoder uses action REPLACE
|
|
||||||
throw new UncheckedIOException(ex);
|
|
||||||
}
|
|
||||||
writePosition(writePosition() + length);
|
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue