/* LineInputStream.java --
   Copyright (C) 2002, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath 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
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.net;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * An input stream that can read lines of input.
 *
 * @author Chris Burdess (dog@gnu.org)
 */
public class LineInputStream
  extends InputStream
{

  /**
   * The underlying input stream.
   */
  protected InputStream in;
  
  /*
   * Line buffer.
   */
  private ByteArrayOutputStream buf;

  /*
   * Encoding to use when translating bytes to characters.
   */
  private String encoding;

  /*
   * End-of-stream flag.
   */
  private boolean eof;

  /**
   * Whether we can use block reads.
   */
  private final boolean blockReads;

  /**
   * Constructor using the US-ASCII character encoding.
   * @param in the underlying input stream
   */
  public LineInputStream(InputStream in)
  {
    this(in, "US-ASCII");
  }

  /**
   * Constructor.
   * @param in the underlying input stream
   * @param encoding the character encoding to use
   */
  public LineInputStream(InputStream in, String encoding)
  {
    this.in = in;
    buf = new ByteArrayOutputStream();
    this.encoding = encoding;
    eof = false;
    // If it is already buffered, additional buffering gains nothing.
    blockReads = !(in instanceof BufferedInputStream) && in.markSupported();
  }

  public int read()
    throws IOException
  {
    return in.read();
  }

  public int read(byte[] buf)
    throws IOException
  {
    return in.read(buf);
  }
  
  public int read(byte[] buf, int off, int len)
    throws IOException
  {
    return in.read(buf, off, len);
  }

  /**
   * Read a line of input.
   */
  public String readLine()
    throws IOException
  {
    if (eof)
      {
        return null;
      }
    do
      {
        if (blockReads)
          {
            // Use mark and reset to read chunks of bytes
            final int MAX_LENGTH = 1024;
            int len, pos;

            len = in.available();
            if (len == 0 || len > MAX_LENGTH)
              len = MAX_LENGTH;
            byte[] b = new byte[len];
            in.mark(len);
            // Read into buffer b
            len = in.read(b, 0, len);
            // Handle EOF
            if (len == -1)
              {
                eof = true;
                if (buf.size() == 0)
                  {
                    return null;
                  }
                else
                  {
                    // We don't care about resetting buf
                    return buf.toString(encoding);
                  }
              }
            // Get index of LF in b
            pos = indexOf(b, len, (byte) 0x0a);
            if (pos != -1)
              {
                // Write pos bytes to buf
                buf.write(b, 0, pos);
                // Reset stream, and read pos + 1 bytes
                in.reset();
                pos += 1;
                while (pos > 0)
                  {
                    len = in.read(b, 0, pos);
                    pos = (len == -1) ? -1 : pos - len;
                  }
                // Return line
                String ret = buf.toString(encoding);
                buf.reset();
                return ret;
              }
            else
              {
                // Append everything to buf and fall through to re-read.
                buf.write(b, 0, len);
              }
          }
        else
          {
            // We must use character reads in order not to read too much
            // from the underlying stream.
            int c = in.read();
            switch (c)
              {
              case -1:
                eof = true;
                if (buf.size() == 0)
                  {
                    return null;
                  }
                // Fall through and return contents of buffer.
              case 0x0a:                // LF
                String ret = buf.toString(encoding);
                buf.reset();
                return ret;
              default:
                buf.write(c);
              }
          }
      }
    while (true);
  }

  private int indexOf(byte[] b, int len, byte c)
  {
    for (int pos = 0; pos < len; pos++)
      {
        if (b[pos] == c)
          {
            return pos;
          }
      }
    return -1;
  }
}

