Fix StringDecoder#decodeToMono issue with empty input

Before this change decodeToMono always created a StringBuilder to
aggregate resulting in an "" (empty string) rather than an empty
Mono for an empty input stream.

Now we aggregate in the DataBuffer instead and then decode to String.
This commit is contained in:
Rossen Stoyanchev
2016-07-07 05:36:19 -04:00
parent 1e1e2f8b1b
commit a584311178
2 changed files with 31 additions and 11 deletions

View File

@@ -91,16 +91,16 @@ public class StringDecoder extends AbstractDecoder<String> {
if (this.splitOnNewline) {
inputFlux = Flux.from(inputStream).flatMap(StringDecoder::splitOnNewline);
}
return decodeInternal(inputFlux, mimeType);
return inputFlux.map(buffer -> decodeDataBuffer(buffer, mimeType));
}
@Override
public Mono<String> decodeToMono(Publisher<DataBuffer> inputStream, ResolvableType elementType,
MimeType mimeType, Object... hints) {
return decodeInternal(Flux.from(inputStream), mimeType).
collect(StringBuilder::new, StringBuilder::append).
map(StringBuilder::toString);
return Flux.from(inputStream)
.reduce(DataBuffer::write)
.map(buffer -> decodeDataBuffer(buffer, mimeType));
}
private static Flux<DataBuffer> splitOnNewline(DataBuffer dataBuffer) {
@@ -120,13 +120,11 @@ public class StringDecoder extends AbstractDecoder<String> {
return Flux.fromIterable(results);
}
private Flux<String> decodeInternal(Flux<DataBuffer> inputFlux, MimeType mimeType) {
private String decodeDataBuffer(DataBuffer dataBuffer, MimeType mimeType) {
Charset charset = getCharset(mimeType);
return inputFlux.map(dataBuffer -> {
CharBuffer charBuffer = charset.decode(dataBuffer.asByteBuffer());
DataBufferUtils.release(dataBuffer);
return charBuffer.toString();
});
CharBuffer charBuffer = charset.decode(dataBuffer.asByteBuffer());
DataBufferUtils.release(dataBuffer);
return charBuffer.toString();
}
private Charset getCharset(MimeType mimeType) {

View File

@@ -73,7 +73,18 @@ public class StringDecoderTests extends AbstractDataBufferAllocatingTestCase {
}
@Test
public void decodeEmpty() throws InterruptedException {
public void decodeEmptyFlux() throws InterruptedException {
Flux<DataBuffer> source = Flux.empty();
Flux<String> output = this.decoder.decode(source, ResolvableType.forClass(String.class), null);
TestSubscriber.subscribe(output)
.assertNoError()
.assertComplete()
.assertNoValues();
}
@Test
public void decodeEmptyString() throws InterruptedException {
Flux<DataBuffer> source = Flux.just(stringBuffer(""));
Flux<String> output = this.decoder.decode(source, ResolvableType.forClass(String.class), null);
@@ -92,4 +103,15 @@ public class StringDecoderTests extends AbstractDataBufferAllocatingTestCase {
.assertValues("foobarbaz");
}
@Test
public void decodeToMonoWithEmptyFlux() throws InterruptedException {
Flux<DataBuffer> source = Flux.empty();
Mono<String> output = this.decoder.decodeToMono(source, ResolvableType.forClass(String.class), null);
TestSubscriber.subscribe(output)
.assertNoError()
.assertComplete()
.assertNoValues();
}
}