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