Created
December 15, 2015 08:35
-
-
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...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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