Polish FastByteArrayOutputStream[Tests]
See gh-31737
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -33,12 +33,12 @@ import org.springframework.lang.Nullable;
|
|||||||
* its sibling {@link ResizableByteArrayOutputStream}.
|
* its sibling {@link ResizableByteArrayOutputStream}.
|
||||||
*
|
*
|
||||||
* <p>Unlike {@link java.io.ByteArrayOutputStream}, this implementation is backed
|
* <p>Unlike {@link java.io.ByteArrayOutputStream}, this implementation is backed
|
||||||
* by a {@link java.util.ArrayDeque} of {@code byte[]} instead of 1 constantly
|
* by a {@link java.util.ArrayDeque} of {@code byte[]} buffers instead of one
|
||||||
* resizing {@code byte[]}. It does not copy buffers when it gets expanded.
|
* constantly resizing {@code byte[]}. It does not copy buffers when it gets expanded.
|
||||||
*
|
*
|
||||||
* <p>The initial buffer is only created when the stream is first written.
|
* <p>The initial buffer is only created when the stream is first written.
|
||||||
* There is also no copying of the internal buffer if its content is extracted
|
* There is also no copying of the internal buffers if the stream's content is
|
||||||
* with the {@link #writeTo(OutputStream)} method.
|
* extracted via the {@link #writeTo(OutputStream)} method.
|
||||||
*
|
*
|
||||||
* @author Craig Andrews
|
* @author Craig Andrews
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
@@ -72,16 +72,16 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new <code>FastByteArrayOutputStream</code>
|
* Create a new {@code FastByteArrayOutputStream} with the default initial
|
||||||
* with the default initial capacity of 256 bytes.
|
* capacity of 256 bytes.
|
||||||
*/
|
*/
|
||||||
public FastByteArrayOutputStream() {
|
public FastByteArrayOutputStream() {
|
||||||
this(DEFAULT_BLOCK_SIZE);
|
this(DEFAULT_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new <code>FastByteArrayOutputStream</code>
|
* Create a new {@code FastByteArrayOutputStream} with the specified initial
|
||||||
* with the specified initial capacity.
|
* capacity.
|
||||||
* @param initialBlockSize the initial buffer size in bytes
|
* @param initialBlockSize the initial buffer size in bytes
|
||||||
*/
|
*/
|
||||||
public FastByteArrayOutputStream(int initialBlockSize) {
|
public FastByteArrayOutputStream(int initialBlockSize) {
|
||||||
@@ -150,16 +150,17 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the buffer's contents into a string decoding bytes using the
|
* Convert this stream's contents to a string by decoding the bytes using the
|
||||||
* platform's default character set. The length of the new {@code String}
|
* platform's default character set. The length of the new {@code String}
|
||||||
* is a function of the character set, and hence may not be equal to the
|
* is a function of the character set, and hence may not be equal to the
|
||||||
* size of the buffer.
|
* size of the buffers.
|
||||||
* <p>This method always replaces malformed-input and unmappable-character
|
* <p>This method always replaces malformed-input and unmappable-character
|
||||||
* sequences with the default replacement string for the platform's
|
* sequences with the default replacement string for the platform's
|
||||||
* default character set. The {@linkplain java.nio.charset.CharsetDecoder}
|
* default character set. The {@linkplain java.nio.charset.CharsetDecoder}
|
||||||
* class should be used when more control over the decoding process is
|
* class should be used when more control over the decoding process is
|
||||||
* required.
|
* required.
|
||||||
* @return a String decoded from the buffer's contents
|
* @return a String decoded from this stream's contents
|
||||||
|
* @see #toString(Charset)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
@@ -167,19 +168,19 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the buffer's contents into a string by decoding the bytes using
|
* Convert this stream's contents to a string by decoding the bytes using the
|
||||||
* the specified {@link java.nio.charset.Charset charset}.
|
* specified {@link Charset}.
|
||||||
*
|
* @param charset the {@link Charset} to use to decode the bytes
|
||||||
* @param charset the {@linkplain java.nio.charset.Charset charset}
|
* @return a String decoded from this stream's contents
|
||||||
* to be used to decode the {@code bytes}
|
* @since 6.1.2
|
||||||
* @return a String decoded from the buffer's contents
|
* @see #toString()
|
||||||
*/
|
*/
|
||||||
public String toString(Charset charset) {
|
public String toString(Charset charset) {
|
||||||
if (size() == 0) {
|
if (size() == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
if (buffers.size() == 1) {
|
if (this.buffers.size() == 1) {
|
||||||
return new String(buffers.getFirst(), 0, index, charset);
|
return new String(this.buffers.getFirst(), 0, this.index, charset);
|
||||||
}
|
}
|
||||||
return new String(toByteArrayUnsafe(), charset);
|
return new String(toByteArrayUnsafe(), charset);
|
||||||
}
|
}
|
||||||
@@ -187,14 +188,14 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||||||
// Custom methods
|
// Custom methods
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the number of bytes stored in this <code>FastByteArrayOutputStream</code>.
|
* Return the number of bytes stored in this {@code FastByteArrayOutputStream}.
|
||||||
*/
|
*/
|
||||||
public int size() {
|
public int size() {
|
||||||
return (this.alreadyBufferedSize + this.index);
|
return (this.alreadyBufferedSize + this.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the stream's data to a byte array and return the byte array.
|
* Convert this stream's contents to a byte array and return the byte array.
|
||||||
* <p>Also replaces the internal structures with the byte array to
|
* <p>Also replaces the internal structures with the byte array to
|
||||||
* conserve memory: if the byte array is being created anyway, we might
|
* conserve memory: if the byte array is being created anyway, we might
|
||||||
* as well as use it. This approach also means that if this method is
|
* as well as use it. This approach also means that if this method is
|
||||||
@@ -202,7 +203,7 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||||||
* a no-op.
|
* a no-op.
|
||||||
* <p>This method is "unsafe" as it returns the internal buffer.
|
* <p>This method is "unsafe" as it returns the internal buffer.
|
||||||
* Callers should not modify the returned buffer.
|
* Callers should not modify the returned buffer.
|
||||||
* @return the current contents of this output stream, as a byte array.
|
* @return the current contents of this stream as a byte array
|
||||||
* @see #size()
|
* @see #size()
|
||||||
* @see #toByteArray()
|
* @see #toByteArray()
|
||||||
*/
|
*/
|
||||||
@@ -218,8 +219,8 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||||||
/**
|
/**
|
||||||
* Create a newly allocated byte array.
|
* Create a newly allocated byte array.
|
||||||
* <p>Its size is the current size of this output stream, and it will
|
* <p>Its size is the current size of this output stream, and it will
|
||||||
* contain the valid contents of the internal buffer.
|
* contain the valid contents of the internal buffers.
|
||||||
* @return the current contents of this output stream, as a byte array
|
* @return the current contents of this stream as a byte array
|
||||||
* @see #size()
|
* @see #size()
|
||||||
* @see #toByteArrayUnsafe()
|
* @see #toByteArrayUnsafe()
|
||||||
*/
|
*/
|
||||||
@@ -229,7 +230,7 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the contents of this <code>FastByteArrayOutputStream</code>.
|
* Reset the contents of this {@code FastByteArrayOutputStream}.
|
||||||
* <p>All currently accumulated output in the output stream is discarded.
|
* <p>All currently accumulated output in the output stream is discarded.
|
||||||
* The output stream can be used again.
|
* The output stream can be used again.
|
||||||
*/
|
*/
|
||||||
@@ -242,19 +243,21 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an {@link InputStream} to retrieve the data in this OutputStream.
|
* Get an {@link InputStream} to retrieve the contents of this
|
||||||
* <p>Note that if any methods are called on the OutputStream
|
* {@code FastByteArrayOutputStream}.
|
||||||
|
* <p>Note that if any methods are called on this {@code FastByteArrayOutputStream}
|
||||||
* (including, but not limited to, any of the write methods, {@link #reset()},
|
* (including, but not limited to, any of the write methods, {@link #reset()},
|
||||||
* {@link #toByteArray()}, and {@link #toByteArrayUnsafe()}) then the
|
* {@link #toByteArray()}, and {@link #toByteArrayUnsafe()}) then the
|
||||||
* {@link java.io.InputStream}'s behavior is undefined.
|
* {@code InputStream}'s behavior is undefined.
|
||||||
* @return {@link InputStream} of the contents of this OutputStream
|
* @return {@code InputStream} of the contents of this {@code FastByteArrayOutputStream}
|
||||||
*/
|
*/
|
||||||
public InputStream getInputStream() {
|
public InputStream getInputStream() {
|
||||||
return new FastByteArrayInputStream(this);
|
return new FastByteArrayInputStream(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the buffers content to the given OutputStream.
|
* Write the contents of this {@code FastByteArrayOutputStream} to the given
|
||||||
|
* {@link OutputStream}.
|
||||||
* @param out the OutputStream to write to
|
* @param out the OutputStream to write to
|
||||||
*/
|
*/
|
||||||
public void writeTo(OutputStream out) throws IOException {
|
public void writeTo(OutputStream out) throws IOException {
|
||||||
@@ -271,7 +274,7 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resize the internal buffer size to a specified capacity.
|
* Resize the internal buffer size to the specified capacity.
|
||||||
* @param targetCapacity the desired size of the buffer
|
* @param targetCapacity the desired size of the buffer
|
||||||
* @throws IllegalArgumentException if the given capacity is smaller than
|
* @throws IllegalArgumentException if the given capacity is smaller than
|
||||||
* the actual size of the content stored in the buffer already
|
* the actual size of the content stored in the buffer already
|
||||||
@@ -340,7 +343,7 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of {@link java.io.InputStream} that reads from a given
|
* An implementation of {@link java.io.InputStream} that reads from a given
|
||||||
* <code>FastByteArrayOutputStream</code>.
|
* {@code FastByteArrayOutputStream}.
|
||||||
*/
|
*/
|
||||||
private static final class FastByteArrayInputStream extends UpdateMessageDigestInputStream {
|
private static final class FastByteArrayInputStream extends UpdateMessageDigestInputStream {
|
||||||
|
|
||||||
@@ -358,8 +361,8 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||||||
private int totalBytesRead = 0;
|
private int totalBytesRead = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new <code>FastByteArrayOutputStreamInputStream</code> backed
|
* Create a new {@code FastByteArrayInputStream} backed by the given
|
||||||
* by the given <code>FastByteArrayOutputStream</code>.
|
* {@code FastByteArrayOutputStream}.
|
||||||
*/
|
*/
|
||||||
public FastByteArrayInputStream(FastByteArrayOutputStream fastByteArrayOutputStream) {
|
public FastByteArrayInputStream(FastByteArrayOutputStream fastByteArrayOutputStream) {
|
||||||
this.fastByteArrayOutputStream = fastByteArrayOutputStream;
|
this.fastByteArrayOutputStream = fastByteArrayOutputStream;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -29,15 +29,13 @@ import static org.assertj.core.api.Assertions.assertThatIOException;
|
|||||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test suite for {@link FastByteArrayOutputStream}.
|
* Tests for {@link FastByteArrayOutputStream}.
|
||||||
*
|
*
|
||||||
* @author Craig Andrews
|
* @author Craig Andrews
|
||||||
*/
|
*/
|
||||||
class FastByteArrayOutputStreamTests {
|
class FastByteArrayOutputStreamTests {
|
||||||
|
|
||||||
private static final int INITIAL_CAPACITY = 256;
|
private final FastByteArrayOutputStream os = new FastByteArrayOutputStream();
|
||||||
|
|
||||||
private final FastByteArrayOutputStream os = new FastByteArrayOutputStream(INITIAL_CAPACITY);
|
|
||||||
|
|
||||||
private final byte[] helloBytes = "Hello World".getBytes(StandardCharsets.UTF_8);
|
private final byte[] helloBytes = "Hello World".getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
@@ -63,16 +61,18 @@ class FastByteArrayOutputStreamTests {
|
|||||||
assertThat(this.os.toString()).isEqualTo("Hello World");
|
assertThat(this.os.toString()).isEqualTo("Hello World");
|
||||||
assertThat(this.os.toString(StandardCharsets.UTF_8)).isEqualTo("Hello World");
|
assertThat(this.os.toString(StandardCharsets.UTF_8)).isEqualTo("Hello World");
|
||||||
|
|
||||||
|
@SuppressWarnings("resource")
|
||||||
FastByteArrayOutputStream empty = new FastByteArrayOutputStream();
|
FastByteArrayOutputStream empty = new FastByteArrayOutputStream();
|
||||||
assertThat(empty.toString()).isEqualTo("");
|
assertThat(empty.toString()).isEqualTo("");
|
||||||
assertThat(empty.toString(StandardCharsets.US_ASCII)).isEqualTo("");
|
assertThat(empty.toString(StandardCharsets.US_ASCII)).isEqualTo("");
|
||||||
|
|
||||||
|
@SuppressWarnings("resource")
|
||||||
FastByteArrayOutputStream outputStream = new FastByteArrayOutputStream(5);
|
FastByteArrayOutputStream outputStream = new FastByteArrayOutputStream(5);
|
||||||
// Add bytes in multiple writes to ensure we get more than one buffer internally
|
// Add bytes in multiple writes to ensure we get more than one buffer internally
|
||||||
outputStream.write(this.helloBytes, 0, 5);
|
outputStream.write(this.helloBytes, 0, 5);
|
||||||
outputStream.write(this.helloBytes, 5, 6);
|
outputStream.write(this.helloBytes, 5, 6);
|
||||||
assertThat(outputStream.toString(StandardCharsets.UTF_8)).isEqualTo("Hello World");
|
|
||||||
assertThat(outputStream.toString()).isEqualTo("Hello World");
|
assertThat(outputStream.toString()).isEqualTo("Hello World");
|
||||||
|
assertThat(outputStream.toString(StandardCharsets.UTF_8)).isEqualTo("Hello World");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -102,10 +102,9 @@ class FastByteArrayOutputStreamTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void close() throws Exception {
|
void close() {
|
||||||
this.os.close();
|
this.os.close();
|
||||||
assertThatIOException().isThrownBy(() ->
|
assertThatIOException().isThrownBy(() -> this.os.write(this.helloBytes));
|
||||||
this.os.write(this.helloBytes));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -128,8 +127,9 @@ class FastByteArrayOutputStreamTests {
|
|||||||
@Test
|
@Test
|
||||||
void failResize() throws Exception {
|
void failResize() throws Exception {
|
||||||
this.os.write(this.helloBytes);
|
this.os.write(this.helloBytes);
|
||||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
assertThatIllegalArgumentException()
|
||||||
this.os.resize(5));
|
.isThrownBy(() -> this.os.resize(5))
|
||||||
|
.withMessage("New capacity must not be smaller than current size");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -156,7 +156,7 @@ class FastByteArrayOutputStreamTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void getInputStreamReadBytePromotion() throws Exception {
|
void getInputStreamReadBytePromotion() throws Exception {
|
||||||
byte[] bytes = new byte[] { -1 };
|
byte[] bytes = { -1 };
|
||||||
this.os.write(bytes);
|
this.os.write(bytes);
|
||||||
InputStream inputStream = this.os.getInputStream();
|
InputStream inputStream = this.os.getInputStream();
|
||||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||||
|
|||||||
Reference in New Issue
Block a user