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

#ifndef INCLUDE_JAKELIB2_IO_BUFFEREDREADER_H
# define INCLUDE_JAKELIB2_IO_BUFFEREDREADER_H
# include "Reader.h"
# include "../lang/Synchronizeable.h"

namespace jakelib {
  namespace io {

    /**
     * \c BufferedReader provides a \c Reader that uses an internal
     * buffer to improve performance when subsequently reading single
     * characters.
     *
     * It also provides the \c readString() method that reads a full line
     * of text (until the next newline character).
     *
     * @todo skip / mark / reset
     *
     * @class BufferedReader
     * @version $Id: BufferedReader.h,v 1.24 2003/09/13 10:29:03 florian Exp $
     * @author Florian 'Overflo' Wolff (florian@donuz.de)
     */
    class BufferedReader : public Reader,
                           public jakelib::lang::Synchronizeable
    {
    public:

      /**
       * @brief Creates a new \c BufferedReader from a given \c Reader object.
       * Uses the given \c bufferSize to allocate the input buffer.
       *
       * @param reader The \c Reader to be buffered.
       * @param bufferSize Buffer size in bytes, default is 8kB.
       */
      BufferedReader(Reader* reader, int bufferSize = 8192);

      /**
       * @brief The destructor.
       */
      ~BufferedReader();

      /**
       * Reads a full line of text. I.e. all characters up to the next newline.
       *
       * @todo \c skipLF does nothing!
       */
      virtual jakelib::lang::String* readLine(jboolean skipLF = false);

      /**
       * Skips the specified number of bytes.
       *
       * @todo To be implemented!
       */
      int skip(int n);

      /**
       * Determines whether the next \c read() call is guarantied not to block.
       * I.e. if the buffer is not empty.
       */
      jboolean ready();

      /**
       * Returns \c false since \c BufferedReader does not yet support
       * marking.
       *
       * @todo To be implemented!
       */
      jboolean markSupported();

      /**
       * 
       *
       * @todo To be implemented!
       */
      void mark(int readAheadLimit);

      /**
       * Reset the read cursor to next the most recent mark.
       *
       * @todo To be implemented!
       */
      void reset();

      void close();

      virtual int read();

      virtual int read(jchar* buf, int offset, int len);

    private:

      /** @brief The current buffer size */
      int bufferSize;

      Reader* reader;
      jchar* buffer;

      int nChars;
      int nextChar;

      /**
       * @throws IOException If the reader is closed
       */
      void ensureOpen();

      /**
       * @brief (Re)Fills the input buffer.
       */
      void fill();

      JAKELIB_DECLARE_CLASS(BufferedReader);
    };

  }
}
#endif

