package at.gv.egovernment.moa.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
 * Utility methods for streams.
 * 
 * @author Patrick Peck
 * @version $Id$
 */
public class StreamUtils {
  
  /**
   * Compare the contents of two InputStreams.
   * 
   * @param is1 The 1st InputStream to compare.
   * @param is2 The 2nd InputStream to compare.
   * @return boolean true, if both streams contain the exactly the
   * same content, false otherwise.
   * @throws IOException An error occurred reading one of the streams.
   */
  public static boolean compareStreams(InputStream is1, InputStream is2) 
    throws IOException {
      
    byte[] buf1 = new byte[256];
    byte[] buf2 = new byte[256];
    int length1;
    int length2;
  
    try {
      while (true) {
        length1 = is1.read(buf1);
        length2 = is2.read(buf2);
        
        if (length1 != length2) {
          return false;
        }
        if (length1 <= 0) {
          return true;
        }
        if (!compareBytes(buf1, buf2, length1)) {
          return false;
        }
      }
    } catch (IOException e) {
      throw e;
    } finally {
      // close both streams
      try {
        is1.close();
        is2.close();
      } catch (IOException e) {
        // ignore this
      }
    }
  }
  
  /**
   * Compare two byte arrays, up to a given maximum length.
   * 
   * @param b1 1st byte array to compare.
   * @param b2 2nd byte array to compare.
   * @param length The maximum number of bytes to compare.
   * @return true, if the byte arrays are equal, false
   * otherwise.
   */
  private static boolean compareBytes(byte[] b1, byte[] b2, int length) {
    if (b1.length != b2.length) {
      return false;
    }
  
    for (int i = 0; i < b1.length && i < length; i++) {
      if (b1[i] != b2[i]) {
        return false;
      }
    }
  
    return true;
  }
  /**
   * Reads a byte array from a stream.
   * @param in The InputStream to read.
   * @return The bytes contained in the given InputStream.
   * @throws IOException on any exception thrown
   */
  public static byte[] readStream(InputStream in) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    int b;
    while ((b = in.read()) >= 0)
      out.write(b);
    in.close();
    return out.toByteArray();
  }
  /**
   * Reads a String from a stream, using given encoding.
   * @param in The InputStream to read.
   * @param encoding The character encoding to use for converting the bytes
   * of the InputStream into a String.
   * @return The content of the given InputStream converted into
   * a String.
   * @throws IOException on any exception thrown
   */
  public static String readStream(InputStream in, String encoding) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    int b;
    while ((b = in.read()) >= 0)
      out.write(b);
    in.close();
    return out.toString(encoding);
  }
 
}