#ifndef cathlibcpp_poscmds_H
#define cathlibcpp_poscmds_H

// File:       poscmds.h
// Author:     (c) Miles Sabin, 1997
// Purpose:    private header for ostream command classes.


#ifndef cathlibcpp_bool_H
#include "bool.h"
#endif

#ifndef cathlibcpp_config_H
#include "config.h"
#endif

#ifndef cathlibcpp_ios_H
#include "ios.h"
#endif


class basic_ostream_char;


class OStreamCommand
{
  public:

    // constructors
    OStreamCommand();
    virtual ~OStreamCommand();

  protected:

    // mutators
    void execute_template(basic_ostream_char& os);

    virtual ios::iostate execute(basic_ostream_char& os) = 0;

    ios::iostate insert_fill(basic_ostream_char& os, char fill_char, int width);

    void set_rethrow()
      { rethrow_ = true; }

  private:

    // not implemented
    OStreamCommand(OStreamCommand const&);
    OStreamCommand& operator=(OStreamCommand const&);

    bool rethrow_;
};


class InsertStringCommand : public OStreamCommand
{
  public:

    // constructors
    InsertStringCommand(basic_ostream_char& os, char const* s, int n, int width);
    ~InsertStringCommand();

  protected:

    // mutators
    ios::iostate execute(basic_ostream_char& os);

  protected:

    char const* s_;
    int n_;
    int width_;
};


class InsertIntegralCommand : public OStreamCommand
{
  public:

    // constructors
    InsertIntegralCommand(basic_ostream_char& os, long n, bool is_unsigned = false);
    ~InsertIntegralCommand();

  protected:

    // mutators
    ios::iostate execute(basic_ostream_char& os);

  private:

    long n_;
    bool is_unsigned_;
};


class InsertStreamBufCommand : public OStreamCommand
{
  public:

    // constructors
    InsertStreamBufCommand(basic_ostream_char& os, basic_streambuf_char* isb);
    ~InsertStreamBufCommand();

  protected:

    // mutators
    ios::iostate execute(basic_ostream_char& os);

  private:

    basic_streambuf_char* isb_;
};


class PutCommand : public OStreamCommand
{
  public:

    // constructors
    PutCommand(basic_ostream_char& os, char c);
    ~PutCommand();

  protected:

    // mutators
    ios::iostate execute(basic_ostream_char& os);

  private:

    char c_;
};


class WriteCommand : public OStreamCommand
{
  public:

    // constructors
    WriteCommand(basic_ostream_char& os, char const* s, streamsize n);
    ~WriteCommand();

  protected:

    // mutators
    ios::iostate execute(basic_ostream_char& os);

  private:

    char const* s_;
    streamsize n_;
};


class FlushCommand : public OStreamCommand
{
  public:

    // constructors
    FlushCommand(basic_ostream_char& os);
    ~FlushCommand();

  protected:

    // mutators
    ios::iostate execute(basic_ostream_char& os);
};


class OStreamSeekoffCommand : public OStreamCommand
{
  public:

    // constructors
    OStreamSeekoffCommand(basic_ostream_char& os, int off, ios::seekdir way, ios::openmode which = ios::in|ios::out);
    ~OStreamSeekoffCommand();

    // accessors
    int as_int() const
      { return result_; }

  protected:

    // mutators
    ios::iostate execute(basic_ostream_char& os);

  private:

    int off_;
    ios::seekdir way_;
    ios::openmode which_;
    int result_;
};


class OStreamSeekposCommand : public OStreamCommand
{
  public:

    // constructors
    OStreamSeekposCommand(basic_ostream_char& os, int sp, ios::openmode which = ios::in|ios::out);
    ~OStreamSeekposCommand();

    // accessors
    int as_int() const
      { return result_; }

  protected:

    // mutators
    ios::iostate execute(basic_ostream_char& os);

  private:

    int sp_;
    ios::openmode which_;
    int result_;
};

#endif



