// ---------------------------------------------------------------------------
// - Input.hpp                                                               -
// - standard object library - input stream base class definition            -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  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.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2008 amaury darsch                                   -
// ---------------------------------------------------------------------------

#ifndef  AFNIX_INPUT_HPP
#define  AFNIX_INPUT_HPP

#ifndef  AFNIX_STREAM_HPP
#include "Stream.hpp"
#endif

#ifndef  AFNIX_BUFFER_HPP
#include "Buffer.hpp"
#endif

namespace afnix {

  /// The input stream class is a base class which provides a read method for
  /// character in a generic way. Various classes are derived from it, like 
  /// the InputTerm or InputFile. The class implements a buffer which provides
  /// a generic pushback method. When the read method is invoked, the character
  /// is placed in the buffer.
  /// @author amaury darsch

  class Input : public Stream {
  protected:
    /// the local buffer
    mutable Buffer d_buffer;

  public:
    /// @return the stream descriptor
    virtual int getsid (void) const;

    /// @return the next available character
    virtual char read (void) =0;

    /// @return the next character in byte mode
    virtual t_quad rbyte (void);

    /// @return the next character in utf8 mode
    virtual t_quad rutf8 (void);

    /// @return the next available unicode character
    virtual t_quad rduc (void);

    /// @return a buffer of character
    /// @param size the number of character to read
    virtual Buffer* read (const long size);

    /// @return the next available line
    virtual String readln (void);

    /// @return true if we are at the eof
    virtual bool iseof (void) const =0;

    /// check if we can read a character
    /// @param tout the timeout value
    virtual bool valid (const long tout) const =0;

    /// push back a character in the input stream.
    /// @param value the character to push back
    virtual void pushback (const char value);

    /// pushback a c-string
    /// @param s the string to pushback
    virtual void pushback (const char* s);

    /// pushback a c-string by size
    /// @param s    the string to pushback
    /// @param size the string size
    virtual void pushback (const char* s, const long size);

    /// pushback a string on this input stream
    virtual void pushback (const String& value);

    /// @return the size of the input buffer
    virtual long buflen (void) const;

    /// flush the input stream until a certain character is found
    /// @param value the blocking character
    virtual void flush (const char value);

    /// flush the input stream until a certain character is found
    /// @param value the blocking character
    virtual void flush (const t_quad value);

  public:
    /// @return true if the given quark is defined
    bool isquark (const long quark, const bool hflg) const;

    /// apply this object with a set of arguments and a quark
    /// @param robj  the current runnable
    /// @param nset  the current nameset    
    /// @param quark the quark to apply these arguments
    /// @param argv  the arguments  to apply
    Object* apply (Runnable* robj, Nameset* nset, const long quark,
		   Vector* argv);
  };
}

#endif
