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    }