Write CharSequence instances to DataBuffers

Prior to this commit, one could write a `CharSequence` to an existing
`DataBuffer` instance by turning it into a byte array or `ByteBuffer`
first. This had the following disadvantages:

1. Memory allocation was not efficient (not leveraging pooled memory
when available)
2. Dealing with `CharsetEncoder` is not always easy
3. `DataBuffer` implementations, like `NettyDataBuffer` can use
optimized implementations in some cases

This commit adds a new `DataBuffer#write(CharSequence, Charset)` method
for those cases and also an `ensureCapacity` method useful for checking
that the current buffer has enough capacity to write to it..

Issue: SPR-17558
This commit is contained in:
Brian Clozel
2018-12-20 21:33:33 +01:00
parent 5e4a8966ee
commit 6361b0cb23
7 changed files with 190 additions and 17 deletions

View File

@@ -20,6 +20,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import org.junit.Test;
@@ -150,6 +151,70 @@ public class DataBufferTests extends AbstractDataBufferAllocatingTestCase {
release(buffer);
}
@Test
public void writeNullString() {
DataBuffer buffer = createDataBuffer(1);
try {
buffer.write(null, StandardCharsets.UTF_8);
fail("IllegalArgumentException expected");
}
catch (IllegalArgumentException exc) {
}
finally {
release(buffer);
}
}
@Test
public void writeNullCharset() {
DataBuffer buffer = createDataBuffer(1);
try {
buffer.write("test", null);
fail("IllegalArgumentException expected");
}
catch (IllegalArgumentException exc) {
}
finally {
release(buffer);
}
}
@Test
public void writeUtf8String() {
DataBuffer buffer = createDataBuffer(6);
buffer.write("Spring", StandardCharsets.UTF_8);
byte[] result = new byte[6];
buffer.read(result);
assertArrayEquals("Spring".getBytes(StandardCharsets.UTF_8), result);
release(buffer);
}
@Test
public void writeUtf8StringOutGrowsCapacity() {
DataBuffer buffer = createDataBuffer(5);
buffer.write("Spring €", StandardCharsets.UTF_8);
byte[] result = new byte[10];
buffer.read(result);
assertArrayEquals("Spring €".getBytes(StandardCharsets.UTF_8), result);
release(buffer);
}
@Test
public void writeIsoString() {
DataBuffer buffer = createDataBuffer(3);
buffer.write("\u00A3", StandardCharsets.ISO_8859_1);
byte[] result = new byte[1];
buffer.read(result);
assertArrayEquals("\u00A3".getBytes(StandardCharsets.ISO_8859_1), result);
release(buffer);
}
@Test
public void inputStream() throws IOException {
DataBuffer buffer = createDataBuffer(4);

View File

@@ -19,6 +19,7 @@ package org.springframework.core.io.buffer;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.function.IntPredicate;
import org.springframework.util.Assert;
@@ -139,6 +140,11 @@ class LeakAwareDataBuffer implements PooledDataBuffer {
return this.delegate.capacity(newCapacity);
}
@Override
public DataBuffer ensureCapacity(int capacity) {
return this.delegate.ensureCapacity(capacity);
}
@Override
public byte getByte(int index) {
return this.delegate.getByte(index);
@@ -184,6 +190,11 @@ class LeakAwareDataBuffer implements PooledDataBuffer {
return this.delegate.write(byteBuffers);
}
@Override
public DataBuffer write(CharSequence charSequence, Charset charset) {
return this.delegate.write(charSequence, charset);
}
@Override
public DataBuffer slice(int index, int length) {
return this.delegate.slice(index, length);