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