garydgregory commented on code in PR #748: URL: https://github.com/apache/commons-io/pull/748#discussion_r2094611488
########## src/main/java/org/apache/commons/io/input/QueueInputStream.java: ########## @@ -224,4 +226,49 @@ public int read() { } } + /** + * Reads up to {@code length} bytes of data from the input stream into + * an array of bytes. The first byte is read while honoring the timeout; the rest are read while <i>not</i> honoring + * the timeout. The number of bytes actually read is returned as an integer. + * + * @param b the buffer into which the data is read. + * @param offset the start offset in array {@code b} at which the data is written. + * @param length the maximum number of bytes to read. + * @return the total number of bytes read into the buffer, or {@code -1} if there is no more data because the + * end of the stream has been reached. + * @throws NullPointerException If {@code b} is {@code null}. + * @throws IllegalStateException if thread is interrupted while waiting for the first byte. + * @throws IndexOutOfBoundsException if {@code offset} is negative, {@code length} is negative, or {@code length} is + * greater than {@code b.length - offset}. + * @since 2.20.0 + */ + @Override + public int read(final byte[] b, final int offset, final int length) { + if (b == null) { + throw new NullPointerException(); + } else if (offset < 0 || length < 0 || length > b.length - offset) { + throw new IndexOutOfBoundsException( + String.format("Range [%d, %<d + %d) out of bounds for length %d", offset, length, b.length)); + } else if (length == 0) { + return 0; + } + final List<Integer> drain = new ArrayList<>(Math.min(length, blockingQueue.size())); + blockingQueue.drainTo(drain, length); + if (drain.isEmpty()) { + // no data immediately available. wait for first byte + final int value = read(); + if (value == EOF) { + return EOF; + } + drain.add(value); + blockingQueue.drainTo(drain, length - 1); Review Comment: I think this call to `drainTo(...)` could be wrong because it can cause EOF markers to end up in the `drain` data. We want to drain until we get the requested length _or_ the EOF marker is seen in the drained data. For example: - Thread A is paused just before, on, or during the `drain.add(value)` above, but before `blockingQueue.drainTo(drain, length - 1);` - Thread B adds a `-1` (an EOF marker). - Thread A resumes, calls `blockingQueue.drainTo(drain, length - 1);` and now contains the EOF marker in `drain` and includes it in `b`. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@commons.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org