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...
*
* @param in input stream of interest
* @return length calculation or MAX_VALUE.
*/
static int findLimit(InputStream in)
{
if (in instanceof LimitedInputStream)
{
return ((LimitedInputStream)in).getRemaining();
}
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;
}
}