Skip to content

Instantly share code, notes, and snippets.

@icedraco
Created December 15, 2015 08:35
Show Gist options
  • Select an option

  • Save icedraco/8634516b529fcba6721c to your computer and use it in GitHub Desktop.

Select an option

Save icedraco/8634516b529fcba6721c to your computer and use it in GitHub Desktop.
FakeInputStream / FakeOutputStream - InputStream and OutputStream that may help testing implementations that deal with I/O from packet-based streams in Java. Meant mostly for the VpnService-related testing on Android...
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* Simulates an InputStream that provides pre-determined packet data
*
* @author IceDragon [icedragon@quickfox.org]
* @version 1.0
*/
public class FakeInputStream extends InputStream {
private final Queue<ByteBuffer> mPackets;
private ByteBuffer mCurrentPacket;
/*** Constructors ********************************************************/
public FakeInputStream() {
mPackets = new ConcurrentLinkedQueue<>();
mCurrentPacket = null;
}
/*** Methods *************************************************************/
public void add(byte[] packet) {
add(packet, packet.length);
}
public void add(byte[] packet, int len) {
ByteBuffer buffer = ByteBuffer.wrap(packet);
buffer.position(0);
buffer.limit(len);
mPackets.add(buffer);
}
public int pending() {
return mPackets.size();
}
public ByteBuffer getCurrentPacket() {
return mCurrentPacket;
}
/*** Methods (InputStream) ***********************************************/
@Override
public int read() throws IOException {
try {
trySwapBuffer();
return mCurrentPacket.get();
}
catch (NoSuchElementException ex) {
return -1;
}
}
@Override
public int read(byte[] dest) {
return read(dest, 0, dest.length);
}
@Override
public int read(byte[] dest, int offset, int len) {
// max. bytes we can read = max. bytes the destination can contain
int limit = dest.length - offset;
// len is less than that...
if (len < limit) {
limit = len;
}
try {
trySwapBuffer();
// available bytes are less than len
if (mCurrentPacket.remaining() < limit) {
limit = mCurrentPacket.remaining();
}
mCurrentPacket.get(dest, offset, limit);
return limit;
}
catch (NoSuchElementException ex) {
return 0;
}
}
/*** Helper Methods ******************************************************/
private boolean trySwapBuffer() throws NoSuchElementException {
if (mCurrentPacket == null || !mCurrentPacket.hasRemaining()) {
mCurrentPacket = mPackets.remove();
return true;
}
return false;
}
}
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* Simulates an OutputStream that provides pre-determined packet data
*
* @author IceDragon [icedragon@quickfox.org]
* @version 1.0
*/
public class FakeOutputStream extends OutputStream {
private final Queue<ByteBuffer> mPackets;
/*** Constructors ********************************************************/
public FakeOutputStream() {
mPackets = new ConcurrentLinkedQueue<>();
}
/*** Methods *************************************************************/
public int pending() {
return mPackets.size();
}
public boolean hasNextPacket() {
return pending() > 0;
}
public ByteBuffer nextPacket() {
try {
return mPackets.remove();
}
catch (NoSuchElementException ex) {
return null;
}
}
/*** Methods (InputStream) ***********************************************/
@Override
public void write(int b) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(1);
buffer.put((byte)b);
buffer.flip();
mPackets.add(buffer);
}
@Override
public void write(byte[] src) throws IOException {
write(src, 0, src.length);
}
@Override
public void write(byte[] src, int offset, int len) {
// max. bytes we can read = max. bytes the destination can contain
int limit = src.length - offset;
// len is less than that...
if (len < limit) {
limit = len;
}
ByteBuffer buffer = ByteBuffer.allocate(limit);
buffer.put(src, offset, len);
buffer.flip();
mPackets.add(buffer);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment