X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fnet%2Fpterodactylus%2Ffcp%2FFcpUtils.java;h=a7859243a4bac01751561f47f8aba959965233e5;hb=5a6f76df163e8fb00a36bb14088cab8f36c94f13;hp=cf8b8d346452cb6a5d9c4c4074593d7c3b1dbd03;hpb=64c2c9bd494f3ea9d1ae84f8d86827dea025bee6;p=jFCPlib.git diff --git a/src/net/pterodactylus/fcp/FcpUtils.java b/src/net/pterodactylus/fcp/FcpUtils.java index cf8b8d3..a785924 100644 --- a/src/net/pterodactylus/fcp/FcpUtils.java +++ b/src/net/pterodactylus/fcp/FcpUtils.java @@ -19,8 +19,13 @@ package net.pterodactylus.fcp; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -31,7 +36,7 @@ import java.util.concurrent.atomic.AtomicLong; /** * Helper class with utility methods for the FCP protocol. * - * @author David Roden + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> */ public class FcpUtils { @@ -77,7 +82,7 @@ public class FcpUtils { */ public static String encodeMultiIntegerField(int[] values) { StringBuilder encodedField = new StringBuilder(); - for (int value: values) { + for (int value : values) { if (encodedField.length() > 0) { encodedField.append(';'); } @@ -96,7 +101,7 @@ public class FcpUtils { */ public static String encodeMultiStringField(String[] values) { StringBuilder encodedField = new StringBuilder(); - for (String value: values) { + for (String value : values) { if (encodedField.length() > 0) { encodedField.append(';'); } @@ -268,4 +273,198 @@ 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); + 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); + } + + } + }