diff options
Diffstat (limited to 'core/src/main/java/org/spongycastle/asn1/IndefiniteLengthInputStream.java')
-rw-r--r-- | core/src/main/java/org/spongycastle/asn1/IndefiniteLengthInputStream.java | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/core/src/main/java/org/spongycastle/asn1/IndefiniteLengthInputStream.java b/core/src/main/java/org/spongycastle/asn1/IndefiniteLengthInputStream.java new file mode 100644 index 00000000..39e003a4 --- /dev/null +++ b/core/src/main/java/org/spongycastle/asn1/IndefiniteLengthInputStream.java @@ -0,0 +1,111 @@ +package org.spongycastle.asn1; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; + +class IndefiniteLengthInputStream + extends LimitedInputStream +{ + private int _b1; + private int _b2; + private boolean _eofReached = false; + private boolean _eofOn00 = true; + + IndefiniteLengthInputStream( + InputStream in, + int limit) + throws IOException + { + super(in, limit); + + _b1 = in.read(); + _b2 = in.read(); + + if (_b2 < 0) + { + // Corrupted stream + throw new EOFException(); + } + + checkForEof(); + } + + void setEofOn00( + boolean eofOn00) + { + _eofOn00 = eofOn00; + checkForEof(); + } + + private boolean checkForEof() + { + if (!_eofReached && _eofOn00 && (_b1 == 0x00 && _b2 == 0x00)) + { + _eofReached = true; + setParentEofDetect(true); + } + return _eofReached; + } + + public int read(byte[] b, int off, int len) + throws IOException + { + // Only use this optimisation if we aren't checking for 00 + if (_eofOn00 || len < 3) + { + return super.read(b, off, len); + } + + if (_eofReached) + { + return -1; + } + + int numRead = _in.read(b, off + 2, len - 2); + + if (numRead < 0) + { + // Corrupted stream + throw new EOFException(); + } + + b[off] = (byte)_b1; + b[off + 1] = (byte)_b2; + + _b1 = _in.read(); + _b2 = _in.read(); + + if (_b2 < 0) + { + // Corrupted stream + throw new EOFException(); + } + + return numRead + 2; + } + + public int read() + throws IOException + { + if (checkForEof()) + { + return -1; + } + + int b = _in.read(); + + if (b < 0) + { + // Corrupted stream + throw new EOFException(); + } + + int v = _b1; + + _b1 = _b2; + _b2 = b; + + return v; + } +} |