package org.bouncycastle.asn1;

import org.bouncycastle.util.io.Streams;

import java.io.EOFException;
import java.io.InputStream;
import java.io.IOException;

class DefiniteLengthInputStream
        extends LimitedInputStream
{
    private static final byte[] EMPTY_BYTES = new byte[0];

    private int _length;

    DefiniteLengthInputStream(
        InputStream in,
        int         length)
    {
        super(in);

        if (length < 0)
        {
            throw new IllegalArgumentException("negative lengths not allowed");
        }

        this._length = length;
    }

    public int read()
        throws IOException
    {
        if (_length > 0)
        {
            int b = _in.read();

            if (b < 0)
            {
                throw new EOFException();
            }

            --_length;
            return b;
        }

        setParentEofDetect(true);

        return -1;
    }

    public int read(byte[] buf, int off, int len)
        throws IOException
    {
        if (_length > 0)
        {
            int toRead = Math.min(len, _length);
            int numRead = _in.read(buf, off, toRead);

            if (numRead < 0)
            {
                throw new EOFException();
            }

            _length -= numRead;
            return numRead;
        }

        setParentEofDetect(true);

        return -1;
    }

    byte[] toByteArray()
        throws IOException
    {
        byte[] bytes;
        if (_length > 0)
        {
            bytes = new byte[_length];
            if (Streams.readFully(_in, bytes) < _length)
            {
                throw new EOFException();
            }
            _length = 0;
        }
        else
        {
            bytes = EMPTY_BYTES;
        }

        setParentEofDetect(true);

        return bytes;
    }
}

@@ -568,24 +568,108 @@
 th = length;
+%0A%0A        if (length == 0)%0A        %7B%0A            setParentEofDetect(true);%0A        %7D
 %0A    %7D%0A%0A    
@@ -731,33 +731,34 @@
     if (_length 
-%3E
+==
  0)%0A        %7B%0A  
@@ -751,32 +751,62 @@
 )%0A        %7B%0A    
+        return -1;%0A        %7D%0A%0A
         int b = 
@@ -822,28 +822,24 @@
 );%0A%0A        
-    
 if (b %3C 0)%0A 
@@ -841,34 +841,26 @@
  0)%0A        
-  
-  %7B%0A    
+%7B%0A
             
@@ -885,36 +885,32 @@
 tion();%0A        
- 
-   
 %7D%0A%0A            -
@@ -904,20 +904,20 @@
         
-    
+if (
 --_lengt
@@ -921,43 +921,29 @@
 ngth
-;%0A            return b;%0A        %7D%0A%0A
+ == 0)%0A        %7B%0A    
     
@@ -963,32 +963,42 @@
 EofDetect(true);
+%0A        %7D
 %0A%0A        return
@@ -990,34 +990,33 @@
 %0A        return 
--1
+b
 ;%0A    %7D%0A%0A    pub
@@ -1103,33 +1103,34 @@
     if (_length 
-%3E
+==
  0)%0A        %7B%0A  
@@ -1123,32 +1123,62 @@
 )%0A        %7B%0A    
+        return -1;%0A        %7D%0A%0A
         int toRe
@@ -1206,20 +1206,16 @@
 ength);%0A
-    
         
@@ -1261,28 +1261,24 @@
 );%0A%0A        
- 
-   
 if (numRead 
@@ -1278,28 +1278,24 @@
 umRead %3C 0)%0A
-    
         %7B%0A  
@@ -1296,36 +1296,32 @@
   %7B%0A            
-    
 throw new EOFExc
@@ -1334,28 +1334,24 @@
 ();%0A        
-   
- 
 %7D%0A%0A         
@@ -1341,36 +1341,37 @@
      %7D%0A%0A        
-    
+if ((
 _length -= numRe
@@ -1376,49 +1376,30 @@
 Read
-;%0A            return numRead;%0A        %7D%0A%0A
+) == 0)%0A        %7B%0A    
     
@@ -1419,32 +1419,42 @@
 EofDetect(true);
+%0A        %7D
 %0A%0A        return
@@ -1450,26 +1450,31 @@
      return 
--1
+numRead
 ;%0A    %7D%0A%0A   
@@ -1532,30 +1532,8 @@
   %7B%0A
-        byte%5B%5D bytes;%0A
     
@@ -1552,9 +1552,10 @@
 gth 
-%3E
+==
  0)%0A
@@ -1567,32 +1567,78 @@
    %7B%0A           
+ return EMPTY_BYTES;%0A        %7D%0A%0A        byte%5B%5D
  bytes = new byt
@@ -1649,20 +1649,16 @@
 ength%5D;%0A
-    
         
@@ -1706,34 +1706,26 @@
 th)%0A        
-  
-  %7B%0A    
+%7B%0A
             
@@ -1754,34 +1754,26 @@
 ();%0A        
- 
-   %7D%0A    
+%7D%0A
         _len
@@ -1785,85 +1785,8 @@
  0;%0A
-        %7D%0A        else%0A        %7B%0A            bytes = EMPTY_BYTES;%0A        %7D%0A%0A
     
@@ -1815,17 +1815,16 @@
 (true);%0A
-%0A
         

Refactor to avoid multiple calls to setParentEofDetect(..)