/* C++ Stream I/O header file Copyright (c) Borland International 1987,1988,1990 All Rights Reserved. %W% %G% %U% NOTE: The data and function variables are declared so that any combination of alignment and size-of-enum compiler options will produce the same results. */ #if ! defined(_I_STREAM_H_) // protect against multiple inclusion #define _I_STREAM_H_ #include /* * whitespace */ struct whitespace { char x; }; extern struct whitespace WS; class istream; class ostream; /* * basic stream buffer class */ class streambuf { friend istream; friend ostream; protected: FILE *file; // if non-0, connected stdio file char *base; // start of buffer char *pptr; // next free char (for output) char *gptr; // next avail char (for input) char *eptr; // one off end of buffer int didalloc; // non-0 if we allocated a buffer // empty full output buffer, put c in it virtual int _Cdecl overflow( int = EOF ); // fill empty input buffer, get first char virtual int _Cdecl underflow(); // allocate a buffer int _Cdecl allocate(); // specify a buffer to use, possibly with data in it (offset > 0 ) streambuf * _Cdecl setbuf( char *, int, unsigned = 0 ); // add a null byte to a string without advancing pointer virtual void _Cdecl terminate(); public: // constructor: no buffer _Cdecl streambuf() { file = 0; didalloc = 0; base = pptr = gptr = eptr = 0; } // constructor: user buffer _Cdecl streambuf( char *buf, int len ) { file = 0; didalloc = 0; setbuf(buf, len); } // destructor virtual _Cdecl ~streambuf(); // get next char from input buffer virtual int _Cdecl snextc(); // write a char to output buffer virtual int _Cdecl sputc( int ); // return a char to input buffer virtual void _Cdecl sputbackc( char ); }; /* * file buffer class */ enum open_mode { input, output, append }; // mode for opening a file class filebuf: public streambuf { private: int fd; // external file id int isopen; // non-0 if open protected: // we don't need to add a null byte to a file void _Cdecl terminate() { }; public: _Cdecl filebuf() { isopen = 0; fd = 0; } // basic constructor _Cdecl filebuf( FILE * ); // tie to existing stdio file _Cdecl filebuf( int ); // tie to existing file _Cdecl filebuf( int , char *, int ); // tie to file, user buffer _Cdecl ~filebuf() { close(); } // destructor (virtual) // open a named external file filebuf * _Cdecl open( char *, int ); // close the external file int _Cdecl close(); // get next char from input buffer int _Cdecl snextc() { return ::fgetc(file); } // write a char to output buffer int _Cdecl sputc( int _C ) { return ::fputc(_C, file); } // return a char to input buffer void _Cdecl sputbackc( char _C ) { (void) ::ungetc(_C, file); } }; /* * formatting functions */ char * _Cdecl dec( long, int = 0 ); // internal to decimal text char * _Cdecl hex( long, int = 0 ); // internal to hex text char * _Cdecl oct( long, int = 0 ); // internal to octal text char * _Cdecl chr( int, int = 0 ); // char to string char * _Cdecl str( const char *, int = 0 ); // make fixed-width string char * _Cdecl form( char * ... ); // general formating /* * state of istream or ostream */ enum stream_state { _good, _eof, _fail, _bad }; /* * class ostream */ class ostream { friend istream; private: streambuf *stream; // connected streambuf or filebuf char mystream; // non-0 if stream was alloc'd here char state; // state of stream public: _Cdecl ostream( streambuf * ); // connect to existing streambuf _Cdecl ostream( int ); // connect to open file _Cdecl ostream( int, char * ); // connect to char array _Cdecl ~ostream() { // destructor (void) flush(); if( mystream ) delete stream; } // test the stream _Cdecl operator void*() { return (state==_good) ? this : 0; } int _Cdecl operator !() { return (state != _good); } ostream& _Cdecl operator << ( int ); // write a char, uns char, short, or int ostream& _Cdecl operator << ( long ); // write a long ostream& _Cdecl operator << ( unsigned int _U ) { // write uns short, uns int return *this << ((long) _U); } ostream& _Cdecl operator << ( unsigned long ); // write unsigned long ostream& _Cdecl operator << ( const char * ); // write a string ostream& _Cdecl operator << ( double ); // write floating-point ostream& _Cdecl operator << ( long double ); // write floating-point ostream& _Cdecl put( char _C ) { // write char as a char if( stream->sputc(_C) == EOF ) state = _fail; return *this; } ostream& _Cdecl flush(); // flush output buffer // return stream state int _Cdecl rdstate() { return state; } // set stream state void _Cdecl clear( int _S = _good ) { state = _S; } // non-0 if bad int _Cdecl bad() { return (state >= _bad); } // non-0 if bad or failed int _Cdecl fail() { return (state >= _fail); } // non-0 if end of input int _Cdecl eof() { return (state == _eof); } // non-0 if ok int _Cdecl good() { return (state == _good); } }; /* * class istream */ class istream { friend ostream; friend void _Cdecl eatwhite( istream & _S ) { _S >> WS; } private: ostream *tied_to; // tied ostream, if non-0 streambuf *stream; // connected streambuf or filebuf char skipping; // non-0 if skipping whitespace char mystream; // non-0 if stream was alloc'd here int state; // state of stream void _Cdecl checkskip( int&, int& ); // used internally long _Cdecl get_long( int ); // used internally public: // connect to streambuf or filebuf _Cdecl istream( streambuf *, int = 1, ostream * = 0 ); // connect to string _Cdecl istream( int, char *, int = 1 ); // connect to open file _Cdecl istream( int, int = 1, ostream * = 0 ); // destructor _Cdecl ~istream() { if( mystream ) delete stream; } // test the stream _Cdecl operator void*() { return (state==_good) ? this : 0; } int _Cdecl operator !() { return (state != _good); } /* * input functions */ istream& _Cdecl operator >> ( signed char& _C ) { unsigned char _X; *this >> _X; if( state == _good ) _C = (signed char) _X; return *this; } istream& _Cdecl operator >> ( short& _S ) { short _T = (short) get_long(0); if( state == _good ) _S = _T; return *this; } istream& _Cdecl operator >> ( int& _I ) { int _T = (int) get_long(0); if( state == _good ) _I = _T; return *this; } istream& _Cdecl operator >> ( long& _L ) { long _T = get_long(0); if( state == _good ) _L = _T; return *this; } istream& _Cdecl operator >> ( unsigned char& ); istream& _Cdecl operator >> ( unsigned short& _S ) { unsigned short _T = (unsigned short) get_long(1); if( state == _good ) _S = _T; return *this; } istream& _Cdecl operator >> ( unsigned int& _I ) { unsigned int _T = (unsigned int) get_long(1); if( state == _good ) _I = _T; return *this; } istream& _Cdecl operator >> ( unsigned long& _L ) { unsigned long _T = (unsigned long) get_long(1); if( state == _good ) _L = _T; return *this; } istream& _Cdecl operator >> ( float& ); istream& _Cdecl operator >> ( double& ); istream& _Cdecl operator >> ( long double& ); istream& _Cdecl operator >> ( char * ); istream& _Cdecl operator >> ( whitespace& ); istream& _Cdecl get(char& ); istream& _Cdecl get(char *, int, int = '\n' ); // set skipping state int _Cdecl skip( int _S ) { short _T = skipping; skipping = _S; return _T; } // tie to ostream ostream * _Cdecl tie( ostream *_To ) { ostream *_T = tied_to; tied_to = _To; return _T; } // return a character to input void _Cdecl putback( char _C ) { stream->sputbackc(_C); }; // return stream state int _Cdecl rdstate() { return state; } // set stream state void _Cdecl clear( int _S = _good ) { state = _S; } // non-0 if bad int _Cdecl bad() { return (state >= _bad); } // non-0 if bad or failed int _Cdecl fail() { return (state >= _fail); } // non-0 if end of input int _Cdecl eof() { return (state == _eof); } // non-0 if ok int _Cdecl good() { return (state == _good); } }; extern istream _Cdecl cin; extern ostream _Cdecl cout; extern ostream _Cdecl cerr; #endif