116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropackage org.bouncycastle.util.io; 216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.io.ByteArrayOutputStream; 416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.io.IOException; 516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.io.InputStream; 616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.io.OutputStream; 716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro/** 953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * Utility methods to assist with stream processing. 1053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro */ 1116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropublic final class Streams 1216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro{ 13bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro private static int BUFFER_SIZE = 4096; 1416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 1553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro /** 1653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * Read stream till EOF is encountered. 1753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * 1853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param inStr stream to be emptied. 1953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @throws IOException in case of underlying IOException. 2053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro */ 2116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public static void drain(InputStream inStr) 2216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IOException 2316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 2416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] bs = new byte[BUFFER_SIZE]; 2516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro while (inStr.read(bs, 0, bs.length) >= 0) 2616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 2716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 2816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 2916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 3053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro /** 3153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * Read stream fully, returning contents in a byte array. 3253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * 3353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param inStr stream to be read. 3453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @return a byte array representing the contents of inStr. 3553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @throws IOException in case of underlying IOException. 3653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro */ 3716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public static byte[] readAll(InputStream inStr) 3816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IOException 3916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 4016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ByteArrayOutputStream buf = new ByteArrayOutputStream(); 4116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro pipeAll(inStr, buf); 4216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return buf.toByteArray(); 4316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 4416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 4553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro /** 4653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * Read from inStr up to a maximum number of bytes, throwing an exception if more the maximum amount 4753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * of requested data is available. 4853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * 4953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param inStr stream to be read. 5053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param limit maximum number of bytes that can be read. 5153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @return a byte array representing the contents of inStr. 5253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @throws IOException in case of underlying IOException, or if limit is reached on inStr still has data in it. 5353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro */ 5416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public static byte[] readAllLimited(InputStream inStr, int limit) 5516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IOException 5616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 5716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ByteArrayOutputStream buf = new ByteArrayOutputStream(); 5816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro pipeAllLimited(inStr, limit, buf); 5916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return buf.toByteArray(); 6016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 6116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 6253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro /** 6353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * Fully read in buf's length in data, or up to EOF, whichever occurs first, 6453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * 6553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param inStr the stream to be read. 6653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param buf the buffer to be read into. 6753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @return the number of bytes read into the buffer. 6853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @throws IOException in case of underlying IOException. 6953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro */ 7016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public static int readFully(InputStream inStr, byte[] buf) 7116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IOException 7216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 7316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return readFully(inStr, buf, 0, buf.length); 7416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 7516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 7653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro /** 7753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * Fully read in len's bytes of data into buf, or up to EOF, whichever occurs first, 7853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * 7953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param inStr the stream to be read. 8053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param buf the buffer to be read into. 8153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param off offset into buf to start putting bytes into. 8253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param len the number of bytes to be read. 8353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @return the number of bytes read into the buffer. 8453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @throws IOException in case of underlying IOException. 8553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro */ 8616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public static int readFully(InputStream inStr, byte[] buf, int off, int len) 8716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IOException 8816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 8916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int totalRead = 0; 9016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro while (totalRead < len) 9116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 9216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int numRead = inStr.read(buf, off + totalRead, len - totalRead); 9316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (numRead < 0) 9416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 9516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro break; 9616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 9716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro totalRead += numRead; 9816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 9916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return totalRead; 10016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 10116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 10253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro /** 10353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * Write the full contents of inStr to the destination stream outStr. 10453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * 10553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param inStr source input stream. 10653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param outStr destination output stream. 10753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @throws IOException in case of underlying IOException. 10853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro */ 10916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public static void pipeAll(InputStream inStr, OutputStream outStr) 11016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IOException 11116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 11216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] bs = new byte[BUFFER_SIZE]; 11316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int numRead; 11416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro while ((numRead = inStr.read(bs, 0, bs.length)) >= 0) 11516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 11616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro outStr.write(bs, 0, numRead); 11716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 11816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 11916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 12053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro /** 12153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * Write up to limit bytes of data from inStr to the destination stream outStr. 12253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * 12353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param inStr source input stream. 12453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param limit the maximum number of bytes allowed to be read. 12553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @param outStr destination output stream. 12653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * @throws IOException in case of underlying IOException, or if limit is reached on inStr still has data in it. 12753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro */ 12816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public static long pipeAllLimited(InputStream inStr, long limit, OutputStream outStr) 12916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IOException 13016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 13116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro long total = 0; 13216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] bs = new byte[BUFFER_SIZE]; 13316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int numRead; 13416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro while ((numRead = inStr.read(bs, 0, bs.length)) >= 0) 13516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 136bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro if ((limit - total) < numRead) 13716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 13816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new StreamOverflowException("Data Overflow"); 13916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 140bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro total += numRead; 14116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro outStr.write(bs, 0, numRead); 14216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 14316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return total; 14416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 1454caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro 1464caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro public static void writeBufTo(ByteArrayOutputStream buf, OutputStream output) 1474caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro throws IOException 1484caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 1494caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro buf.writeTo(output); 1504caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 15116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro} 152