//    This is part of the iostream library, providing -*- C++ -*- input/output.
//    Copyright (C) 1991 Per Bothner.
//
//    This library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Library General Public
//    License as published by the Free Software Foundation; either
//    version 2 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
//    Library General Public License for more details.
//
//    You should have received a copy of the GNU Library General Public
//    License along with this library; if not, write to the Free
//    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#ifndef _IOSTREAM_H
#pragma interface
#define _IOSTREAM_H
#define Q_ENV

#include <streambuf.h>

class istream; class ostream;
typedef istream& (*__imanip)(istream&);
typedef ostream& (*__omanip)(ostream&);

extern istream& ws(istream& ins);
extern ostream& flush(ostream& outs);
extern ostream& endl(ostream& outs);
extern ostream& ends(ostream& outs);

class ostream : public ios
{
    void do_osfx();
  public:
    ostream();
    ostream(streambuf* sb, ostream* tied=NULL);
    ~ostream();

    int opfx() { if (!good()) return 0; if (_tie) _tie->flush(); return 1; }
    void osfx() { if (flags() & (ios::unitbuf|ios::stdio))
		      do_osfx(); }
    streambuf* ostreambuf() const { return _strbuf; }
    ostream& flush();
    ostream& put(char c);
    ostream& write(const char *s, size_t n);
    ostream& write(const unsigned char *s, size_t n);
    ostream& operator<<(char c);
    ostream& operator<<(unsigned char c) { return *this << (char)c; }
    ostream& operator<<(const char *s);
    ostream& operator<<(const unsigned char *s)
	{ return *this << (const char*)s; }
    ostream& operator<<(void *p);
    ostream& operator<<(short n) {return *this << (int)n;}
    ostream& operator<<(int n);
    ostream& operator<<(long n);
    ostream& operator<<(unsigned short n) {return *this << (unsigned int)n;}
    ostream& operator<<(unsigned int n);
    ostream& operator<<(unsigned long n);
    ostream& operator<<(float n);
    ostream& operator<<(double n);
    ostream& operator<<(__omanip func) { return (*func)(*this); }
    ostream& operator<<(streambuf*);
    ostream& form(const char *format ...);
    ostream& vform(const char *format, void *args); // Should be va_list
    void close();
};

class istream : public ios
{
  public:
    size_t _gcount;
    istream();
    istream(streambuf* sb, ostream*tied=NULL);
    ~istream();
    streambuf* istreambuf() const { return _strbuf; }
    istream& get(char& c);
    istream& get(unsigned char& c);
    int get() { return _strbuf->sbumpc(); }
    istream& getline(char* ptr, int len, char delim = '\n');
    istream& get(char* ptr, int len, char delim = '\n');
    int ipfx(int need) {
	if (!good()) return 0;
	if (_tie && (need == 0 || rdbuf()->in_avail() < need)) _tie->flush();
	if (!need && (flags() & ios::skipws) && !ws(*this)) return 0;
	return 1;
    }
    int ipfx0() { // Optimized version of ipfx(0).
	if (!good()) return 0;
	if (_tie) _tie->flush();
	if ((flags() & ios::skipws) && !ws(*this)) return 0;
	return 1;
    }
    int ipfx1() { // Optimized version of ipfx(1).
	if (!good()) return 0;
	if (_tie && rdbuf()->in_avail() == 0) _tie->flush();
	return 1;
    }
    size_t gcount() { return _gcount; }
    void close();
    istream& operator>>(char*);
    istream& operator>>(unsigned char* p) { return *this >> (char*)p; }
    istream& operator>>(char& c);
    istream& operator>>(unsigned char& c);
    istream& operator>>(int&);
    istream& operator>>(long&);
    istream& operator>>(short&);
    istream& operator>>(unsigned int&);
    istream& operator>>(unsigned long&);
    istream& operator>>(unsigned short&);
    istream& operator>>(float&);
    istream& operator>>(double&);
    istream& operator>>(__imanip func) { return (*func)(*this); }
    istream& putback(char ch) {
	if (good() && _strbuf->sputbackc(ch) == EOF) clear(ios::failbit);
	return *this;}
};

#if 0
class iostream : public istream, public ostream /*, virtual public ios*/ {
  public:
  iostream();
  iostream(FILE *in, FILE *out);
  iostream(FILE *shared);
  ~iostream();
};
#endif

extern istream cin;
extern ostream cout, cerr, clog; // clog->rdbuf() == cerr->rdbuf()

inline ostream& ostream::put(char c) { _strbuf->sputc(c); return *this; }
inline ostream& ostream::write(const char *s, size_t n)
{
    _strbuf->sputn(s, n);
    return *this;
}
inline ostream& ostream::write(const unsigned char *s, size_t n)
{
    _strbuf->sputn((const char*)s, n);
    return *this;
}

#endif /*!_IOSTREAM_H*/
