Skip to content

Commit 79a1fcb

Browse files
committed
Polishing DataBuffer::write(CharSequence, Charset)
See gh-29943
1 parent 026be04 commit 79a1fcb

File tree

1 file changed

+19
-22
lines changed
  • spring-core/src/main/java/org/springframework/core/io/buffer

1 file changed

+19
-22
lines changed

spring-core/src/main/java/org/springframework/core/io/buffer/DataBuffer.java

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@
1919
import java.io.Closeable;
2020
import java.io.InputStream;
2121
import java.io.OutputStream;
22-
import java.io.UncheckedIOException;
2322
import java.nio.ByteBuffer;
2423
import java.nio.CharBuffer;
25-
import java.nio.charset.CharacterCodingException;
2624
import java.nio.charset.Charset;
2725
import java.nio.charset.CharsetEncoder;
2826
import java.nio.charset.CoderResult;
@@ -265,32 +263,31 @@ default DataBuffer ensureCapacity(int capacity) {
265263
default DataBuffer write(CharSequence charSequence, Charset charset) {
266264
Assert.notNull(charSequence, "CharSequence must not be null");
267265
Assert.notNull(charset, "Charset must not be null");
268-
if (charSequence.length() != 0) {
269-
CharsetEncoder charsetEncoder = charset.newEncoder()
266+
if (charSequence.length() > 0) {
267+
CharsetEncoder encoder = charset.newEncoder()
270268
.onMalformedInput(CodingErrorAction.REPLACE)
271269
.onUnmappableCharacter(CodingErrorAction.REPLACE);
272270
CharBuffer src = CharBuffer.wrap(charSequence);
273-
int length = (int) (src.remaining() * charsetEncoder.maxBytesPerChar());
274-
ensureWritable(length);
275-
try (ByteBufferIterator iterator = writableByteBuffers()) {
276-
Assert.state(iterator.hasNext(), "No ByteBuffer available");
277-
ByteBuffer dest = iterator.next();
278-
int pos = dest.position();
279-
CoderResult cr = charsetEncoder.encode(src, dest, true);
280-
if (!cr.isUnderflow()) {
281-
cr.throwException();
271+
int cap = (int) (src.remaining() * encoder.averageBytesPerChar());
272+
while (true) {
273+
ensureWritable(cap);
274+
CoderResult cr;
275+
try (ByteBufferIterator iterator = writableByteBuffers()) {
276+
Assert.state(iterator.hasNext(), "No ByteBuffer available");
277+
ByteBuffer dest = iterator.next();
278+
cr = encoder.encode(src, dest, true);
279+
if (cr.isUnderflow()) {
280+
cr = encoder.flush(dest);
281+
}
282+
writePosition(dest.position());
282283
}
283-
cr = charsetEncoder.flush(dest);
284-
if (!cr.isUnderflow()) {
285-
cr.throwException();
284+
if (cr.isUnderflow()) {
285+
break;
286+
}
287+
if (cr.isOverflow()) {
288+
cap = 2 * cap + 1;
286289
}
287-
length = dest.position() - pos;
288-
}
289-
catch (CharacterCodingException ex) {
290-
// should not happen, because the encoder uses action REPLACE
291-
throw new UncheckedIOException(ex);
292290
}
293-
writePosition(writePosition() + length);
294291
}
295292
return this;
296293
}

0 commit comments

Comments
 (0)