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