Skip to content

Commit 87787e4

Browse files
committed
[java] batch copy input to the circular buffer
1 parent 9e7615d commit 87787e4

File tree

2 files changed

+56
-14
lines changed

2 files changed

+56
-14
lines changed

java/src/org/openqa/selenium/io/CircularOutputStream.java

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@
2323
/** Captures the last N bytes of output. */
2424
public class CircularOutputStream extends OutputStream {
2525
private static final int DEFAULT_SIZE = 4096;
26-
private int start;
2726
private int end;
2827
private boolean filled = false;
29-
private byte[] buffer;
28+
private final byte[] buffer;
3029

3130
public CircularOutputStream(int maxSize) {
3231
buffer = new byte[maxSize];
@@ -36,22 +35,57 @@ public CircularOutputStream() {
3635
this(DEFAULT_SIZE);
3736
}
3837

38+
@Override
39+
public void write(byte[] b) {
40+
// overridden to get rid of the IOException
41+
write(b, 0, b.length);
42+
}
43+
44+
@Override
45+
public synchronized void write(byte[] b, int off, int len) {
46+
int bufferSize = buffer.length;
47+
48+
while (len > 0) {
49+
int chunk = Math.min(bufferSize, len);
50+
51+
if (bufferSize >= end + chunk) {
52+
System.arraycopy(b, off, buffer, end, chunk);
53+
end += chunk;
54+
} else {
55+
int space = bufferSize - end;
56+
System.arraycopy(b, off, buffer, end, space);
57+
filled = true;
58+
end = chunk - space;
59+
System.arraycopy(b, off + space, buffer, 0, end);
60+
}
61+
62+
off += chunk;
63+
len -= chunk;
64+
}
65+
}
66+
3967
@Override
4068
public synchronized void write(int b) {
4169
if (end == buffer.length) {
4270
filled = true;
4371
end = 0;
4472
}
4573

46-
if (filled && end == start) {
47-
start = start == buffer.length - 1 ? 0 : start + 1;
48-
}
49-
5074
buffer[end++] = (byte) b;
5175
}
5276

5377
@Override
54-
public String toString() {
78+
public void flush() {
79+
// overridden to get rid of the IOException
80+
}
81+
82+
@Override
83+
public void close() {
84+
// overridden to get rid of the IOException
85+
}
86+
87+
@Override
88+
public synchronized String toString() {
5589
int size = filled ? buffer.length : end;
5690
byte[] toReturn = new byte[size];
5791

@@ -61,13 +95,9 @@ public String toString() {
6195
return new String(toReturn, Charset.defaultCharset());
6296
}
6397

64-
int copyStart = buffer.length - start;
65-
if (copyStart == buffer.length) {
66-
copyStart = 0;
67-
}
68-
69-
System.arraycopy(buffer, start, toReturn, 0, copyStart);
70-
System.arraycopy(buffer, 0, toReturn, copyStart, end);
98+
int n = buffer.length - end;
99+
System.arraycopy(buffer, end, toReturn, 0, n);
100+
System.arraycopy(buffer, 0, toReturn, n, end);
71101
return new String(toReturn, Charset.defaultCharset());
72102
}
73103
}

java/test/org/openqa/selenium/io/CircularOutputStreamTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,18 @@ void testCircularness() {
124124
}
125125
}
126126

127+
@Test
128+
void testWriteExceedsBuffer() {
129+
CircularOutputStream os = new CircularOutputStream(5);
130+
try (PrintWriter pw = new PrintWriter(os, true)) {
131+
132+
pw.write("00");
133+
pw.write("000000000000012345");
134+
pw.flush();
135+
assertThat(os.toString()).isEqualTo("12345");
136+
}
137+
}
138+
127139
@Test
128140
void testConcurrentWrites() throws InterruptedException {
129141
final int bytesToWrite = 10000;

0 commit comments

Comments
 (0)