1c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrompackage org.bouncycastle.asn1; 2c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.EOFException; 4c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.IOException; 5c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.InputStream; 6c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 7c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.util.io.Streams; 8c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromclass DefiniteLengthInputStream 10c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom extends LimitedInputStream 11c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom{ 12c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private static final byte[] EMPTY_BYTES = new byte[0]; 13c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 14c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private final int _originalLength; 15c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom private int _remaining; 16c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 17c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom DefiniteLengthInputStream( 18c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom InputStream in, 19c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int length) 20c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 216e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom super(in, length); 22c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 23c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (length < 0) 24c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 25c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IllegalArgumentException("negative lengths not allowed"); 26c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 27c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 28c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this._originalLength = length; 29c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this._remaining = length; 30c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 31c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (length == 0) 32c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 33c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom setParentEofDetect(true); 34c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 35c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 36c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 37c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int getRemaining() 38c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 39c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return _remaining; 40c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 41c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 42c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public int read() 43c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws IOException 44c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 45c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (_remaining == 0) 46c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 47c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return -1; 48c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 49c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 50c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int b = _in.read(); 51c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 52c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (b < 0) 53c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 54c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining); 55c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 56c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 57c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (--_remaining == 0) 58c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 59c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom setParentEofDetect(true); 60c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 61c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return b; 63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 64c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 65c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public int read(byte[] buf, int off, int len) 66c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws IOException 67c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 68c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (_remaining == 0) 69c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 70c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return -1; 71c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int toRead = Math.min(len, _remaining); 74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom int numRead = _in.read(buf, off, toRead); 75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (numRead < 0) 77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 78c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining); 79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 80c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 81c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if ((_remaining -= numRead) == 0) 82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 83c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom setParentEofDetect(true); 84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 85c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 86c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return numRead; 87c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 88c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 89c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] toByteArray() 90c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throws IOException 91c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 92c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (_remaining == 0) 93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 94c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return EMPTY_BYTES; 95c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 96c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 97c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom byte[] bytes = new byte[_remaining]; 98c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if ((_remaining -= Streams.readFully(_in, bytes)) != 0) 99c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 100c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining); 101c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 102c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom setParentEofDetect(true); 103c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return bytes; 104c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 105c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom} 106