Skip to content

Commit

Permalink
[java] batch copy input to the circular buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
joerg1985 committed Aug 29, 2023
1 parent 9e7615d commit 87787e4
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 14 deletions.
58 changes: 44 additions & 14 deletions java/src/org/openqa/selenium/io/CircularOutputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@
/** Captures the last N bytes of output. */
public class CircularOutputStream extends OutputStream {
private static final int DEFAULT_SIZE = 4096;
private int start;
private int end;
private boolean filled = false;
private byte[] buffer;
private final byte[] buffer;

public CircularOutputStream(int maxSize) {
buffer = new byte[maxSize];
Expand All @@ -36,22 +35,57 @@ public CircularOutputStream() {
this(DEFAULT_SIZE);
}

@Override
public void write(byte[] b) {
// overridden to get rid of the IOException
write(b, 0, b.length);
}

@Override
public synchronized void write(byte[] b, int off, int len) {
int bufferSize = buffer.length;

while (len > 0) {
int chunk = Math.min(bufferSize, len);

if (bufferSize >= end + chunk) {
System.arraycopy(b, off, buffer, end, chunk);
end += chunk;
} else {
int space = bufferSize - end;
System.arraycopy(b, off, buffer, end, space);
filled = true;
end = chunk - space;
System.arraycopy(b, off + space, buffer, 0, end);
}

off += chunk;
len -= chunk;
}
}

@Override
public synchronized void write(int b) {
if (end == buffer.length) {
filled = true;
end = 0;
}

if (filled && end == start) {
start = start == buffer.length - 1 ? 0 : start + 1;
}

buffer[end++] = (byte) b;
}

@Override
public String toString() {
public void flush() {
// overridden to get rid of the IOException
}

@Override
public void close() {
// overridden to get rid of the IOException
}

@Override
public synchronized String toString() {
int size = filled ? buffer.length : end;
byte[] toReturn = new byte[size];

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

int copyStart = buffer.length - start;
if (copyStart == buffer.length) {
copyStart = 0;
}

System.arraycopy(buffer, start, toReturn, 0, copyStart);
System.arraycopy(buffer, 0, toReturn, copyStart, end);
int n = buffer.length - end;
System.arraycopy(buffer, end, toReturn, 0, n);
System.arraycopy(buffer, 0, toReturn, n, end);
return new String(toReturn, Charset.defaultCharset());
}
}
12 changes: 12 additions & 0 deletions java/test/org/openqa/selenium/io/CircularOutputStreamTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,18 @@ void testCircularness() {
}
}

@Test
void testWriteExceedsBuffer() {
CircularOutputStream os = new CircularOutputStream(5);
try (PrintWriter pw = new PrintWriter(os, true)) {

pw.write("00");
pw.write("000000000000012345");
pw.flush();
assertThat(os.toString()).isEqualTo("12345");
}
}

@Test
void testConcurrentWrites() throws InterruptedException {
final int bytesToWrite = 10000;
Expand Down

0 comments on commit 87787e4

Please sign in to comment.