This is an automated email from the ASF dual-hosted git repository. britter pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-io.git
The following commit(s) were added to refs/heads/master by this push: new f15433d Fix broken build (#73) f15433d is described below commit f15433d69c96aec08c9a0c3c15a69edd8250ae2b Author: Benedikt Ritter <benerit...@gmail.com> AuthorDate: Sun Feb 17 11:21:55 2019 +0100 Fix broken build (#73) Several things were broken with the build. This fixes build failures and makes the build pass again on all Java versions tested on Travis CI. 1. The test started to fail after the changes made in b5990be. This is because after changing the type of writer from Appendable to NullWriter the wrong overload of copy would be used: copy(Reader, Writer) instead of copy(Reader, Appendable) This change just forces the right overload at the call site. 2. Replace tabs with spaces 3. Add missing package-info file 4. Fix NPE during javadoc generation Commons parent 46 shipped with maven-javadoc-plugin 3.0.0 which was affected by https://issues.apache.org/jira/browse/MJAVADOC-517. This upgrades the build to commons parent 47, which includes maven-javadoc-plugin 3.0.1. 5. Fix invalid javadoc links 6. Fix problem with Javadoc tool reporting import of unnamed modules --- pom.xml | 14 +- .../org/apache/commons/io/DirectoryWalker.java | 25 +- .../input/MessageDigestCalculatingInputStream.java | 6 +- .../io/input/buffer/CircularBufferInputStream.java | 189 ++++----- .../io/input/buffer/CircularByteBuffer.java | 421 +++++++++++---------- .../io/input/buffer/PeekableInputStream.java | 119 +++--- .../commons/io/input/buffer/package-info.java | 17 + .../org/apache/commons/io/IOUtilsCopyTestCase.java | 2 +- 8 files changed, 424 insertions(+), 369 deletions(-) diff --git a/pom.xml b/pom.xml index 55c9e5b..869112e 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ <parent> <groupId>org.apache.commons</groupId> <artifactId>commons-parent</artifactId> - <version>46</version> + <version>47</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>commons-io</groupId> @@ -350,6 +350,18 @@ file comparators, endian transformation classes, and much more. </ignorePathsToDelete> </configuration> </plugin> + <!-- + Fix for https://bugs.openjdk.java.net/browse/JDK-8212233 + which is addressed in maven-javadoc-plugin:3.1.0, see https://issues.apache.org/jira/browse/MJAVADOC-562 + --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>${commons.javadoc.version}</version> + <configuration> + <source>7</source> + </configuration> + </plugin> </plugins> </build> diff --git a/src/main/java/org/apache/commons/io/DirectoryWalker.java b/src/main/java/org/apache/commons/io/DirectoryWalker.java index 8e5a63d..a897c38 100644 --- a/src/main/java/org/apache/commons/io/DirectoryWalker.java +++ b/src/main/java/org/apache/commons/io/DirectoryWalker.java @@ -36,16 +36,15 @@ import org.apache.commons.io.filefilter.TrueFileFilter; * <p> * The following sections describe: * <ul> - * <li><a href="#DirectoryWalker_example">1. Example Implementation</a> - example + * <li><a href="#example">1. Example Implementation</a> - example * <code>FileCleaner</code> implementation.</li> - * <li><a href="#DirectoryWalker_filter">2. Filter Example</a> - using + * <li><a href="#filter">2. Filter Example</a> - using * {@link FileFilter}(s) with <code>DirectoryWalker</code>.</li> - * <li><a href="#DirectoryWalker_cancel">3. Cancellation</a> - how to implement cancellation + * <li><a href="#cancel">3. Cancellation</a> - how to implement cancellation * behaviour.</li> * </ul> * - * <a id="DirectoryWalker_example"></a> - * <h3>1. Example Implementation</h3> + * <h3 id="example">1. Example Implementation</h3> * * There are many possible extensions, for example, to delete all * files and '.svn' directories, and return a list of deleted files: @@ -81,8 +80,7 @@ import org.apache.commons.io.filefilter.TrueFileFilter; * } * </pre> * - * <a id="DirectoryWalker_filter"></a> - * <h3>2. Filter Example</h3> + * <h3 id="filter">2. Filter Example</h3> * * Choosing which directories and files to process can be a key aspect * of using this class. This information can be setup in three ways, @@ -148,8 +146,7 @@ import org.apache.commons.io.filefilter.TrueFileFilter; * This is much simpler than the previous example, and is why it is the preferred * option for filtering. * - * <a id="DirectoryWalker_cancel"></a> - * <h3>3. Cancellation</h3> + * <h3 id="cancel">3. Cancellation</h3> * * The DirectoryWalker contains some of the logic required for cancel processing. * Subclasses must complete the implementation. @@ -172,17 +169,16 @@ import org.apache.commons.io.filefilter.TrueFileFilter; * <p> * Two possible scenarios are envisaged for cancellation: * <ul> - * <li><a href="#DirectoryWalker_external">3.1 External / Multi-threaded</a> - cancellation being + * <li><a href="#external">3.1 External / Multi-threaded</a> - cancellation being * decided/initiated by an external process.</li> - * <li><a href="#DirectoryWalker_internal">3.2 Internal</a> - cancellation being decided/initiated + * <li><a href="#internal">3.2 Internal</a> - cancellation being decided/initiated * from within a DirectoryWalker implementation.</li> * </ul> * <p> * The following sections provide example implementations for these two different * scenarios. * - * <a id="DirectoryWalker_external"></a> - * <h4>3.1 External / Multi-threaded</h4> + * <h4 id="external">3.1 External / Multi-threaded</h4> * * This example provides a public <code>cancel()</code> method that can be * called by another thread to stop the processing. A typical example use-case @@ -213,8 +209,7 @@ import org.apache.commons.io.filefilter.TrueFileFilter; * } * </pre> * - * <a id="DirectoryWalker_internal"></a> - * <h4>3.2 Internal</h4> + * <h4 id="internal">3.2 Internal</h4> * * This shows an example of how internal cancellation processing could be implemented. * <b>Note</b> the decision logic and throwing a {@link CancelException} could be implemented diff --git a/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java b/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java index 257adce..6d57dad 100644 --- a/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java +++ b/src/main/java/org/apache/commons/io/input/MessageDigestCalculatingInputStream.java @@ -46,14 +46,12 @@ public class MessageDigestCalculatingInputStream extends ObservableInputStream { } @Override - public - void data(final int pByte) throws IOException { + public void data(final int pByte) throws IOException { md.update((byte) pByte); } @Override - public - void data(final byte[] pBuffer, final int pOffset, final int pLength) throws IOException { + public void data(final byte[] pBuffer, final int pOffset, final int pLength) throws IOException { md.update(pBuffer, pOffset, pLength); } } diff --git a/src/main/java/org/apache/commons/io/input/buffer/CircularBufferInputStream.java b/src/main/java/org/apache/commons/io/input/buffer/CircularBufferInputStream.java index 20be218..8d20de1 100644 --- a/src/main/java/org/apache/commons/io/input/buffer/CircularBufferInputStream.java +++ b/src/main/java/org/apache/commons/io/input/buffer/CircularBufferInputStream.java @@ -16,7 +16,6 @@ */ package org.apache.commons.io.input.buffer; -import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Objects; @@ -24,101 +23,117 @@ import java.util.Objects; /** * Implementation of a buffered input stream, which is internally based on the - * {@link CircularByteBuffer}. Unlike the {@link BufferedInputStream}, this one + * {@link CircularByteBuffer}. Unlike the {@link java.io.BufferedInputStream}, this one * doesn't need to reallocate byte arrays internally. */ public class CircularBufferInputStream extends InputStream { - protected final InputStream in; - protected final CircularByteBuffer buffer; - protected final int bufferSize; - private boolean eofSeen; + protected final InputStream in; + protected final CircularByteBuffer buffer; + protected final int bufferSize; + private boolean eofSeen; - /** Creates a new instance, which filters the given input stream, and - * uses the given buffer size. - * @param pIn The input stream, which is being buffered. - * @param pBufferSize The size of the {@link CircularByteBuffer}, which is - * used internally. - */ - public CircularBufferInputStream(InputStream pIn, int pBufferSize) { - Objects.requireNonNull(pIn, "InputStream"); - if (pBufferSize <= 0) { - throw new IllegalArgumentException("Invalid buffer size: " + pBufferSize); - } - in = pIn; - buffer = new CircularByteBuffer(pBufferSize); - bufferSize = pBufferSize; - eofSeen = false; - } + /** + * Creates a new instance, which filters the given input stream, and + * uses the given buffer size. + * + * @param pIn The input stream, which is being buffered. + * @param pBufferSize The size of the {@link CircularByteBuffer}, which is + * used internally. + */ + public CircularBufferInputStream(InputStream pIn, int pBufferSize) { + Objects.requireNonNull(pIn, "InputStream"); + if (pBufferSize <= 0) { + throw new IllegalArgumentException("Invalid buffer size: " + pBufferSize); + } + in = pIn; + buffer = new CircularByteBuffer(pBufferSize); + bufferSize = pBufferSize; + eofSeen = false; + } - /** Creates a new instance, which filters the given input stream, and - * uses a reasonable default buffer size (8192). - * @param pIn The input stream, which is being buffered. - */ - public CircularBufferInputStream(InputStream pIn) { - this(pIn, 8192); - } + /** + * Creates a new instance, which filters the given input stream, and + * uses a reasonable default buffer size (8192). + * + * @param pIn The input stream, which is being buffered. + */ + public CircularBufferInputStream(InputStream pIn) { + this(pIn, 8192); + } - protected void fillBuffer() throws IOException { - if (eofSeen) { - return; - } - int space = buffer.getSpace(); - final byte[] buf = new byte[space]; - while (space > 0) { - final int res = in.read(buf, 0, space); - if (res == -1) { - eofSeen = true; - return; - } else if (res > 0) { - buffer.add(buf, 0, res); - space -= res; - } - } - } + /** + * Fills the buffer with the contents of the input stream. + * + * @throws IOException in case of an error while reading from the input stream. + */ + protected void fillBuffer() throws IOException { + if (eofSeen) { + return; + } + int space = buffer.getSpace(); + final byte[] buf = new byte[space]; + while (space > 0) { + final int res = in.read(buf, 0, space); + if (res == -1) { + eofSeen = true; + return; + } else if (res > 0) { + buffer.add(buf, 0, res); + space -= res; + } + } + } - protected boolean haveBytes(int pNumber) throws IOException { - if (buffer.getCurrentNumberOfBytes() < pNumber) { - fillBuffer(); - } - return buffer.hasBytes(); - } + /** + * Fills the buffer from the input stream until the given number of bytes have been added to the buffer. + * + * @param pNumber number of byte to fill into the buffer + * @return true if the buffer has bytes + * @throws IOException in case of an error while reading from the input stream. + */ + protected boolean haveBytes(int pNumber) throws IOException { + if (buffer.getCurrentNumberOfBytes() < pNumber) { + fillBuffer(); + } + return buffer.hasBytes(); + } - @Override - public int read() throws IOException { - if (!haveBytes(1)) { - return -1; - } - return buffer.read(); - } + @Override + public int read() throws IOException { + if (!haveBytes(1)) { + return -1; + } + return buffer.read(); + } - @Override - public int read(byte[] pBuffer) throws IOException { - return read(pBuffer, 0, pBuffer.length); - } + @Override + public int read(byte[] pBuffer) throws IOException { + return read(pBuffer, 0, pBuffer.length); + } - @Override - public int read(byte[] pBuffer, int pOffset, int pLength) throws IOException { - Objects.requireNonNull(pBuffer, "Buffer"); - if (pOffset < 0) { - throw new IllegalArgumentException("Offset must not be negative"); - } - if (pLength < 0) { - throw new IllegalArgumentException("Length must not be negative"); - } - if (!haveBytes(pLength)) { - return -1; - } - final int result = Math.min(pLength, buffer.getCurrentNumberOfBytes()); - for (int i = 0; i < result; i++) { - pBuffer[pOffset+i] = buffer.read(); - } - return result; - } + @Override + public int read(byte[] pBuffer, int pOffset, int pLength) throws IOException { + Objects.requireNonNull(pBuffer, "Buffer"); + if (pOffset < 0) { + throw new IllegalArgumentException("Offset must not be negative"); + } + if (pLength < 0) { + throw new IllegalArgumentException("Length must not be negative"); + } + if (!haveBytes(pLength)) { + return -1; + } + final int result = Math.min(pLength, buffer.getCurrentNumberOfBytes()); + for (int i = 0; i < result; i++) { + pBuffer[pOffset + i] = buffer.read(); + } + return result; + } - @Override - public void close() throws IOException { - in.close(); - eofSeen = true; - buffer.clear(); - } + @Override + public void close() throws IOException { + in.close(); + eofSeen = true; + buffer.clear(); + } } diff --git a/src/main/java/org/apache/commons/io/input/buffer/CircularByteBuffer.java b/src/main/java/org/apache/commons/io/input/buffer/CircularByteBuffer.java index 8fb82d3..95ca142 100644 --- a/src/main/java/org/apache/commons/io/input/buffer/CircularByteBuffer.java +++ b/src/main/java/org/apache/commons/io/input/buffer/CircularByteBuffer.java @@ -26,225 +26,236 @@ import java.util.Objects; * like the {@link CircularBufferInputStream}. */ public class CircularByteBuffer { - private final byte[] buffer; - private int startOffset, endOffset, currentNumberOfBytes; + private final byte[] buffer; + private int startOffset, endOffset, currentNumberOfBytes; - /** - * Creates a new instance with the given buffer size. - * @param pSize the size of buffer to create - */ - public CircularByteBuffer(int pSize) { - buffer = new byte[pSize]; - startOffset = 0; - endOffset = 0; - currentNumberOfBytes = 0; - } + /** + * Creates a new instance with the given buffer size. + * + * @param pSize the size of buffer to create + */ + public CircularByteBuffer(int pSize) { + buffer = new byte[pSize]; + startOffset = 0; + endOffset = 0; + currentNumberOfBytes = 0; + } - /** - * Creates a new instance with a reasonable default buffer size (8192). - */ - public CircularByteBuffer() { - this(8192); - } + /** + * Creates a new instance with a reasonable default buffer size (8192). + */ + public CircularByteBuffer() { + this(8192); + } - /** - * Returns the next byte from the buffer, removing it at the same time, so - * that following invocations won't return it again. - * @return The byte, which is being returned. - * @throws IllegalStateException The buffer is empty. Use {@link #hasBytes()}, - * or {@link #getCurrentNumberOfBytes()}, to prevent this exception. - */ - public byte read() { - if (currentNumberOfBytes <= 0) { - throw new IllegalStateException("No bytes available."); - } - final byte b = buffer[startOffset]; - --currentNumberOfBytes; - if (++startOffset == buffer.length) { - startOffset = 0; - } - return b; - } + /** + * Returns the next byte from the buffer, removing it at the same time, so + * that following invocations won't return it again. + * + * @return The byte, which is being returned. + * @throws IllegalStateException The buffer is empty. Use {@link #hasBytes()}, + * or {@link #getCurrentNumberOfBytes()}, to prevent this exception. + */ + public byte read() { + if (currentNumberOfBytes <= 0) { + throw new IllegalStateException("No bytes available."); + } + final byte b = buffer[startOffset]; + --currentNumberOfBytes; + if (++startOffset == buffer.length) { + startOffset = 0; + } + return b; + } - /** - * Returns the given number of bytes from the buffer by storing them in - * the given byte array at the given offset. - * @param pBuffer The byte array, where to add bytes. - * @param pOffset The offset, where to store bytes in the byte array. - * @param pLength The number of bytes to return. - * @throws NullPointerException The byte array {@code pBuffer} is null. - * @throws IllegalArgumentException Either of {@code pOffset}, or {@code pLength} is negative, - * or the length of the byte array {@code pBuffer} is too small. - * @throws IllegalStateException The buffer doesn't hold the given number - * of bytes. Use {@link #getCurrentNumberOfBytes()} to prevent this - * exception. - */ - public void read(byte[] pBuffer, int pOffset, int pLength) { - Objects.requireNonNull(pBuffer); - if (pOffset < 0 || pOffset >= pBuffer.length) { - throw new IllegalArgumentException("Invalid offset: " + pOffset); - } - if (pLength < 0 || pLength > buffer.length) { - throw new IllegalArgumentException("Invalid length: " + pLength); - } - if (pOffset+pLength > pBuffer.length) { - throw new IllegalArgumentException("The supplied byte array contains only " - + pBuffer.length + " bytes, but offset, and length would require " - + (pOffset+pLength-1)); - } - if (currentNumberOfBytes < pLength) { - throw new IllegalStateException("Currently, there are only " + currentNumberOfBytes - + "in the buffer, not " + pLength); - } - int offset = pOffset; - for (int i = 0; i < pLength; i++) { - pBuffer[offset++] = buffer[startOffset]; - --currentNumberOfBytes; - if (++startOffset == buffer.length) { - startOffset = 0; - } - } - } + /** + * Returns the given number of bytes from the buffer by storing them in + * the given byte array at the given offset. + * + * @param pBuffer The byte array, where to add bytes. + * @param pOffset The offset, where to store bytes in the byte array. + * @param pLength The number of bytes to return. + * @throws NullPointerException The byte array {@code pBuffer} is null. + * @throws IllegalArgumentException Either of {@code pOffset}, or {@code pLength} is negative, + * or the length of the byte array {@code pBuffer} is too small. + * @throws IllegalStateException The buffer doesn't hold the given number + * of bytes. Use {@link #getCurrentNumberOfBytes()} to prevent this + * exception. + */ + public void read(byte[] pBuffer, int pOffset, int pLength) { + Objects.requireNonNull(pBuffer); + if (pOffset < 0 || pOffset >= pBuffer.length) { + throw new IllegalArgumentException("Invalid offset: " + pOffset); + } + if (pLength < 0 || pLength > buffer.length) { + throw new IllegalArgumentException("Invalid length: " + pLength); + } + if (pOffset + pLength > pBuffer.length) { + throw new IllegalArgumentException("The supplied byte array contains only " + + pBuffer.length + " bytes, but offset, and length would require " + + (pOffset + pLength - 1)); + } + if (currentNumberOfBytes < pLength) { + throw new IllegalStateException("Currently, there are only " + currentNumberOfBytes + + "in the buffer, not " + pLength); + } + int offset = pOffset; + for (int i = 0; i < pLength; i++) { + pBuffer[offset++] = buffer[startOffset]; + --currentNumberOfBytes; + if (++startOffset == buffer.length) { + startOffset = 0; + } + } + } - /** - * Adds a new byte to the buffer, which will eventually be returned by following - * invocations of {@link #read()}. - * @param pByte The byte, which is being added to the buffer. - * @throws IllegalStateException The buffer is full. Use {@link #hasSpace()}, - * or {@link #getSpace()}, to prevent this exception. - */ - public void add(byte pByte) { - if (currentNumberOfBytes >= buffer.length) { - throw new IllegalStateException("No space available"); - } - buffer[endOffset] = pByte; - ++currentNumberOfBytes; - if (++endOffset == buffer.length) { - endOffset = 0; - } - } + /** + * Adds a new byte to the buffer, which will eventually be returned by following + * invocations of {@link #read()}. + * + * @param pByte The byte, which is being added to the buffer. + * @throws IllegalStateException The buffer is full. Use {@link #hasSpace()}, + * or {@link #getSpace()}, to prevent this exception. + */ + public void add(byte pByte) { + if (currentNumberOfBytes >= buffer.length) { + throw new IllegalStateException("No space available"); + } + buffer[endOffset] = pByte; + ++currentNumberOfBytes; + if (++endOffset == buffer.length) { + endOffset = 0; + } + } - /** - * Returns, whether the next bytes in the buffer are exactly those, given by - * {@code pBuffer}, {@code pOffset}, and {@code pLength}. No bytes are being - * removed from the buffer. If the result is true, then the following invocations - * of {@link #read()} are guaranteed to return exactly those bytes. - * @param pBuffer the buffer to compare against - * @param pOffset start offset - * @param pLength length to compare - * @return True, if the next invocations of {@link #read()} will return the - * bytes at offsets {@code pOffset}+0, {@code pOffset}+1, ..., - * {@code pOffset}+{@code pLength}-1 of byte array {@code pBuffer}. - * @throws IllegalArgumentException Either of {@code pOffset}, or {@code pLength} is negative. - * @throws NullPointerException The byte array {@code pBuffer} is null. - */ - public boolean peek(byte[] pBuffer, int pOffset, int pLength) { - Objects.requireNonNull(pBuffer, "Buffer"); - if (pOffset < 0 || pOffset >= pBuffer.length) { - throw new IllegalArgumentException("Invalid offset: " + pOffset); - } - if (pLength < 0 || pLength > buffer.length) { - throw new IllegalArgumentException("Invalid length: " + pLength); - } - if (pLength < currentNumberOfBytes) { - return false; - } - int offset = startOffset; - for (int i = 0; i < pLength; i++) { - if (buffer[offset] != pBuffer[i+pOffset]) { - return false; - } - if (++offset == buffer.length) { - offset = 0; - } - } - return true; - } + /** + * Returns, whether the next bytes in the buffer are exactly those, given by + * {@code pBuffer}, {@code pOffset}, and {@code pLength}. No bytes are being + * removed from the buffer. If the result is true, then the following invocations + * of {@link #read()} are guaranteed to return exactly those bytes. + * + * @param pBuffer the buffer to compare against + * @param pOffset start offset + * @param pLength length to compare + * @return True, if the next invocations of {@link #read()} will return the + * bytes at offsets {@code pOffset}+0, {@code pOffset}+1, ..., + * {@code pOffset}+{@code pLength}-1 of byte array {@code pBuffer}. + * @throws IllegalArgumentException Either of {@code pOffset}, or {@code pLength} is negative. + * @throws NullPointerException The byte array {@code pBuffer} is null. + */ + public boolean peek(byte[] pBuffer, int pOffset, int pLength) { + Objects.requireNonNull(pBuffer, "Buffer"); + if (pOffset < 0 || pOffset >= pBuffer.length) { + throw new IllegalArgumentException("Invalid offset: " + pOffset); + } + if (pLength < 0 || pLength > buffer.length) { + throw new IllegalArgumentException("Invalid length: " + pLength); + } + if (pLength < currentNumberOfBytes) { + return false; + } + int offset = startOffset; + for (int i = 0; i < pLength; i++) { + if (buffer[offset] != pBuffer[i + pOffset]) { + return false; + } + if (++offset == buffer.length) { + offset = 0; + } + } + return true; + } - /** - * Adds the given bytes to the buffer. This is the same as invoking {@link #add(byte)} - * for the bytes at offsets {@code pOffset}+0, {@code pOffset}+1, ..., - * {@code pOffset}+{@code pLength}-1 of byte array {@code pBuffer}. + /** + * Adds the given bytes to the buffer. This is the same as invoking {@link #add(byte)} + * for the bytes at offsets {@code pOffset}+0, {@code pOffset}+1, ..., + * {@code pOffset}+{@code pLength}-1 of byte array {@code pBuffer}. + * * @param pBuffer the buffer to copy * @param pOffset start offset * @param pLength length to copy - * @throws IllegalStateException The buffer doesn't have sufficient space. Use - * {@link #getSpace()} to prevent this exception. - * @throws IllegalArgumentException Either of {@code pOffset}, or {@code pLength} is negative. - * @throws NullPointerException The byte array {@code pBuffer} is null. - */ - public void add(byte[] pBuffer, int pOffset, int pLength) { - Objects.requireNonNull(pBuffer, "Buffer"); - if (pOffset < 0 || pOffset >= pBuffer.length) { - throw new IllegalArgumentException("Invalid offset: " + pOffset); - } - if (pLength < 0) { - throw new IllegalArgumentException("Invalid length: " + pLength); - } - if (currentNumberOfBytes+pLength > buffer.length) { - throw new IllegalStateException("No space available"); - } - for (int i = 0; i < pLength; i++) { - buffer[endOffset] = pBuffer[pOffset+i]; - if (++endOffset == buffer.length) { - endOffset = 0; - } - } - currentNumberOfBytes += pLength; - } + * @throws IllegalStateException The buffer doesn't have sufficient space. Use + * {@link #getSpace()} to prevent this exception. + * @throws IllegalArgumentException Either of {@code pOffset}, or {@code pLength} is negative. + * @throws NullPointerException The byte array {@code pBuffer} is null. + */ + public void add(byte[] pBuffer, int pOffset, int pLength) { + Objects.requireNonNull(pBuffer, "Buffer"); + if (pOffset < 0 || pOffset >= pBuffer.length) { + throw new IllegalArgumentException("Invalid offset: " + pOffset); + } + if (pLength < 0) { + throw new IllegalArgumentException("Invalid length: " + pLength); + } + if (currentNumberOfBytes + pLength > buffer.length) { + throw new IllegalStateException("No space available"); + } + for (int i = 0; i < pLength; i++) { + buffer[endOffset] = pBuffer[pOffset + i]; + if (++endOffset == buffer.length) { + endOffset = 0; + } + } + currentNumberOfBytes += pLength; + } - /** - * Returns, whether there is currently room for a single byte in the buffer. - * Same as {@link #hasSpace(int) hasSpace(1)}. - * @see #hasSpace(int) - * @see #getSpace() - * @return true if there is space for a byte - */ - public boolean hasSpace() { - return currentNumberOfBytes < buffer.length; - } + /** + * Returns, whether there is currently room for a single byte in the buffer. + * Same as {@link #hasSpace(int) hasSpace(1)}. + * + * @return true if there is space for a byte + * @see #hasSpace(int) + * @see #getSpace() + */ + public boolean hasSpace() { + return currentNumberOfBytes < buffer.length; + } - /** - * Returns, whether there is currently room for the given number of bytes in the buffer. - * @see #hasSpace() - * @see #getSpace() - * @param pBytes the byte count - * @return true if there is space for the given number of bytes - */ - public boolean hasSpace(int pBytes) { - return currentNumberOfBytes+pBytes <= buffer.length; - } + /** + * Returns, whether there is currently room for the given number of bytes in the buffer. + * + * @param pBytes the byte count + * @return true if there is space for the given number of bytes + * @see #hasSpace() + * @see #getSpace() + */ + public boolean hasSpace(int pBytes) { + return currentNumberOfBytes + pBytes <= buffer.length; + } - /** - * Returns, whether the buffer is currently holding, at least, a single byte. - * @return true if the buffer is not empty - */ - public boolean hasBytes() { - return currentNumberOfBytes > 0; - } + /** + * Returns, whether the buffer is currently holding, at least, a single byte. + * + * @return true if the buffer is not empty + */ + public boolean hasBytes() { + return currentNumberOfBytes > 0; + } - /** - * Returns the number of bytes, that can currently be added to the buffer. - * @return the number of bytes that can be added - */ - public int getSpace() { - return buffer.length - currentNumberOfBytes; - } + /** + * Returns the number of bytes, that can currently be added to the buffer. + * + * @return the number of bytes that can be added + */ + public int getSpace() { + return buffer.length - currentNumberOfBytes; + } - /** - * Returns the number of bytes, that are currently present in the buffer. - * @return the number of bytes - */ - public int getCurrentNumberOfBytes() { - return currentNumberOfBytes; - } + /** + * Returns the number of bytes, that are currently present in the buffer. + * + * @return the number of bytes + */ + public int getCurrentNumberOfBytes() { + return currentNumberOfBytes; + } - /** - * Removes all bytes from the buffer. - */ - public void clear() { - startOffset = 0; - endOffset = 0; - currentNumberOfBytes = 0; - } + /** + * Removes all bytes from the buffer. + */ + public void clear() { + startOffset = 0; + endOffset = 0; + currentNumberOfBytes = 0; + } } diff --git a/src/main/java/org/apache/commons/io/input/buffer/PeekableInputStream.java b/src/main/java/org/apache/commons/io/input/buffer/PeekableInputStream.java index 6263846..feed9c1 100644 --- a/src/main/java/org/apache/commons/io/input/buffer/PeekableInputStream.java +++ b/src/main/java/org/apache/commons/io/input/buffer/PeekableInputStream.java @@ -21,67 +21,74 @@ import java.io.InputStream; import java.util.Objects; -/** Implementation of a buffered input stream, which allows to peek into +/** + * Implementation of a buffered input stream, which allows to peek into * the buffers first bytes. This comes in handy when manually implementing * scanners, lexers, parsers, or the like. */ public class PeekableInputStream extends CircularBufferInputStream { - /** Creates a new instance, which filters the given input stream, and - * uses the given buffer size. - * @param pIn The input stream, which is being buffered. - * @param pBufferSize The size of the {@link CircularByteBuffer}, which is - * used internally. - */ - public PeekableInputStream(InputStream pIn, int pBufferSize) { - super(pIn, pBufferSize); - } + /** + * Creates a new instance, which filters the given input stream, and + * uses the given buffer size. + * + * @param pIn The input stream, which is being buffered. + * @param pBufferSize The size of the {@link CircularByteBuffer}, which is + * used internally. + */ + public PeekableInputStream(InputStream pIn, int pBufferSize) { + super(pIn, pBufferSize); + } - /** Creates a new instance, which filters the given input stream, and - * uses a reasonable default buffer size (8192). - * @param pIn The input stream, which is being buffered. - */ - public PeekableInputStream(InputStream pIn) { - super(pIn); - } + /** + * Creates a new instance, which filters the given input stream, and + * uses a reasonable default buffer size (8192). + * + * @param pIn The input stream, which is being buffered. + */ + public PeekableInputStream(InputStream pIn) { + super(pIn); + } - /** - * Returns, whether the next bytes in the buffer are as given by - * {@code pBuffer}. This is equivalent to {@link #peek(byte[],int,int)} - * with {@code pOffset} == 0, and {@code pLength} == {@code pBuffer.length} - * @param pBuffer the buffer to compare against - * @return true if the next bytes are as given - * @throws IOException Refilling the buffer failed. - */ - public boolean peek(byte[] pBuffer) throws IOException { - Objects.requireNonNull(pBuffer, "Buffer"); - if (pBuffer.length > bufferSize) { - throw new IllegalArgumentException("Peek request size of " + pBuffer.length - + " bytes exceeds buffer size of " + bufferSize + " bytes"); - } - if (buffer.getCurrentNumberOfBytes() < pBuffer.length) { - fillBuffer(); - } - return buffer.peek(pBuffer, 0, pBuffer.length); - } + /** + * Returns, whether the next bytes in the buffer are as given by + * {@code pBuffer}. This is equivalent to {@link #peek(byte[], int, int)} + * with {@code pOffset} == 0, and {@code pLength} == {@code pBuffer.length} + * + * @param pBuffer the buffer to compare against + * @return true if the next bytes are as given + * @throws IOException Refilling the buffer failed. + */ + public boolean peek(byte[] pBuffer) throws IOException { + Objects.requireNonNull(pBuffer, "Buffer"); + if (pBuffer.length > bufferSize) { + throw new IllegalArgumentException("Peek request size of " + pBuffer.length + + " bytes exceeds buffer size of " + bufferSize + " bytes"); + } + if (buffer.getCurrentNumberOfBytes() < pBuffer.length) { + fillBuffer(); + } + return buffer.peek(pBuffer, 0, pBuffer.length); + } - /** - * Returns, whether the next bytes in the buffer are as given by - * {@code pBuffer}, {code pOffset}, and {@code pLength}. - * @param pBuffer the buffer to compare against - * @param pOffset the start offset - * @param pLength the length to compare - * @return true if the next bytes in the buffer are as given - * @throws IOException if there is a problem calling fillBuffer() - */ - public boolean peek(byte[] pBuffer, int pOffset, int pLength) throws IOException { - Objects.requireNonNull(pBuffer, "Buffer"); - if (pBuffer.length > bufferSize) { - throw new IllegalArgumentException("Peek request size of " + pBuffer.length - + " bytes exceeds buffer size of " + bufferSize + " bytes"); - } - if (buffer.getCurrentNumberOfBytes() < pBuffer.length) { - fillBuffer(); - } - return buffer.peek(pBuffer, pOffset, pLength); - } + /** + * Returns, whether the next bytes in the buffer are as given by + * {@code pBuffer}, {code pOffset}, and {@code pLength}. + * + * @param pBuffer the buffer to compare against + * @param pOffset the start offset + * @param pLength the length to compare + * @return true if the next bytes in the buffer are as given + * @throws IOException if there is a problem calling fillBuffer() + */ + public boolean peek(byte[] pBuffer, int pOffset, int pLength) throws IOException { + Objects.requireNonNull(pBuffer, "Buffer"); + if (pBuffer.length > bufferSize) { + throw new IllegalArgumentException("Peek request size of " + pBuffer.length + + " bytes exceeds buffer size of " + bufferSize + " bytes"); + } + if (buffer.getCurrentNumberOfBytes() < pBuffer.length) { + fillBuffer(); + } + return buffer.peek(pBuffer, pOffset, pLength); + } } diff --git a/src/main/java/org/apache/commons/io/input/buffer/package-info.java b/src/main/java/org/apache/commons/io/input/buffer/package-info.java new file mode 100644 index 0000000..06dc565 --- /dev/null +++ b/src/main/java/org/apache/commons/io/input/buffer/package-info.java @@ -0,0 +1,17 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.io.input.buffer; diff --git a/src/test/java/org/apache/commons/io/IOUtilsCopyTestCase.java b/src/test/java/org/apache/commons/io/IOUtilsCopyTestCase.java index 8b4cd87..a50b054 100644 --- a/src/test/java/org/apache/commons/io/IOUtilsCopyTestCase.java +++ b/src/test/java/org/apache/commons/io/IOUtilsCopyTestCase.java @@ -257,7 +257,7 @@ public class IOUtilsCopyTestCase { final NullWriter writer = new NullWriter(); // Test copy() method - assertEquals(size, IOUtils.copy(reader, writer)); + assertEquals(size, IOUtils.copy(reader, (Appendable) writer)); // reset the input reader.close();