ByteArrayBranchingStream.java
/*
* The contents of this file are subject to the terms of the Common Development and
* Distribution License (the License). You may not use this file except in compliance with the
* License.
*
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
* specific language governing permission and limitations under the License.
*
* When distributing Covered Software, include this CDDL Header Notice in each file and include
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions Copyright [year] [name of copyright owner]".
*
* Copyright 2010–2011 ApexIdentity Inc.
* Portions Copyright 2011-2016 ForgeRock AS.
*/
package org.forgerock.http.io;
import java.io.IOException;
/**
* Wraps a byte array with a stream that can branch to perform divergent reads.
*/
final class ByteArrayBranchingStream extends BranchingInputStream {
/** The index of the next byte to read from the byte array. */
private int position = 0;
/** The currently marked position in the stream. */
private int mark = -1;
/** The byte array to expose as the input stream. */
private byte[] data;
ByteArrayBranchingStream(byte[] data) {
super(null);
this.data = data;
}
private ByteArrayBranchingStream(byte[] data, BranchingInputStream parent) {
super(parent);
this.data = data;
}
@Override
public ByteArrayBranchingStream branch() {
ByteArrayBranchingStream branch = new ByteArrayBranchingStream(data, this);
branch.position = this.position;
return branch;
}
@Override
public ByteArrayBranchingStream copy() throws IOException {
ByteArrayBranchingStream branch = new ByteArrayBranchingStream(data, this.parent());
branch.position = this.position;
return branch;
}
@Override
public synchronized int read() {
return (position < data.length ? data[position++] & 0xff : -1);
}
@Override
public int read(byte[] b) {
return read(b, 0, b.length);
}
@Override
public synchronized int read(byte[] b, int off, int len) {
if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
}
if (position >= data.length) {
// end of stream has been reached
return -1;
}
len = Math.min(len, data.length - position);
System.arraycopy(data, position, b, off, len);
position += len;
return len;
}
@Override
public synchronized long skip(long n) {
if (n <= 0) {
return 0;
}
n = Math.min(n, data.length - position);
position += n;
return n;
}
@Override
public synchronized int available() {
return data.length - position;
}
@Override
public boolean markSupported() {
return true;
}
@Override
public void mark(int readlimit) {
mark = position;
}
@Override
public synchronized void reset() throws IOException {
if (mark < 0) {
throw new IOException("position was not marked");
}
position = mark;
}
@Override
public void close() {
}
}