// -*- c++ -*-

/*
 * Jakelib2 - General purpose C++ library
 * Copyright (C) 2001 Florian Wolff  (florian@donuz.de)
 *
 * 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
 *
 * $Id: InputStream.h,v 1.21 2003/09/13 08:46:07 florian Exp $
 */

#ifndef INCLUDE_JAKELIB2_IO_INPUTSTREAM_H
# define INCLUDE_JAKELIB2_IO_INPUTSTREAM_H

namespace jakelib {
  namespace io {
    class OutputStream;

    /**
     * This abstract class forms the base of the hierarchy of classes that read
     * input as a stream of bytes.
     *
     * It provides a common set of methods for
     * reading bytes from streams. Subclasses implement and extend these
     * methods to read bytes from a particular input source such as a file
     * or network connection.
     *
     * @class InputStream
     * @version $Id: InputStream.h,v 1.21 2003/09/13 08:46:07 florian Exp $
     * @author Florian 'Overflo' Wolff (florian@donuz.de)
     */
    class InputStream : public jakelib::lang::Object
    {
    public:

      /**
       * Reads the next \c jbyte from the stream and returns it as an integer value in the range
       * <tt>0..255</tt>.
       *
       * If the end of the stream is reached, <tt>-1</tt> is returned.
       * <tt>read</tt> blocks if no data is available but the end of the stream is not 
       * reached yet. If non-blocking mode is actived (see \c setBlocking) \c -2
       * is returned if there is no data available.
       *
       * @returns Next \c jbyte from stream or \c -1 if end of stream
       *          reached or \c -2 if non-blocking mode and no data available
       */
      virtual int read() = 0;

      /**
       * Tries to read \a len number of bytes.
       *
       * @return \c -1 if not even a single byte could be read, the
       *         exact number of bytes read otherwise.
       */
      virtual int read(jbyte* b, int offset, int len);

      /**
       * Closes this input stream.
       */
      virtual void close();

      /**
       * Reset the read cursor to next the most recent mark.
       */
      virtual void reset();

      /**
       * @todo To be implemented
       */
      virtual int available();

      /**
       * Skips the specified number of bytes.
       */
      virtual int skip(int n);

      /**
       * @todo To be implemented
       */
      virtual void mark(int readLimit);

      /**
       * @todo To be implemented
       */
      virtual jboolean markSupported();

      /**
       * Copies this InputStream to the specified OutputStream.
       * An internal 8kB buffer is used.
       */
      void copyTo(OutputStream* destination);

      /**
       * Copies this InputStream to the specified OutputStream.
       * An internal 8kB buffer is used.
       * Reads/Writes up to \a maxBytes number of bytes.
       */
      void copyTo(OutputStream* destination, int maxBytes);

      /**
       * @brief Sets the blocking mode. 
       */
      virtual void setBlocking(jboolean on) = 0;

      static const long SKIP_BUFFER_SIZE;

      static jbyte* skipBuffer;

      JAKELIB_DECLARE_CLASS(InputStream);
    };
  }
}
#endif

