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 }