//
// $Id$
//
// samskivert library - useful routines for java programs
// Copyright (C) 2001-2007 Michael Bayne
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.samskivert.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Writer;
import java.io.Reader;
import java.nio.charset.Charset;

import static com.samskivert.Log.log;

/**
 * Convenience methods for streams.
 */
public class StreamUtil
{
    /**
     * Convenient close for a stream. Use in a finally clause and love life.
     */
    public static void close (InputStream in)
    {
        if (in != null) {
            try {
                in.close();
            } catch (IOException ioe) {
                log.warning("Error closing input stream", "stream", in, "cause", ioe);
            }
        }
    }

    /**
     * Convenient close for a stream. Use in a finally clause and love life.
     */
    public static void close (OutputStream out)
    {
        if (out != null) {
            try {
                out.close();
            } catch (IOException ioe) {
                log.warning("Error closing output stream", "stream", out, "cause", ioe);
            }
        }
    }

    /**
     * Convenient close for a Reader. Use in a finally clause and love life.
     */
    public static void close (Reader in)
    {
        if (in != null) {
            try {
                in.close();
            } catch (IOException ioe) {
                log.warning("Error closing reader", "reader", in, "cause", ioe);
            }
        }
    }

    /**
     * Convenient close for a Writer. Use in a finally clause and love life.
     */
    public static void close (Writer out)
    {
        if (out != null) {
            try {
                out.close();
            } catch (IOException ioe) {
                log.warning("Error closing writer", "writer", out, "cause", ioe);
            }
        }
    }

    /**
     * Reads the contents of the supplied stream into a string using the supplied {@link Charset}.
     */
    public static String toString (InputStream stream, String charset)
        throws IOException
    {
        InputStreamReader reader = new InputStreamReader(stream, charset);
        char[] inbuf = new char[4096];
        StringBuffer outbuf = new StringBuffer();
        for (int read = 0; (read = reader.read(inbuf)) > 0; ) {
            outbuf.append(inbuf, 0, read);
        }
        return outbuf.toString();
    }

    /**
     * Copies the contents of the supplied input stream to the supplied output stream.
     */
    public static void copy (InputStream in, OutputStream out)
        throws IOException
    {
        byte[] buffer = new byte[4096];
        for (int read = 0; (read = in.read(buffer)) > 0; ) {
            out.write(buffer, 0, read);
        }
    }
}

@@ -2683,20 +2683,21 @@
 %0A     * 
-Read
+Copie
 s the co
@@ -2723,291 +2723,196 @@
 ied 
+input 
 stream 
-in
 to 
-a string using the supplied %7B@link Charset%7D.%0A     */%0A    public static String toString (InputStream stream, String charset)%0A        throws IOException%0A    %7B%0A        InputStreamReader reader = new InputStreamReader(stream, charset);%0A        char
+the supplied output stream.%0A     */%0A    public static void copy (InputStream in, OutputStream out)%0A        throws IOException%0A    %7B%0A        byte
 %5B%5D 
-in
 buf
+fer
  = new 
-char
+byte
 %5B4096%5D;%0A
     
@@ -2911,58 +2911,8 @@
 6%5D;%0A
-        StringBuffer outbuf = new StringBuffer();%0A
     
@@ -2946,25 +2946,22 @@
 d = 
-reader
+in
 .read(
-in
 buf
+fer
 )) %3E
@@ -2987,24 +2987,21 @@
  out
-buf.append(inbuf
+.write(buffer
 , 0,
@@ -3022,42 +3022,8 @@
   %7D%0A
-        return outbuf.toString();%0A
     
@@ -3032,37 +3032,36 @@
 %0A    /**%0A     * 
-Copie
+Read
 s the contents o
@@ -3079,194 +3079,499 @@
 ied 
-input 
 stream 
+in
 to 
-the supplied output stream.%0A     */%0A    public static void copy (InputStream in, OutputStream out)%0A        throws IOException%0A    %7B%0A        byte%5B%5D buffer = new byte%5B4096%5D
+a string using the supplied %7B@link Charset%7D.%0A     */%0A    public static String toString (InputStream stream, String charset)%0A        throws IOException%0A    %7B%0A        return toString(new InputStreamReader(stream, charset));%0A    %7D%0A%0A    /**%0A     * Reads the contents of the supplied reader into a string.%0A     */%0A    public static String toString (Reader reader)%0A        throws IOException%0A    %7B%0A        char%5B%5D inbuf = new char%5B4096%5D;%0A        StringBuffer outbuf = new StringBuffer()
 ;%0A  
@@ -3599,38 +3599,41 @@
  0; (read = 
-in
+reader
 .read(
+in
 buf
-fer
 )) %3E 0; ) %7B%0A
@@ -3643,37 +3643,40 @@
          out
-.write(buffer
+buf.append(inbuf
 , 0, read);%0A
@@ -3681,20 +3681,54 @@
 ;%0A        %7D%0A
+        return outbuf.toString();%0A
     %7D%0A%7D%0A

Allow code that already has a reader to rock right on as well.