From 8b8d32e4960f456c202286df2ce6971b65590c39 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Mon, 18 Dec 2017 22:23:42 +0000 Subject: [PATCH] Util: LookaheadInputStream speedups and cleanups --- .../net/i2p/util/LookaheadInputStream.java | 74 ++++++++++++------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/core/java/src/net/i2p/util/LookaheadInputStream.java b/core/java/src/net/i2p/util/LookaheadInputStream.java index 67d48e87ad..cb5b5ca5ca 100644 --- a/core/java/src/net/i2p/util/LookaheadInputStream.java +++ b/core/java/src/net/i2p/util/LookaheadInputStream.java @@ -6,15 +6,19 @@ import java.io.IOException; import java.io.InputStream; import java.util.Arrays; +import net.i2p.data.DataHelper; + /** * Simple lookahead buffer to keep the last K bytes in reserve, * configured to easily be reused. Currently only used by the - * ResettableGZIPInputStream - * + * ResettableGZIPInputStream. */ public class LookaheadInputStream extends FilterInputStream { private boolean _eofReached; private final byte[] _footerLookahead; + private final int size; + // Next byte to read. + private int index; private static final InputStream _fakeInputStream = new ByteArrayInputStream(new byte[0]); /** @@ -29,6 +33,7 @@ public class LookaheadInputStream extends FilterInputStream { public LookaheadInputStream(int lookaheadSize) { super(_fakeInputStream); _footerLookahead = new byte[lookaheadSize]; + size = lookaheadSize; } public boolean getEOFReached() { return _eofReached; } @@ -37,41 +42,33 @@ public class LookaheadInputStream extends FilterInputStream { * Start the LookaheadInputStream with the given input stream. * Resets everything if the LookaheadInputStream was previously used. * WARNING - blocking until lookaheadSize bytes are read! + * + * @throws IOException if less than lookaheadSize bytes could be read. */ public void initialize(InputStream src) throws IOException { in = src; _eofReached = false; - Arrays.fill(_footerLookahead, (byte)0x00); - int footerRead = 0; - while (footerRead < _footerLookahead.length) { - int read = in.read(_footerLookahead, footerRead, _footerLookahead.length - footerRead); - if (read == -1) throw new IOException("EOF reading the footer lookahead"); - footerRead += read; - } + index = 0; + DataHelper.read(in, _footerLookahead); } @Override public int read() throws IOException { if (_eofReached) - return -1; //throw new IOException("Already past the EOF"); + return -1; int c = in.read(); if (c == -1) { _eofReached = true; return -1; } - int rv = _footerLookahead[0]; - // FIXME use an index!!!!!!!!!!!! - System.arraycopy(_footerLookahead, 1, _footerLookahead, 0, _footerLookahead.length-1); - _footerLookahead[_footerLookahead.length-1] = (byte)c; - if (rv < 0) rv += 256; + int rv = _footerLookahead[index] & 0xff; + _footerLookahead[index] = (byte)c; + index++; + if (index >= size) + index = 0; return rv; } - @Override - public int read(byte buf[]) throws IOException { - return read(buf, 0, buf.length); - } - @Override public int read(byte buf[], int off, int len) throws IOException { if (_eofReached) @@ -90,8 +87,32 @@ public class LookaheadInputStream extends FilterInputStream { return len; } - /** grab the lookahead footer */ - public byte[] getFooter() { return _footerLookahead; } + /** + * Grab the lookahead footer. + * This will be of size lookaheadsize given in constructor. + * The last byte received will be in the last byte of the array. + */ + public byte[] getFooter() { + if (index == 0) + return _footerLookahead; + byte[] rv = new byte[size]; + System.arraycopy(_footerLookahead, index, rv, 0, size - index); + System.arraycopy(_footerLookahead, 0, rv, size - index, index); + return rv; + } + + /** + * @since 0.9.33 + */ + @Override + public long skip(long n) throws IOException { + long rv = 0; + int c; + while (rv < n && (c = read()) >= 0) { + rv++; + } + return rv; + } /******* public static void main(String args[]) { @@ -111,14 +132,17 @@ public class LookaheadInputStream extends FilterInputStream { for (int i = 0; i < 8; i++) if (lis.getFooter()[i] != (byte)(i+24)) throw new RuntimeException("Error at footer " + i + " [" + lis.getFooter()[i] + "]"); - System.out.println("Everything is fine in general"); } catch (Exception e) { e.printStackTrace(); } for (int i = 9; i < 32*1024; i++) { - if (!test(i)) break; + if (!test(i)) { + System.out.println("Everything is NOT fine at size=" + i); + break; + } } + System.out.println("Everything is fine in general"); } private static boolean test(int size) { @@ -137,7 +161,7 @@ public class LookaheadInputStream extends FilterInputStream { for (int i = 0; i < 8; i++) if (lis.getFooter()[i] != buf[i+(size-8)]) throw new RuntimeException("Error at footer " + i + " [" + lis.getFooter()[i] + "]"); - System.out.println("Everything is fine at size=" + size); + //System.out.println("Everything is fine at size=" + size); return true; } catch (Exception e) { e.printStackTrace(); -- GitLab