1 package org.bouncycastle.util.io; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.OutputStream; 7 8 /** 9 * Utility methods to assist with stream processing. 10 */ 11 public final class Streams 12 { 13 private static int BUFFER_SIZE = 4096; 14 15 /** 16 * Read stream till EOF is encountered. 17 * 18 * @param inStr stream to be emptied. 19 * @throws IOException in case of underlying IOException. 20 */ 21 public static void drain(InputStream inStr) 22 throws IOException 23 { 24 byte[] bs = new byte[BUFFER_SIZE]; 25 while (inStr.read(bs, 0, bs.length) >= 0) 26 { 27 } 28 } 29 30 /** 31 * Read stream fully, returning contents in a byte array. 32 * 33 * @param inStr stream to be read. 34 * @return a byte array representing the contents of inStr. 35 * @throws IOException in case of underlying IOException. 36 */ 37 public static byte[] readAll(InputStream inStr) 38 throws IOException 39 { 40 ByteArrayOutputStream buf = new ByteArrayOutputStream(); 41 pipeAll(inStr, buf); 42 return buf.toByteArray(); 43 } 44 45 /** 46 * Read from inStr up to a maximum number of bytes, throwing an exception if more the maximum amount 47 * of requested data is available. 48 * 49 * @param inStr stream to be read. 50 * @param limit maximum number of bytes that can be read. 51 * @return a byte array representing the contents of inStr. 52 * @throws IOException in case of underlying IOException, or if limit is reached on inStr still has data in it. 53 */ 54 public static byte[] readAllLimited(InputStream inStr, int limit) 55 throws IOException 56 { 57 ByteArrayOutputStream buf = new ByteArrayOutputStream(); 58 pipeAllLimited(inStr, limit, buf); 59 return buf.toByteArray(); 60 } 61 62 /** 63 * Fully read in buf's length in data, or up to EOF, whichever occurs first, 64 * 65 * @param inStr the stream to be read. 66 * @param buf the buffer to be read into. 67 * @return the number of bytes read into the buffer. 68 * @throws IOException in case of underlying IOException. 69 */ 70 public static int readFully(InputStream inStr, byte[] buf) 71 throws IOException 72 { 73 return readFully(inStr, buf, 0, buf.length); 74 } 75 76 /** 77 * Fully read in len's bytes of data into buf, or up to EOF, whichever occurs first, 78 * 79 * @param inStr the stream to be read. 80 * @param buf the buffer to be read into. 81 * @param off offset into buf to start putting bytes into. 82 * @param len the number of bytes to be read. 83 * @return the number of bytes read into the buffer. 84 * @throws IOException in case of underlying IOException. 85 */ 86 public static int readFully(InputStream inStr, byte[] buf, int off, int len) 87 throws IOException 88 { 89 int totalRead = 0; 90 while (totalRead < len) 91 { 92 int numRead = inStr.read(buf, off + totalRead, len - totalRead); 93 if (numRead < 0) 94 { 95 break; 96 } 97 totalRead += numRead; 98 } 99 return totalRead; 100 } 101 102 /** 103 * Write the full contents of inStr to the destination stream outStr. 104 * 105 * @param inStr source input stream. 106 * @param outStr destination output stream. 107 * @throws IOException in case of underlying IOException. 108 */ 109 public static void pipeAll(InputStream inStr, OutputStream outStr) 110 throws IOException 111 { 112 byte[] bs = new byte[BUFFER_SIZE]; 113 int numRead; 114 while ((numRead = inStr.read(bs, 0, bs.length)) >= 0) 115 { 116 outStr.write(bs, 0, numRead); 117 } 118 } 119 120 /** 121 * Write up to limit bytes of data from inStr to the destination stream outStr. 122 * 123 * @param inStr source input stream. 124 * @param limit the maximum number of bytes allowed to be read. 125 * @param outStr destination output stream. 126 * @throws IOException in case of underlying IOException, or if limit is reached on inStr still has data in it. 127 */ 128 public static long pipeAllLimited(InputStream inStr, long limit, OutputStream outStr) 129 throws IOException 130 { 131 long total = 0; 132 byte[] bs = new byte[BUFFER_SIZE]; 133 int numRead; 134 while ((numRead = inStr.read(bs, 0, bs.length)) >= 0) 135 { 136 if ((limit - total) < numRead) 137 { 138 throw new StreamOverflowException("Data Overflow"); 139 } 140 total += numRead; 141 outStr.write(bs, 0, numRead); 142 } 143 return total; 144 } 145 146 public static void writeBufTo(ByteArrayOutputStream buf, OutputStream output) 147 throws IOException 148 { 149 buf.writeTo(output); 150 } 151 } 152