|
19 | 19 | import java.io.Closeable;
|
20 | 20 | import java.io.InputStream;
|
21 | 21 | import java.io.OutputStream;
|
22 |
| -import java.io.UncheckedIOException; |
23 | 22 | import java.nio.ByteBuffer;
|
24 | 23 | import java.nio.CharBuffer;
|
25 |
| -import java.nio.charset.CharacterCodingException; |
26 | 24 | import java.nio.charset.Charset;
|
27 | 25 | import java.nio.charset.CharsetEncoder;
|
28 | 26 | import java.nio.charset.CoderResult;
|
@@ -265,32 +263,31 @@ default DataBuffer ensureCapacity(int capacity) {
|
265 | 263 | default DataBuffer write(CharSequence charSequence, Charset charset) {
|
266 | 264 | Assert.notNull(charSequence, "CharSequence must not be null");
|
267 | 265 | 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() |
270 | 268 | .onMalformedInput(CodingErrorAction.REPLACE)
|
271 | 269 | .onUnmappableCharacter(CodingErrorAction.REPLACE);
|
272 | 270 | 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()); |
282 | 283 | }
|
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; |
286 | 289 | }
|
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); |
292 | 290 | }
|
293 |
| - writePosition(writePosition() + length); |
294 | 291 | }
|
295 | 292 | return this;
|
296 | 293 | }
|
|
0 commit comments