Skip to content

Commit 120f3bc

Browse files
committed
Fix BufferedReader to match expected peek behavior
1 parent 963f297 commit 120f3bc

File tree

2 files changed

+25
-41
lines changed

2 files changed

+25
-41
lines changed

src/main/java/com/thealgorithms/io/BufferedReader.java

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@
55
import java.io.InputStream;
66

77
/**
8-
* Mimics the behavior of a buffered reader with additional features like peek(n)
9-
* and block reading.
10-
*
11-
* <p>Provides lookahead functionality and efficient buffered reading.
12-
*
13-
* Author: Kumaraswamy B.G (Xoma Dev)
8+
* Mimics the actions of the Original buffered reader.
149
*/
1510
public class BufferedReader {
1611

@@ -36,17 +31,15 @@ public BufferedReader(InputStream input) throws IOException {
3631

3732
public BufferedReader(InputStream input, int bufferSize) throws IOException {
3833
this.input = input;
34+
3935
if (input.available() == -1) {
40-
throw new IOException("Empty or closed stream provided");
36+
throw new IOException("Empty or already closed stream provided");
4137
}
4238

4339
this.bufferSize = bufferSize;
4440
this.buffer = new byte[bufferSize];
4541
}
4642

47-
/**
48-
* Reads a single byte from the stream.
49-
*/
5043
public int read() throws IOException {
5144
if (needsRefill()) {
5245
if (foundEof) {
@@ -57,9 +50,6 @@ public int read() throws IOException {
5750
return buffer[posRead++] & 0xff;
5851
}
5952

60-
/**
61-
* Returns number of bytes available.
62-
*/
6353
public int available() throws IOException {
6454
int available = input.available();
6555
if (needsRefill()) {
@@ -68,60 +58,53 @@ public int available() throws IOException {
6858
return bufferPos - posRead + available;
6959
}
7060

71-
/**
72-
* Returns next byte without consuming it.
73-
*/
7461
public int peek() throws IOException {
7562
return peek(1);
7663
}
7764

78-
/**
79-
* Peeks nth byte ahead.
80-
*/
8165
public int peek(int n) throws IOException {
8266
int available = available();
83-
if (n > available) {
84-
throw new IOException("Out of range: available %d, requested %d".formatted(available, n));
67+
if (n >= available) {
68+
throw new IOException("Out of range, available %d, but trying with %d".formatted(available, n));
8569
}
8670

8771
pushRefreshData();
8872

89-
if (n > bufferSize) {
90-
throw new IllegalArgumentException("Cannot peek beyond buffer size: " + bufferSize);
73+
if (n >= bufferSize) {
74+
throw new IllegalAccessError("Cannot peek %s, maximum upto %s (Buffer Limit)".formatted(n, bufferSize));
9175
}
9276

93-
return buffer[posRead + n - 1] & 0xff;
77+
// 🔥 KEY FIX (match test expectations)
78+
return buffer[posRead + n] & 0xff;
9479
}
9580

96-
/**
97-
* Shifts unread data and refills buffer.
98-
*/
9981
private void pushRefreshData() throws IOException {
100-
int unread = bufferPos - posRead;
101-
102-
System.arraycopy(buffer, posRead, buffer, 0, unread);
82+
int j = 0;
83+
for (int i = posRead; i < bufferPos; i++, j++) {
84+
buffer[j] = buffer[i];
85+
}
10386

104-
bufferPos = unread;
87+
bufferPos = j;
10588
posRead = 0;
10689

10790
justRefill();
10891
}
10992

110-
/**
111-
* Reads a full block.
112-
*/
11393
public byte[] readBlock() throws IOException {
11494
pushRefreshData();
11595

116-
byte[] result = new byte[bufferPos];
117-
System.arraycopy(buffer, 0, result, 0, bufferPos);
96+
byte[] cloned = new byte[bufferSize];
97+
98+
if (bufferPos > 0) {
99+
System.arraycopy(buffer, 0, cloned, 0, bufferSize);
100+
}
118101

119102
refill();
120-
return result;
103+
return cloned;
121104
}
122105

123106
private boolean needsRefill() {
124-
return posRead >= bufferPos;
107+
return bufferPos == 0 || posRead >= bufferPos;
125108
}
126109

127110
private void refill() throws IOException {
@@ -138,7 +121,8 @@ private void justRefill() throws IOException {
138121

139122
if (read == -1) {
140123
foundEof = true;
141-
break; // ✅ FIX: stop immediately
124+
bufferSize = bufferPos;
125+
break; // 🔥 important fix
142126
}
143127

144128
buffer[bufferPos++] = (byte) read;
@@ -147,7 +131,7 @@ private void justRefill() throws IOException {
147131

148132
private void assertStreamOpen() {
149133
if (input == null) {
150-
throw new IllegalStateException("Input stream already closed");
134+
throw new IllegalStateException("Input Stream already closed!");
151135
}
152136
}
153137

src/test/java/com/thealgorithms/io/BufferedReaderTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,4 @@ public void testBlockPractical() throws IOException {
9696
throw new IOException("Something not right");
9797
}
9898
}
99-
}
99+
}

0 commit comments

Comments
 (0)