1package org.bouncycastle.asn1;
2
3import java.io.ByteArrayInputStream;
4import java.io.FileInputStream;
5import java.io.IOException;
6import java.io.InputStream;
7import java.nio.channels.FileChannel;
8
9class StreamUtil
10{
11    // Android-removed: Check max memory at runtime
12    // private static final long  MAX_MEMORY = Runtime.getRuntime().maxMemory();
13
14    /**
15     * Find out possible longest length...
16     *
17     * @param in input stream of interest
18     * @return length calculation or MAX_VALUE.
19     */
20    static int findLimit(InputStream in)
21    {
22        if (in instanceof LimitedInputStream)
23        {
24            return ((LimitedInputStream)in).getRemaining();
25        }
26        else if (in instanceof ASN1InputStream)
27        {
28            return ((ASN1InputStream)in).getLimit();
29        }
30        else if (in instanceof ByteArrayInputStream)
31        {
32            return ((ByteArrayInputStream)in).available();
33        }
34        else if (in instanceof FileInputStream)
35        {
36            try
37            {
38                FileChannel channel = ((FileInputStream)in).getChannel();
39                long  size = (channel != null) ? channel.size() : Integer.MAX_VALUE;
40
41                if (size < Integer.MAX_VALUE)
42                {
43                    return (int)size;
44                }
45            }
46            catch (IOException e)
47            {
48                // ignore - they'll find out soon enough!
49            }
50        }
51
52        // BEGIN Android-changed: Check max memory at runtime
53        long maxMemory = Runtime.getRuntime().maxMemory();
54        if (maxMemory > Integer.MAX_VALUE)
55        {
56            return Integer.MAX_VALUE;
57        }
58
59        return (int) maxMemory;
60        // END Android-changed: Check max memory at runtime
61    }
62
63    static int calculateBodyLength(
64        int length)
65    {
66        int count = 1;
67
68        if (length > 127)
69        {
70            int size = 1;
71            int val = length;
72
73            while ((val >>>= 8) != 0)
74            {
75                size++;
76            }
77
78            for (int i = (size - 1) * 8; i >= 0; i -= 8)
79            {
80                count++;
81            }
82        }
83
84        return count;
85    }
86
87    static int calculateTagLength(int tagNo)
88        throws IOException
89    {
90        int length = 1;
91
92        if (tagNo >= 31)
93        {
94            if (tagNo < 128)
95            {
96                length++;
97            }
98            else
99            {
100                byte[] stack = new byte[5];
101                int pos = stack.length;
102
103                stack[--pos] = (byte)(tagNo & 0x7F);
104
105                do
106                {
107                    tagNo >>= 7;
108                    stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
109                }
110                while (tagNo > 127);
111
112                length += stack.length - pos;
113            }
114        }
115
116        return length;
117    }
118}
119