Home | History | Annotate | Download | only in io
      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