// -*- 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: Reader.h,v 1.20 2003/09/13 10:29:03 florian Exp $
 */

#ifndef INCLUDE_JAKELIB2_IO_READER_H
# define INCLUDE_JAKELIB2_IO_READER_H

namespace jakelib {
  namespace lang {
    class Synchronizeable;
  }
  namespace io {

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

    public:
      Reader();

      Reader(jakelib::lang::Synchronizeable* lock);

      ~Reader();

      /**
       * Reads the next character. Returns \c -1 if no more characters are
       * available.
       *
       * @return The character read (\c 0x00 .. \c 0xffff) or \c -1 if
       *         the end of the input stream is reached.
       */
      virtual jint read();

      /**
       * Tries to read \a len characters from the underlaying input stream.
       *
       * @param buf The destination array.
       * @param offset Offset in the destination array.
       * @param len The number of characters to read.
       * @return \c -1 if not even one character could be read, otherwise the
       *         number of characters actually read.
       */
      virtual int read(jchar* buf, int offset, int len) = 0;

      /**
       * Skips the number of specified characters from the input
       * stream.
       */
      virtual int skip(int n);

      /**
       * Determines whether the next \c read() call is guarantied not to block.
       */
      virtual jboolean ready();

      /**
       * Determines whether \c mark() is supported by a certain 
       * subclass of \c Reader.
       */
      virtual jboolean markSupported();

      /**
       * Marks the current position in the input streams.
       * Subsequent calles to \c reset() will reset the stream
       * to this very position.
       *
       * @see markSupported()
       */
      virtual void mark(int readAheadLimit);

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

      /**
       * Closes the underlaying \c Reader or \c InputStream.
       */
      virtual void close() = 0;

    protected:

      /** The Object on which to synchronize */
      jakelib::lang::Synchronizeable* lock;

    private:
      jchar* skipBuffer;

      static const int maxSkipBufferSize;

      JAKELIB_DECLARE_CLASS(Reader);
    };

  }
}
#endif

