From 80a9a0e629e818a042bb5f222ed96f485b850bd4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sun, 12 Feb 2023 10:36:08 +0100 Subject: [PATCH] =?utf8?q?=E2=99=BB=EF=B8=8F=20Move=20TempInputStream=20to?= =?utf8?q?=20its=20own=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../pterodactylus/fcp/DefaultFcpConnection.java | 2 +- src/main/java/net/pterodactylus/fcp/FcpUtils.java | 194 -------------------- .../net/pterodactylus/fcp/io/TempInputStream.java | 204 +++++++++++++++++++++ .../net/pterodactylus/fcp/TempInputStreamTest.java | 54 ------ .../pterodactylus/fcp/io/TempInputStreamTest.java | 56 ++++++ 5 files changed, 261 insertions(+), 249 deletions(-) create mode 100644 src/main/java/net/pterodactylus/fcp/io/TempInputStream.java delete mode 100644 src/test/java/net/pterodactylus/fcp/TempInputStreamTest.java create mode 100644 src/test/java/net/pterodactylus/fcp/io/TempInputStreamTest.java diff --git a/src/main/java/net/pterodactylus/fcp/DefaultFcpConnection.java b/src/main/java/net/pterodactylus/fcp/DefaultFcpConnection.java index 6890df4..0171678 100644 --- a/src/main/java/net/pterodactylus/fcp/DefaultFcpConnection.java +++ b/src/main/java/net/pterodactylus/fcp/DefaultFcpConnection.java @@ -30,7 +30,7 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -import net.pterodactylus.fcp.FcpUtils.TempInputStream; +import net.pterodactylus.fcp.io.TempInputStream; import static java.nio.charset.StandardCharsets.UTF_8; diff --git a/src/main/java/net/pterodactylus/fcp/FcpUtils.java b/src/main/java/net/pterodactylus/fcp/FcpUtils.java index b83de58..0005f8f 100644 --- a/src/main/java/net/pterodactylus/fcp/FcpUtils.java +++ b/src/main/java/net/pterodactylus/fcp/FcpUtils.java @@ -273,198 +273,4 @@ public class FcpUtils { } } - /** - * This input stream stores the content of another input stream either in a - * file or in memory, depending on the length of the input stream. - * - * @author David ‘Bombe’ Roden <bombe@freenetproject.org> - */ - public static class TempInputStream extends InputStream { - - /** The default maximum lenght for in-memory storage. */ - public static final long MAX_LENGTH_MEMORY = 65536; - - /** The temporary file to read from. */ - private final File tempFile; - - /** The input stream that reads from the file. */ - private final InputStream fileInputStream; - - /** The input stream that reads from memory. */ - private final InputStream memoryInputStream; - - /** - * Creates a new temporary input stream that stores the given input - * stream in a temporary file. - * - * @param originalInputStream - * The original input stream - * @throws IOException - * if an I/O error occurs - */ - public TempInputStream(InputStream originalInputStream) throws IOException { - this(originalInputStream, -1); - } - - /** - * Creates a new temporary input stream that stores the given input - * stream in memory if it is shorter than {@link #MAX_LENGTH_MEMORY}, - * otherwise it is stored in a file. - * - * @param originalInputStream - * The original input stream - * @param length - * The length of the input stream - * @throws IOException - * if an I/O error occurs - */ - public TempInputStream(InputStream originalInputStream, long length) throws IOException { - this(originalInputStream, length, MAX_LENGTH_MEMORY); - } - - /** - * Creates a new temporary input stream that stores the given input - * stream in memory if it is shorter than maxMemoryLength, - * otherwise it is stored in a file. - * - * @param originalInputStream - * The original input stream - * @param length - * The length of the input stream - * @param maxMemoryLength - * The maximum length to store in memory - * @throws IOException - * if an I/O error occurs - */ - public TempInputStream(InputStream originalInputStream, long length, long maxMemoryLength) throws IOException { - if ((length > -1) && (length <= maxMemoryLength)) { - ByteArrayOutputStream memoryOutputStream = new ByteArrayOutputStream((int) length); - try { - FcpUtils.copy(originalInputStream, memoryOutputStream, length, (int) length); - } finally { - memoryOutputStream.close(); - } - tempFile = null; - fileInputStream = null; - memoryInputStream = new ByteArrayInputStream(memoryOutputStream.toByteArray()); - } else { - tempFile = File.createTempFile("temp-", ".bin"); - tempFile.deleteOnExit(); - FileOutputStream fileOutputStream = null; - try { - fileOutputStream = new FileOutputStream(tempFile); - FcpUtils.copy(originalInputStream, fileOutputStream, length); - fileInputStream = new FileInputStream(tempFile); - } finally { - FcpUtils.close(fileOutputStream); - } - memoryInputStream = null; - } - } - - /** - * {@inheritDoc} - */ - @Override - public int available() throws IOException { - if (memoryInputStream != null) { - return memoryInputStream.available(); - } - return fileInputStream.available(); - } - - /** - * {@inheritDoc} - */ - @Override - public void close() throws IOException { - if (memoryInputStream != null) { - memoryInputStream.close(); - return; - } - tempFile.delete(); - fileInputStream.close(); - } - - /** - * {@inheritDoc} - */ - @Override - public synchronized void mark(int readlimit) { - if (memoryInputStream != null) { - memoryInputStream.mark(readlimit); - return; - } - fileInputStream.mark(readlimit); - } - - /** - * {@inheritDoc} - */ - @Override - public boolean markSupported() { - if (memoryInputStream != null) { - return memoryInputStream.markSupported(); - } - return fileInputStream.markSupported(); - } - - /** - * {@inheritDoc} - */ - @Override - public int read() throws IOException { - if (memoryInputStream != null) { - return memoryInputStream.read(); - } - return fileInputStream.read(); - } - - /** - * {@inheritDoc} - */ - @Override - public int read(byte[] b) throws IOException { - if (memoryInputStream != null) { - return memoryInputStream.read(b); - } - return fileInputStream.read(b); - } - - /** - * {@inheritDoc} - */ - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (memoryInputStream != null) { - return memoryInputStream.read(b, off, len); - } - return fileInputStream.read(b, off, len); - } - - /** - * {@inheritDoc} - */ - @Override - public synchronized void reset() throws IOException { - if (memoryInputStream != null) { - memoryInputStream.reset(); - return; - } - fileInputStream.reset(); - } - - /** - * {@inheritDoc} - */ - @Override - public long skip(long n) throws IOException { - if (memoryInputStream != null) { - return memoryInputStream.skip(n); - } - return fileInputStream.skip(n); - } - - } - } diff --git a/src/main/java/net/pterodactylus/fcp/io/TempInputStream.java b/src/main/java/net/pterodactylus/fcp/io/TempInputStream.java new file mode 100644 index 0000000..ab1d31b --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/io/TempInputStream.java @@ -0,0 +1,204 @@ +package net.pterodactylus.fcp.io; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import net.pterodactylus.fcp.FcpUtils; + +/** + * This input stream stores the content of another input stream either in a + * file or in memory, depending on the length of the input stream. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + */ +public class TempInputStream extends InputStream { + + /** + * The default maximum lenght for in-memory storage. + */ + public static final long MAX_LENGTH_MEMORY = 65536; + + /** + * The temporary file to read from. + */ + private final File tempFile; + + /** + * The input stream that reads from the file. + */ + private final InputStream fileInputStream; + + /** + * The input stream that reads from memory. + */ + private final InputStream memoryInputStream; + + /** + * Creates a new temporary input stream that stores the given input + * stream in a temporary file. + * + * @param originalInputStream The original input stream + * @throws IOException if an I/O error occurs + */ + public TempInputStream(InputStream originalInputStream) throws IOException { + this(originalInputStream, -1); + } + + /** + * Creates a new temporary input stream that stores the given input + * stream in memory if it is shorter than {@link #MAX_LENGTH_MEMORY}, + * otherwise it is stored in a file. + * + * @param originalInputStream The original input stream + * @param length The length of the input stream + * @throws IOException if an I/O error occurs + */ + public TempInputStream(InputStream originalInputStream, long length) throws IOException { + this(originalInputStream, length, MAX_LENGTH_MEMORY); + } + + /** + * Creates a new temporary input stream that stores the given input + * stream in memory if it is shorter than maxMemoryLength, + * otherwise it is stored in a file. + * + * @param originalInputStream The original input stream + * @param length The length of the input stream + * @param maxMemoryLength The maximum length to store in memory + * @throws IOException if an I/O error occurs + */ + public TempInputStream(InputStream originalInputStream, long length, long maxMemoryLength) throws IOException { + if ((length > -1) && (length <= maxMemoryLength)) { + ByteArrayOutputStream memoryOutputStream = new ByteArrayOutputStream((int) length); + try { + FcpUtils.copy(originalInputStream, memoryOutputStream, length, (int) length); + } finally { + memoryOutputStream.close(); + } + tempFile = null; + fileInputStream = null; + memoryInputStream = new ByteArrayInputStream(memoryOutputStream.toByteArray()); + } else { + tempFile = File.createTempFile("temp-", ".bin"); + tempFile.deleteOnExit(); + FileOutputStream fileOutputStream = null; + try { + fileOutputStream = new FileOutputStream(tempFile); + FcpUtils.copy(originalInputStream, fileOutputStream, length); + fileInputStream = new FileInputStream(tempFile); + } finally { + FcpUtils.close(fileOutputStream); + } + memoryInputStream = null; + } + } + + /** + * {@inheritDoc} + */ + @Override + public int available() throws IOException { + if (memoryInputStream != null) { + return memoryInputStream.available(); + } + return fileInputStream.available(); + } + + /** + * {@inheritDoc} + */ + @Override + public void close() throws IOException { + if (memoryInputStream != null) { + memoryInputStream.close(); + return; + } + tempFile.delete(); + fileInputStream.close(); + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized void mark(int readlimit) { + if (memoryInputStream != null) { + memoryInputStream.mark(readlimit); + return; + } + fileInputStream.mark(readlimit); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean markSupported() { + if (memoryInputStream != null) { + return memoryInputStream.markSupported(); + } + return fileInputStream.markSupported(); + } + + /** + * {@inheritDoc} + */ + @Override + public int read() throws IOException { + if (memoryInputStream != null) { + return memoryInputStream.read(); + } + return fileInputStream.read(); + } + + /** + * {@inheritDoc} + */ + @Override + public int read(byte[] b) throws IOException { + if (memoryInputStream != null) { + return memoryInputStream.read(b); + } + return fileInputStream.read(b); + } + + /** + * {@inheritDoc} + */ + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (memoryInputStream != null) { + return memoryInputStream.read(b, off, len); + } + return fileInputStream.read(b, off, len); + } + + /** + * {@inheritDoc} + */ + @Override + public synchronized void reset() throws IOException { + if (memoryInputStream != null) { + memoryInputStream.reset(); + return; + } + fileInputStream.reset(); + } + + /** + * {@inheritDoc} + */ + @Override + public long skip(long n) throws IOException { + if (memoryInputStream != null) { + return memoryInputStream.skip(n); + } + return fileInputStream.skip(n); + } + +} diff --git a/src/test/java/net/pterodactylus/fcp/TempInputStreamTest.java b/src/test/java/net/pterodactylus/fcp/TempInputStreamTest.java deleted file mode 100644 index e3f2442..0000000 --- a/src/test/java/net/pterodactylus/fcp/TempInputStreamTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package net.pterodactylus.fcp; - -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertArrayEquals; - - -public class TempInputStreamTest { - - private byte[] prepareArrayOfNBytes(int n) { - byte[] data = new byte[n]; - for (int i = 0; i < n; ++i) { - data[i] = (byte)i; - } - return data; - } - - private void checkTempInputStreamStoresPartOfAnotherStream(int length, int maxMemoryLength) throws IOException { - byte[] originalData = prepareArrayOfNBytes(length + 1); - InputStream anotherStream = new ByteArrayInputStream(originalData); - FcpUtils.TempInputStream cut = new FcpUtils.TempInputStream(anotherStream, length, maxMemoryLength); - - // check length bytes are read from anotherStream and are accessible from cut - byte[] buffer = new byte[length]; - int n = cut.read(buffer); - assertThat(n, is(length)); - assertArrayEquals(Arrays.copyOf(originalData, length), buffer); - assertThat(cut.read(), is(-1)); // check end of cut stream - - // check the rest of data in anotherStream is still there - n = anotherStream.read(buffer); - assertThat(n, is(1)); - assertThat(buffer[0], is(originalData[originalData.length - 1])); - assertThat(anotherStream.read(), is(-1)); // check end of another stream - } - - @Test - public void tempInputStreamShouldCorrectlyStorePartOfAnotherStreamInMemory() throws IOException { - checkTempInputStreamStoresPartOfAnotherStream(1, 1); - } - - @Test - public void tempInputStreamShouldCorrectlyStorePartOfAnotherStreamInFile() throws IOException { - checkTempInputStreamStoresPartOfAnotherStream(2, 1); - } - -} diff --git a/src/test/java/net/pterodactylus/fcp/io/TempInputStreamTest.java b/src/test/java/net/pterodactylus/fcp/io/TempInputStreamTest.java new file mode 100644 index 0000000..1dfac67 --- /dev/null +++ b/src/test/java/net/pterodactylus/fcp/io/TempInputStreamTest.java @@ -0,0 +1,56 @@ +package net.pterodactylus.fcp.io; + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; + +import net.pterodactylus.fcp.io.TempInputStream; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertArrayEquals; + + +public class TempInputStreamTest { + + private byte[] prepareArrayOfNBytes(int n) { + byte[] data = new byte[n]; + for (int i = 0; i < n; ++i) { + data[i] = (byte)i; + } + return data; + } + + private void checkTempInputStreamStoresPartOfAnotherStream(int length, int maxMemoryLength) throws IOException { + byte[] originalData = prepareArrayOfNBytes(length + 1); + InputStream anotherStream = new ByteArrayInputStream(originalData); + TempInputStream cut = new TempInputStream(anotherStream, length, maxMemoryLength); + + // check length bytes are read from anotherStream and are accessible from cut + byte[] buffer = new byte[length]; + int n = cut.read(buffer); + assertThat(n, is(length)); + assertArrayEquals(Arrays.copyOf(originalData, length), buffer); + assertThat(cut.read(), is(-1)); // check end of cut stream + + // check the rest of data in anotherStream is still there + n = anotherStream.read(buffer); + assertThat(n, is(1)); + assertThat(buffer[0], is(originalData[originalData.length - 1])); + assertThat(anotherStream.read(), is(-1)); // check end of another stream + } + + @Test + public void tempInputStreamShouldCorrectlyStorePartOfAnotherStreamInMemory() throws IOException { + checkTempInputStreamStoresPartOfAnotherStream(1, 1); + } + + @Test + public void tempInputStreamShouldCorrectlyStorePartOfAnotherStreamInFile() throws IOException { + checkTempInputStreamStoresPartOfAnotherStream(2, 1); + } + +} -- 2.7.4