diff src/goodjava/io/BufferedInputStream.java @ 1489:fe237d72b234

improve BufferedInputStream
author Franklin Schmidt <fschmidt@gmail.com>
date Sat, 02 May 2020 16:28:24 -0600
parents 97740900c820
children 91c167099462
line wrap: on
line diff
--- a/src/goodjava/io/BufferedInputStream.java	Sat May 02 15:38:48 2020 -0600
+++ b/src/goodjava/io/BufferedInputStream.java	Sat May 02 16:28:24 2020 -0600
@@ -120,23 +120,34 @@
 	 * Read characters into a portion of an array, reading from the underlying
 	 * stream at most once if necessary.
 	 */
-	public synchronized int read(byte[] b, int off, int len) throws IOException {
+	private int read1(byte[] b, int off, int len) throws IOException {
+		int cnt = 0;
 		int avail = count - pos;
-		if (avail <= 0) {
-			/* If the requested length is at least as large as the buffer, do not bother to copy the
-			   bytes into the local buffer.  In this way buffered streams will
-			   cascade harmlessly. */
-			if (len >= buf.length) {
-				return super.read(b, off, len);
-			}
-			fill();
-			avail = count - pos;
-			if (avail <= 0) return -1;
+		if( avail > 0 ) {
+			cnt = (avail < len) ? avail : len;
+			System.arraycopy(buf, pos, b, off, cnt);
+			pos += cnt;
+			len -= cnt;
+			if( len == 0 )
+				return cnt;
+			off += cnt;
+		}
+		if (len >= buf.length) {
+			return cnt + Math.max( 0, super.read(b, off, len) );
 		}
-		int cnt = (avail < len) ? avail : len;
-		System.arraycopy(buf, pos, b, off, cnt);
-		pos += cnt;
-		return cnt;
+		fill();
+		if (count <= 0)
+			return cnt;
+		System.arraycopy(buf, 0, b, off, len);
+		pos += len;
+		return cnt + len;
+	}
+
+	public synchronized int read(byte[] b, int off, int len) throws IOException {
+		if( len == 0 )
+			return 0;
+		int n = read1(b,off,len);
+		return n==0 ? -1 : n;
 	}
 
 	/**
@@ -149,13 +160,18 @@
 	 *                          I/O error occurs.
 	 */
 	public synchronized long skip(long n) throws IOException {
+		if( n <= 0 )
+			return 0;
+		long skipped = 0;
 		long avail = count - pos;
-		if (avail <= 0) {
-			return super.skip(n);
+		if( avail > 0 ) {
+			skipped = (avail < n) ? avail : n;
+			pos += skipped;
+			n -= skipped;
+			if( n == 0 )
+				return skipped;
 		}
-		long skipped = (avail < n) ? avail : n;
-		pos += skipped;
-		return skipped;
+		return skipped + super.skip(n);
 	}
 
 	/**