| package org.bouncycastle.asn1; |
| |
| import java.io.EOFException; |
| import java.io.IOException; |
| import java.io.InputStream; |
| |
| import org.bouncycastle.util.io.Streams; |
| |
| class DefiniteLengthInputStream |
| extends LimitedInputStream |
| { |
| private static final byte[] EMPTY_BYTES = new byte[0]; |
| |
| private final int _originalLength; |
| private int _remaining; |
| |
| DefiniteLengthInputStream( |
| InputStream in, |
| int length) |
| { |
| super(in, length); |
| |
| if (length < 0) |
| { |
| throw new IllegalArgumentException("negative lengths not allowed"); |
| } |
| |
| this._originalLength = length; |
| this._remaining = length; |
| |
| if (length == 0) |
| { |
| setParentEofDetect(true); |
| } |
| } |
| |
| int getRemaining() |
| { |
| return _remaining; |
| } |
| |
| public int read() |
| throws IOException |
| { |
| if (_remaining == 0) |
| { |
| return -1; |
| } |
| |
| int b = _in.read(); |
| |
| if (b < 0) |
| { |
| throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining); |
| } |
| |
| if (--_remaining == 0) |
| { |
| setParentEofDetect(true); |
| } |
| |
| return b; |
| } |
| |
| public int read(byte[] buf, int off, int len) |
| throws IOException |
| { |
| if (_remaining == 0) |
| { |
| return -1; |
| } |
| |
| int toRead = Math.min(len, _remaining); |
| int numRead = _in.read(buf, off, toRead); |
| |
| if (numRead < 0) |
| { |
| throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining); |
| } |
| |
| if ((_remaining -= numRead) == 0) |
| { |
| setParentEofDetect(true); |
| } |
| |
| return numRead; |
| } |
| |
| byte[] toByteArray() |
| throws IOException |
| { |
| if (_remaining == 0) |
| { |
| return EMPTY_BYTES; |
| } |
| |
| byte[] bytes = new byte[_remaining]; |
| if ((_remaining -= Streams.readFully(_in, bytes)) != 0) |
| { |
| throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining); |
| } |
| setParentEofDetect(true); |
| return bytes; |
| } |
| } |