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