diff --git a/spring-web-reactive/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java b/spring-web-reactive/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java index 4a1c73bb34d..27f123ac82c 100644 --- a/spring-web-reactive/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java +++ b/spring-web-reactive/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java @@ -244,7 +244,7 @@ public class DefaultDataBuffer implements DataBuffer { @Override public int available() throws IOException { - return byteBuffer.limit() - readPosition; + return readableByteCount(); } @Override diff --git a/spring-web-reactive/src/main/java/org/springframework/core/io/buffer/support/DataBufferUtils.java b/spring-web-reactive/src/main/java/org/springframework/core/io/buffer/support/DataBufferUtils.java index 48399582336..d4bcc1ad6ca 100644 --- a/spring-web-reactive/src/main/java/org/springframework/core/io/buffer/support/DataBufferUtils.java +++ b/spring-web-reactive/src/main/java/org/springframework/core/io/buffer/support/DataBufferUtils.java @@ -25,23 +25,42 @@ import org.springframework.core.io.buffer.DataBuffer; import org.springframework.util.Assert; /** + * Utility class for working with {@link DataBuffer}s. + * * @author Arjen Poutsma */ public abstract class DataBufferUtils { + /** + * Returns the given {@link DataBuffer} as a {@link Flux} of bytes. + * @param buffer the buffer to return the bytes of + * @return the bytes as a flux + */ public static Flux toPublisher(DataBuffer buffer) { Assert.notNull(buffer, "'buffer' must not be null"); - byte[] bytes1 = new byte[buffer.readableByteCount()]; - buffer.read(bytes1); + byte[] bytes = new byte[buffer.readableByteCount()]; + buffer.read(bytes); - Byte[] bytes2 = new Byte[bytes1.length]; - for (int i = 0; i < bytes1.length; i++) { - bytes2[i] = bytes1[i]; - } - return Flux.fromArray(bytes2); + Byte[] bytesObjects = box(bytes); + + return Flux.fromArray(bytesObjects); } + private static Byte[] box(byte[] bytes) { + Byte[] bytesObjects = new Byte[bytes.length]; + for (int i = 0; i < bytes.length; i++) { + bytesObjects[i] = bytes[i]; + } + return bytesObjects; + } + + /** + * Returns the given data buffer publisher as an input stream, streaming over all + * underlying buffers when available. + * @param publisher the publisher to create the input stream for + * @return the input stream + */ public static InputStream toInputStream(Publisher publisher) { return new DataBufferPublisherInputStream(publisher); } diff --git a/spring-web-reactive/src/test/java/org/springframework/core/io/buffer/support/DataBufferTestUtils.java b/spring-web-reactive/src/test/java/org/springframework/core/io/buffer/support/DataBufferTestUtils.java new file mode 100644 index 00000000000..9d7cecd1379 --- /dev/null +++ b/spring-web-reactive/src/test/java/org/springframework/core/io/buffer/support/DataBufferTestUtils.java @@ -0,0 +1,65 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.io.buffer.support; + +import java.nio.charset.Charset; + +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.util.Assert; + +/** + * Utility class for working with {@link DataBuffer}s in tests. + * + *

Note that this class is in the {@code test} tree of the project: the methods + * contained herein are not suitable for production code bases. + * + * @author Arjen Poutsma + */ +public abstract class DataBufferTestUtils { + + /** + * Dumps all the bytes in the given data buffer, and returns them as a byte array. + * + *

Note that this method reads the entire buffer into the heap, which might + * consume a lot of memory. + * @param buffer the data buffer to dump the bytes of + * @return the bytes in the given data buffer + */ + public static byte[] dumpBytes(DataBuffer buffer) { + Assert.notNull(buffer, "'buffer' must not be null"); + + byte[] bytes = new byte[buffer.readableByteCount()]; + buffer.read(bytes); + return bytes; + } + + /** + * Dumps all the bytes in the given data buffer, and returns them as a string. + * + *

Note that this method reads the entire buffer into the heap, which might + * consume a lot of memory. + * @param buffer the data buffer to dump the string contents of + * @param charset the charset of the data + * @return the string representation of the given data buffer + */ + public static String dumpString(DataBuffer buffer, Charset charset) { + Assert.notNull(charset, "'charset' must not be null"); + + byte[] bytes = dumpBytes(buffer); + return new String(bytes, charset); + } +} diff --git a/spring-web-reactive/src/test/java/org/springframework/core/io/buffer/support/DataBufferTestUtilsTests.java b/spring-web-reactive/src/test/java/org/springframework/core/io/buffer/support/DataBufferTestUtilsTests.java new file mode 100644 index 00000000000..98267b15478 --- /dev/null +++ b/spring-web-reactive/src/test/java/org/springframework/core/io/buffer/support/DataBufferTestUtilsTests.java @@ -0,0 +1,79 @@ +/* + * Copyright 2002-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.core.io.buffer.support; + +import java.nio.charset.StandardCharsets; + +import io.netty.buffer.PooledByteBufAllocator; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferAllocator; +import org.springframework.core.io.buffer.DefaultDataBufferAllocator; +import org.springframework.core.io.buffer.NettyDataBufferAllocator; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +/** + * @author Arjen Poutsma + */ +@RunWith(Parameterized.class) +public class DataBufferTestUtilsTests { + + @Parameterized.Parameter + public DataBufferAllocator allocator; + + @Parameterized.Parameters(name = "{0}") + public static Object[][] buffers() { + + return new Object[][]{ + {new NettyDataBufferAllocator(new UnpooledByteBufAllocator(true))}, + {new NettyDataBufferAllocator(new UnpooledByteBufAllocator(false))}, + {new NettyDataBufferAllocator(new PooledByteBufAllocator(true))}, + {new NettyDataBufferAllocator(new PooledByteBufAllocator(false))}, + {new DefaultDataBufferAllocator(true)}, + {new DefaultDataBufferAllocator(false)}}; + } + + @Test + public void dumpBytes() { + DataBuffer buffer = allocator.allocateBuffer(4); + byte[] source = {'a', 'b', 'c', 'd'}; + buffer.write(source); + + byte[] result = DataBufferTestUtils.dumpBytes(buffer); + + assertArrayEquals(source, result); + } + + @Test + public void dumpString() { + DataBuffer buffer = allocator.allocateBuffer(4); + String source = "abcd"; + buffer.write(source.getBytes(StandardCharsets.UTF_8)); + + String result = DataBufferTestUtils.dumpString(buffer, StandardCharsets.UTF_8); + + + assertEquals(source, result); + } + +} \ No newline at end of file