001 package org.apache.commons.ssl.asn1;
002
003 import java.io.IOException;
004 import java.io.InputStream;
005
006 class IndefiniteLengthInputStream
007 extends LimitedInputStream {
008 private int _b1;
009 private int _b2;
010 private boolean _eofReached = false;
011 private boolean _eofOn00 = true;
012
013 IndefiniteLengthInputStream(
014 InputStream in)
015 throws IOException {
016 super(in);
017
018 _b1 = in.read();
019 _b2 = in.read();
020 _eofReached = (_b2 < 0);
021 }
022
023 void setEofOn00(
024 boolean eofOn00) {
025 _eofOn00 = eofOn00;
026 }
027
028 boolean checkForEof() {
029 if (_eofOn00 && (_b1 == 0x00 && _b2 == 0x00)) {
030 _eofReached = true;
031 setParentEofDetect(true);
032 }
033 return _eofReached;
034 }
035
036 public int read(byte[] b, int off, int len)
037 throws IOException {
038 // Only use this optimisation if we aren't checking for 00
039 if (_eofOn00 || len < 3) {
040 return super.read(b, off, len);
041 }
042
043 if (_eofReached) {
044 return -1;
045 }
046
047 int numRead = _in.read(b, off + 2, len - 2);
048
049 if (numRead < 0) {
050 // throw new EOFException();
051 _eofReached = true;
052 return -1;
053 }
054
055 b[off] = (byte) _b1;
056 b[off + 1] = (byte) _b2;
057
058 _b1 = _in.read();
059 _b2 = _in.read();
060
061 if (_b2 < 0) {
062 // Corrupted stream
063 // throw new EOFException();
064 _eofReached = true;
065 // Just fall thru...
066 }
067
068 return numRead + 2;
069 }
070
071 public int read()
072 throws IOException {
073 if (checkForEof()) {
074 return -1;
075 }
076
077 int b = _in.read();
078
079 //
080 // strictly speaking we should return b1 and b2, but if this happens the stream
081 // is corrupted so we are already in trouble.
082 //
083 if (b < 0) {
084 // Corrupted stream
085 // throw new EOFException();
086 _eofReached = true;
087
088 return -1;
089 }
090
091 int v = _b1;
092
093 _b1 = _b2;
094 _b2 = b;
095
096 return v;
097 }
098 }