2020import java .nio .charset .CoderMalfunctionError ;
2121import java .nio .charset .StandardCharsets ;
2222import java .util .Map ;
23+ import java .util .concurrent .ConcurrentHashMap ;
24+ import java .util .concurrent .ConcurrentMap ;
2325
2426import org .reactivestreams .Publisher ;
2527import reactor .core .publisher .Flux ;
@@ -49,6 +51,9 @@ public final class CharSequenceEncoder extends AbstractEncoder<CharSequence> {
4951 */
5052 public static final Charset DEFAULT_CHARSET = StandardCharsets .UTF_8 ;
5153
54+ private final ConcurrentMap <Charset , Float > charsetToMaxBytesPerChar =
55+ new ConcurrentHashMap <>(3 );
56+
5257
5358 private CharSequenceEncoder (MimeType ... mimeTypes ) {
5459 super (mimeTypes );
@@ -76,7 +81,8 @@ public Flux<DataBuffer> encode(Publisher<? extends CharSequence> inputStream,
7681 });
7782 }
7883 boolean release = true ;
79- DataBuffer dataBuffer = bufferFactory .allocateBuffer ();
84+ int capacity = calculateCapacity (charSequence , charset );
85+ DataBuffer dataBuffer = bufferFactory .allocateBuffer (capacity );
8086 try {
8187 dataBuffer .write (charSequence , charset );
8288 release = false ;
@@ -93,6 +99,13 @@ public Flux<DataBuffer> encode(Publisher<? extends CharSequence> inputStream,
9399 });
94100 }
95101
102+ private int calculateCapacity (CharSequence sequence , Charset charset ) {
103+ float maxBytesPerChar = this .charsetToMaxBytesPerChar
104+ .computeIfAbsent (charset , cs -> cs .newEncoder ().maxBytesPerChar ());
105+ float maxBytesForSequence = sequence .length () * maxBytesPerChar ;
106+ return (int ) Math .ceil (maxBytesForSequence );
107+ }
108+
96109 private Charset getCharset (@ Nullable MimeType mimeType ) {
97110 if (mimeType != null && mimeType .getCharset () != null ) {
98111 return mimeType .getCharset ();
0 commit comments