Author: tilman Date: Thu Feb 25 19:15:41 2021 New Revision: 1886932 URL: http://svn.apache.org/viewvc?rev=1886932&view=rev Log: PDFBOX-5110: improve performance by reading whole segments at once instead of bytes at a time, by Jordi Boixadera
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/digitalsignature/COSFilterInputStream.java Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/digitalsignature/COSFilterInputStream.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/digitalsignature/COSFilterInputStream.java?rev=1886932&r1=1886931&r2=1886932&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/digitalsignature/COSFilterInputStream.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/digitalsignature/COSFilterInputStream.java Thu Feb 25 19:15:41 2021 @@ -21,47 +21,45 @@ import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.pdfbox.io.IOUtils; /** * A filtered stream that includes the bytes that are in the (begin,length) intervals passed in the * constructor. + * + * @author boix_jor + * */ public class COSFilterInputStream extends FilterInputStream { - - /** - * Log instance. - */ - private static final Log LOG = LogFactory.getLog(COSFilterInputStream.class); - - private final int[] byteRange; + private int[][] ranges; + private int range; private long position = 0; public COSFilterInputStream(InputStream in, int[] byteRange) { super(in); - this.byteRange = byteRange; + calculateRanges(byteRange); } public COSFilterInputStream(byte[] in, int[] byteRange) { - super(new ByteArrayInputStream(in)); - this.byteRange = byteRange; + this(new ByteArrayInputStream(in), byteRange); } @Override public int read() throws IOException { - nextAvailable(); - int i = super.read(); - if (i > -1) + if (this.range == -1 || getRemaining() <= 0) { - ++position; + if (!nextRange()) + { + return -1; // EOF + } } - return i; + int result = super.read(); + this.position++; + return result; } @Override @@ -73,65 +71,53 @@ public class COSFilterInputStream extend @Override public int read(byte[] b, int off, int len) throws IOException { - if (len == 0) + if (this.range == -1 || getRemaining() <= 0) { - return 0; - } - - int c = read(); - if (c == -1) - { - return -1; - } - b[off] = (byte) c; - - int i = 1; - try - { - for (; i < len; i++) + if (!nextRange()) { - c = read(); - if (c == -1) - { - break; - } - b[off + i] = (byte) c; + return -1; // EOF } } - catch (IOException ee) - { - LOG.debug("An exception occurred while trying to fill byte[] - ignoring", ee); - } - return i; + int bytesRead = super.read(b, off, (int) Math.min(len, getRemaining())); + this.position += bytesRead; + return bytesRead; } - private boolean inRange() + public byte[] toByteArray() throws IOException { - long pos = position; - for (int i = 0; i < byteRange.length / 2; ++i) + return IOUtils.toByteArray(this); + } + + private void calculateRanges(int[] byteRange) + { + this.ranges = new int[byteRange.length / 2][]; + for (int i = 0; i < byteRange.length / 2; i++) { - if (byteRange[i * 2] <= pos && byteRange[i * 2] + byteRange[i * 2 + 1] > pos) - { - return true; - } + this.ranges[i] = new int[] { byteRange[i * 2], byteRange[i * 2] + byteRange[i * 2 + 1] }; } - return false; + this.range = -1; + } + + private long getRemaining() + { + return this.ranges[this.range][1] - this.position; } - private void nextAvailable() throws IOException + private boolean nextRange() throws IOException { - while (!inRange()) + if (this.ranges.length > this.range + 1) { - ++position; - if (super.read() < 0) + this.range++; + while (this.position < this.ranges[this.range][0]) { - break; + long skipped = super.skip(this.ranges[this.range][0] - this.position); + this.position += skipped; } + return true; + } + else + { + return false; } - } - - public byte[] toByteArray() throws IOException - { - return IOUtils.toByteArray(this); } }