package org.bouncycastle.asn1;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;

class StreamUtil
{
    private static final long  MAX_MEMORY = Runtime.getRuntime().maxMemory();

    /**
     * Find out possible longest length, capped by available memory.
     *
     * @param in input stream of interest
     * @return length calculation or MAX_VALUE.
     */
    static int findLimit(InputStream in)
    {
        if (in instanceof LimitedInputStream)
        {
            return ((LimitedInputStream)in).getLimit();
        }
        else if (in instanceof ASN1InputStream)
        {
            return ((ASN1InputStream)in).getLimit();
        }
        else if (in instanceof ByteArrayInputStream)
        {
            return ((ByteArrayInputStream)in).available();
        }
        else if (in instanceof FileInputStream)
        {
            try
            {
                FileChannel channel = ((FileInputStream)in).getChannel();
                long  size = (channel != null) ? channel.size() : Integer.MAX_VALUE;

                if (size < Integer.MAX_VALUE)
                {
                    return (int)size;
                }
            }
            catch (IOException e)
            {
                // ignore - they'll find out soon enough!
            }
        }

        if (MAX_MEMORY > Integer.MAX_VALUE)
        {
            return Integer.MAX_VALUE;
        }

        return (int)MAX_MEMORY;
    }

    static int calculateBodyLength(
        int length)
    {
        int count = 1;

        if (length > 127)
        {
            int size = 1;
            int val = length;

            while ((val >>>= 8) != 0)
            {
                size++;
            }

            for (int i = (size - 1) * 8; i >= 0; i -= 8)
            {
                count++;
            }
        }

        return count;
    }

    static int calculateTagLength(int tagNo)
        throws IOException
    {
        int length = 1;

        if (tagNo >= 31)
        {
            if (tagNo < 128)
            {
                length++;
            }
            else
            {
                byte[] stack = new byte[5];
                int pos = stack.length;

                stack[--pos] = (byte)(tagNo & 0x7F);

                do
                {
                    tagNo >>= 7;
                    stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
                }
                while (tagNo > 127);

                length += stack.length - pos;
            }
        }

        return length;
    }
}

@@ -1612,32 +1612,8 @@
   %7B%0A
-        int count = 1;%0A%0A
     
@@ -1627,21 +1627,21 @@
 (length 
-%3E 127
+%3C 128
 )%0A      
@@ -1660,18 +1660,14 @@
     
-int size =
+return
  1;%0A
@@ -1676,42 +1676,44 @@
     
+  %7D%0A%0A
       
+  
 int 
-val = length;%0A%0A 
+count = 2;%0A
         
    w
@@ -1712,19 +1712,16 @@
     
-   
 while ((
 val 
@@ -1720,11 +1720,14 @@
 e ((
-val
+length
  %3E%3E%3E
@@ -1737,36 +1737,32 @@
 ) != 0)%0A        
-    
 %7B%0A              
@@ -1763,155 +1763,26 @@
     
-    size++;%0A            %7D%0A%0A            for (int i = (size - 1) * 8; i %3E= 0; i -= 8)%0A            %7B%0A                count++;%0A            %7D%0A        %7D%0A
+++count;%0A        %7D
 %0A   

Simplify calculateBodyLength