|
|
1.1 ! root 1: /* This is part of libio/iostream, providing -*- C++ -*- input/output. ! 2: Copyright (C) 1993 Free Software Foundation ! 3: ! 4: This file is part of the GNU IO Library. This library is free ! 5: software; you can redistribute it and/or modify it under the ! 6: terms of the GNU General Public License as published by the ! 7: Free Software Foundation; either version 2, or (at your option) ! 8: any later version. ! 9: ! 10: This library is distributed in the hope that it will be useful, ! 11: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 13: GNU General Public License for more details. ! 14: ! 15: You should have received a copy of the GNU General Public License ! 16: along with GNU CC; see the file COPYING. If not, write to ! 17: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 18: ! 19: As a special exception, if you link this library with files ! 20: compiled with a GNU compiler to produce an executable, this does not cause ! 21: the resulting executable to be covered by the GNU General Public License. ! 22: This exception does not however invalidate any other reasons why ! 23: the executable file might be covered by the GNU General Public License. */ ! 24: ! 25: #ifndef _STREAMBUF_H ! 26: #define _STREAMBUF_H ! 27: #ifdef __GNUG__ ! 28: #pragma interface ! 29: #pragma cplusplus ! 30: #endif ! 31: ! 32: /* #define _G_IO_THROW */ /* Not implemented: ios::failure */ ! 33: ! 34: //extern "C" { ! 35: #include <libio.h> ! 36: //} ! 37: //#include <_G_config.h> ! 38: #ifdef _IO_NEED_STDARG_H ! 39: #ifdef __cplusplus ! 40: extern "C" { ! 41: #endif ! 42: #include <stdarg.h> ! 43: #ifdef __cplusplus ! 44: } ! 45: #endif ! 46: #endif ! 47: #ifndef _IO_va_list ! 48: #define _IO_va_list char * ! 49: #endif ! 50: ! 51: #ifndef EOF ! 52: #define EOF (-1) ! 53: #endif ! 54: #ifndef NULL ! 55: #ifdef __GNUC__ ! 56: #define NULL ((void*)0) ! 57: #else ! 58: #define NULL (0) ! 59: #endif ! 60: #endif ! 61: ! 62: #ifndef _IO_wchar_t ! 63: #define _IO_wchar_t short ! 64: #endif ! 65: ! 66: class istream; /* Work-around for a g++ name mangling bug. */ ! 67: class ostream; class streambuf; ! 68: ! 69: // In case some header files defines these as macros. ! 70: #undef open ! 71: #undef close ! 72: ! 73: extern "C" int __underflow(struct _IO_FILE*); ! 74: extern "C" int __overflow(struct _IO_FILE*, int); ! 75: ! 76: typedef _IO_off_t streamoff; ! 77: typedef _IO_fpos_t streampos; ! 78: typedef _IO_ssize_t streamsize; ! 79: ! 80: typedef unsigned long __fmtflags; ! 81: typedef unsigned char __iostate; ! 82: ! 83: struct _ios_fields ! 84: { // The data members of an ios. ! 85: // Directly using _strbuf is dangerous, because the vtable ! 86: // pointer can be NULL. Use rdbuf() when in doubt. ! 87: streambuf *_strbuf; ! 88: ostream* _tie; ! 89: int _width; ! 90: __fmtflags _flags; ! 91: _IO_wchar_t _fill; ! 92: __iostate _state; ! 93: __iostate _exceptions; ! 94: int _precision; ! 95: ! 96: void *_arrays; /* Support for ios::iword and ios::pword. */ ! 97: }; ! 98: ! 99: #define _IOS_GOOD 0 ! 100: #define _IOS_EOF 1 ! 101: #define _IOS_FAIL 2 ! 102: #define _IOS_BAD 4 ! 103: ! 104: #define _IO_INPUT 1 ! 105: #define _IO_OUTPUT 2 ! 106: #define _IO_ATEND 4 ! 107: #define _IO_APPEND 8 ! 108: #define _IO_TRUNC 16 ! 109: #define _IO_NOCREATE 32 ! 110: #define _IO_NOREPLACE 64 ! 111: #define _IO_BIN 128 ! 112: ! 113: #ifdef _STREAM_COMPAT ! 114: enum state_value { ! 115: _good = _IOS_GOOD, ! 116: _eof = _IOS_EOF, ! 117: _fail = _IOS_FAIL, ! 118: _bad = _IOS_BAD }; ! 119: enum open_mode { ! 120: input = _IO_INPUT, ! 121: output = _IO_OUTPUT, ! 122: atend = _IO_ATEND, ! 123: append = _IO_APPEND }; ! 124: #endif ! 125: ! 126: class ios : public _ios_fields { ! 127: public: ! 128: typedef __fmtflags fmtflags; ! 129: typedef int iostate; ! 130: typedef int openmode; ! 131: typedef int streamsize; ! 132: enum io_state { ! 133: goodbit = _IOS_GOOD, ! 134: eofbit = _IOS_EOF, ! 135: failbit = _IOS_FAIL, ! 136: badbit = _IOS_BAD }; ! 137: enum open_mode { ! 138: in = _IO_INPUT, ! 139: out = _IO_OUTPUT, ! 140: ate = _IO_ATEND, ! 141: app = _IO_APPEND, ! 142: trunc = _IO_TRUNC, ! 143: nocreate = _IO_NOCREATE, ! 144: noreplace = _IO_NOREPLACE, ! 145: bin = _IOS_BIN }; ! 146: enum seek_dir { beg, cur, end}; ! 147: // ANSI: typedef enum seek_dir seekdir; etc ! 148: // NOTE: If adding flags here, before to update ios::bitalloc(). ! 149: enum { skipws=_IO_SKIPWS, ! 150: left=_IO_LEFT, right=_IO_RIGHT, internal=_IO_INTERNAL, ! 151: dec=_IO_DEC, oct=_IO_OCT, hex=_IO_HEX, ! 152: showbase=_IO_SHOWBASE, showpoint=_IO_SHOWPOINT, ! 153: uppercase=_IO_UPPERCASE, showpos=_IO_SHOWPOS, ! 154: scientific=_IO_SCIENTIFIC, fixed=_IO_FIXED, ! 155: unitbuf=_IO_UNITBUF, stdio=_IO_STDIO, ! 156: dont_close=_IO_DONT_CLOSE // Don't delete streambuf on stream destruction ! 157: }; ! 158: enum { // Masks. ! 159: basefield=dec+oct+hex, ! 160: floatfield = scientific+fixed, ! 161: adjustfield = left+right+internal ! 162: }; ! 163: ! 164: #ifdef _IO_THROW ! 165: class failure : public xmsg { ! 166: ios* _stream; ! 167: public: ! 168: failure(ios* stream) { _stream = stream; } ! 169: failure(string cause, ios* stream) { _stream = stream; } ! 170: ios* rdios() const { return _stream; } ! 171: }; ! 172: #endif ! 173: ! 174: ostream* tie() const { return _tie; } ! 175: ostream* tie(ostream* val) { ostream* save=_tie; _tie=val; return save; } ! 176: ! 177: // Methods to change the format state. ! 178: _IO_wchar_t fill() const { return (_IO_wchar_t)_fill; } ! 179: _IO_wchar_t fill(_IO_wchar_t newf) ! 180: {_IO_wchar_t oldf = (_IO_wchar_t)_fill; _fill = (char)newf; return oldf;} ! 181: fmtflags flags() const { return _flags; } ! 182: fmtflags flags(fmtflags new_val) { ! 183: fmtflags old_val = _flags; _flags = new_val; return old_val; } ! 184: int precision() const { return _precision; } ! 185: int precision(int newp) { ! 186: unsigned short oldp = _precision; _precision = (unsigned short)newp; ! 187: return oldp; } ! 188: fmtflags setf(fmtflags val) { ! 189: fmtflags oldbits = _flags; ! 190: _flags |= val; return oldbits; } ! 191: fmtflags setf(fmtflags val, fmtflags mask) { ! 192: fmtflags oldbits = _flags; ! 193: _flags = (_flags & ~mask) | (val & mask); return oldbits; } ! 194: fmtflags unsetf(fmtflags mask) { ! 195: fmtflags oldbits = _flags; ! 196: _flags &= ~mask; return oldbits; } ! 197: int width() const { return _width; } ! 198: int width(int val) { int save = _width; _width = val; return save; } ! 199: ! 200: #ifdef _IO_THROW ! 201: void _throw_failure() const { throw new ios::failure(this); } ! 202: #else ! 203: void _throw_failure() const { } ! 204: #endif ! 205: void _IO_fix_vtable(); /* TEMPORARY - for binary compatibility */ ! 206: void _IO_fix_vtable() const; ! 207: streambuf* rdbuf() const; ! 208: #if 0 ! 209: streambuf* rdbuf(streambuf *_s) { ! 210: streambuf *_old = _strbuf; _strbuf = _s; return _old; } ! 211: #endif ! 212: void clear(iostate state = 0) { ! 213: _state = _strbuf ? state : state|badbit; ! 214: if (_state & _exceptions) _throw_failure(); } ! 215: void set(iostate flag) { _state |= flag; ! 216: if (_state & _exceptions) _throw_failure(); } ! 217: void setstate(iostate flag) { _state |= flag; // ANSI ! 218: if (_state & _exceptions) _throw_failure(); } ! 219: int good() const { return _state == 0; } ! 220: int eof() const { return _state & ios::eofbit; } ! 221: int fail() const { return _state & (ios::badbit|ios::failbit); } ! 222: int bad() const { return _state & ios::badbit; } ! 223: iostate rdstate() const { return _state; } ! 224: operator void*() const { return fail() ? (void*)0 : (void*)(-1); } ! 225: int operator!() const { return fail(); } ! 226: iostate exceptions() const { return _exceptions; } ! 227: void exceptions(iostate enable) { ! 228: _exceptions = enable; ! 229: if (_state & _exceptions) _throw_failure(); } ! 230: ! 231: static int sync_with_stdio(int on); ! 232: static void sync_with_stdio() { sync_with_stdio(1); } ! 233: static fmtflags bitalloc(); ! 234: static int xalloc(); ! 235: void*& pword(int); ! 236: void* pword(int) const; ! 237: long& iword(int); ! 238: long iword(int) const; ! 239: ! 240: #ifdef _STREAM_COMPAT ! 241: void unset(state_value flag) { _state &= ~flag; } ! 242: void close(); ! 243: int is_open(); ! 244: int readable(); ! 245: int writable(); ! 246: #endif ! 247: ! 248: // Used to initialize standard streams. Not needed in this implementation. ! 249: class Init { ! 250: public: ! 251: Init () { } ! 252: }; ! 253: ! 254: protected: ! 255: ios(streambuf* sb = 0, ostream* tie = 0); ! 256: virtual ~ios(); ! 257: void init(streambuf* sb) { _state=0; _strbuf=sb; } ! 258: }; ! 259: ! 260: #if __GNUG__==1 ! 261: typedef int _seek_dir; ! 262: #else ! 263: typedef ios::seek_dir _seek_dir; ! 264: #endif ! 265: ! 266: // Magic numbers and bits for the _flags field. ! 267: // The magic numbers use the high-order bits of _flags; ! 268: // the remaining bits are abailable for variable flags. ! 269: // Note: The magic numbers must all be negative if stdio ! 270: // emulation is desired. ! 271: ! 272: // A streammarker remembers a position in a buffer. ! 273: // You are guaranteed to be able to seek back to it if it is saving(). ! 274: class streammarker : private _IO_marker { ! 275: friend class streambuf; ! 276: void set_offset(int offset) { _pos = offset; } ! 277: public: ! 278: streammarker(streambuf *sb); ! 279: ~streammarker(); ! 280: int saving() { return 1; } ! 281: int delta(streammarker&); ! 282: int delta(); ! 283: }; ! 284: ! 285: extern unsigned __adjust_column(unsigned start, const char *line, int count); ! 286: ! 287: struct streambuf : public _IO_FILE { // protected?? ! 288: friend class ios; ! 289: friend class istream; ! 290: friend class ostream; ! 291: friend class streammarker; ! 292: const void *&_vtable() { return ((struct _IO_FILE_plus*)this)->_vtable; } ! 293: protected: ! 294: static streambuf* _list_all; /* List of open streambufs. */ ! 295: _IO_FILE*& xchain() { return _chain; } ! 296: void _un_link(); ! 297: void _link_in(); ! 298: char* gptr() const ! 299: { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_base : _IO_read_ptr; } ! 300: char* pptr() const { return _IO_write_ptr; } ! 301: char* egptr() const ! 302: { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_end : _IO_read_end; } ! 303: char* epptr() const { return _IO_write_end; } ! 304: char* pbase() const { return _IO_write_base; } ! 305: char* eback() const ! 306: { return _IO_file_flags & _IO_IN_BACKUP ? _IO_save_base : _IO_read_base;} ! 307: char* base() const { return _IO_buf_base; } ! 308: char* ebuf() const { return _IO_buf_end; } ! 309: int blen() const { return _IO_buf_end - _IO_buf_base; } ! 310: void xput_char(char c) { *_IO_write_ptr++ = c; } ! 311: int xflags() { return _IO_file_flags; } ! 312: int xflags(int f) {int fl = _IO_file_flags; _IO_file_flags = f; return fl;} ! 313: void xsetflags(int f) { _IO_file_flags |= f; } ! 314: void xsetflags(int f, int mask) ! 315: { _IO_file_flags = (_IO_file_flags & ~mask) | (f & mask); } ! 316: void gbump(int n) ! 317: { _IO_file_flags & _IO_IN_BACKUP ? (_IO_save_base+=n):(_IO_read_ptr+=n);} ! 318: void pbump(int n) { _IO_write_ptr += n; } ! 319: void setb(char* b, char* eb, int a=0); ! 320: void setp(char* p, char* ep) ! 321: { _IO_write_base=_IO_write_ptr=p; _IO_write_end=ep; } ! 322: void setg(char* eb, char* g, char *eg) { ! 323: if (_IO_file_flags & _IO_IN_BACKUP) _IO_free_backup_area(this); ! 324: _IO_read_base = eb; _IO_read_ptr = g; _IO_read_end = eg; } ! 325: char *shortbuf() { return _shortbuf; } ! 326: ! 327: int in_backup() { return _flags & _IO_IN_BACKUP; } ! 328: // The start of the main get area: FIXME: wrong for write-mode filebuf? ! 329: char *Gbase() { return in_backup() ? _other_gbase : _IO_read_base; } ! 330: // The end of the main get area: ! 331: char *eGptr() { return in_backup() ? _other_egptr : _IO_read_end; } ! 332: // The start of the backup area: ! 333: char *Bbase() { return in_backup() ? _IO_read_base : _other_gbase; } ! 334: char *Bptr() { return _aux_limit; } ! 335: // The end of the backup area: ! 336: char *eBptr() { return in_backup() ? _IO_read_end : _other_egptr; } ! 337: char *Nbase() { return _other_gbase; } ! 338: char *eNptr() { return _other_egptr; } ! 339: int have_backup() { return _other_gbase != NULL; } ! 340: int have_markers() { return _markers != NULL; } ! 341: void free_backup_area(); ! 342: void unsave_markers(); // Make all streammarkers !saving(). ! 343: int put_mode() { return _flags & _IO_CURRENTLY_PUTTING; } ! 344: int switch_to_get_mode(); ! 345: ! 346: streambuf(int flags=0); ! 347: public: ! 348: static int flush_all(); ! 349: static void flush_all_linebuffered(); // Flush all line buffered files. ! 350: virtual int underflow(); // Leave public for now ! 351: virtual int overflow(int c = EOF); // Leave public for now ! 352: virtual int doallocate(); ! 353: streampos sseekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); ! 354: streampos sseekpos(streampos pos, int mode = ios::in|ios::out); ! 355: ! 356: virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); ! 357: virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out); ! 358: int seekmark(streammarker& mark, int delta = 0); ! 359: int sputbackc(char c); ! 360: int sungetc(); ! 361: virtual ~streambuf(); ! 362: int unbuffered() { return _flags & _IO_UNBUFFERED ? 1 : 0; } ! 363: int linebuffered() { return _flags & _IO_LINE_BUF ? 1 : 0; } ! 364: void unbuffered(int i) ! 365: { if (i) _flags |= _IO_UNBUFFERED; else _flags &= ~_IO_UNBUFFERED; } ! 366: void linebuffered(int i) ! 367: { if (i) _flags |= _IO_LINE_BUF; else _flags &= ~_IO_LINE_BUF; } ! 368: int allocate() { // For AT&T compatibility ! 369: if (base() || unbuffered()) return 0; ! 370: else return doallocate(); } ! 371: // Allocate a buffer if needed; use _shortbuf if appropriate. ! 372: void allocbuf() { if (base() == NULL) doallocbuf(); } ! 373: void doallocbuf(); ! 374: virtual int sync(); ! 375: virtual int pbackfail(int c); ! 376: virtual streambuf* setbuf(char* p, int len); ! 377: int in_avail() { return _IO_read_end - _IO_read_ptr; } ! 378: int out_waiting() { return _IO_write_ptr - _IO_write_base; } ! 379: virtual streamsize xsputn(const char* s, streamsize n); ! 380: streamsize sputn(const char* s, streamsize n) { return xsputn(s, n); } ! 381: streamsize padn(char pad, streamsize n) { return _IO_padn(this, pad, n); } ! 382: virtual streamsize xsgetn(char* s, streamsize n); ! 383: streamsize sgetn(char* s, streamsize n) { return _IO_sgetn(this, s, n); } ! 384: int ignore(int); ! 385: virtual int get_column(); ! 386: virtual int set_column(int); ! 387: long sgetline(char* buf, _IO_size_t n, char delim, int putback_delim); ! 388: int sputc(int c) { return _IO_putc(c, this); } ! 389: int sbumpc() { return _IO_getc(this); } ! 390: int sgetc() { return _IO_peekc(this); } ! 391: int snextc() { ! 392: if (_IO_read_ptr >= _IO_read_end && __underflow(this) == EOF) ! 393: return EOF; ! 394: else return _IO_read_ptr++, sgetc(); } ! 395: void stossc() { if (_IO_read_ptr < _IO_read_end) _IO_read_ptr++; } ! 396: int vscan(char const *fmt0, _IO_va_list ap, ios* stream = NULL); ! 397: int scan(char const *fmt0 ...); ! 398: int vform(char const *fmt0, _IO_va_list ap); ! 399: int form(char const *fmt0 ...); ! 400: #if 0 /* Work in progress */ ! 401: int column(); // Current column number (of put pointer). -1 is unknown. ! 402: void column(int c); // Set column number of put pointer to c. ! 403: #endif ! 404: virtual streamsize sys_read(char* buf, streamsize size); ! 405: virtual streampos sys_seek(streamoff, _seek_dir); ! 406: virtual streamsize sys_write(const char*, streamsize); ! 407: virtual int sys_stat(void*); // Actually, a (struct stat*) ! 408: virtual int sys_close(); ! 409: }; ! 410: ! 411: // A backupbuf is a streambuf with full backup and savepoints on reading. ! 412: // All standard streambufs in the GNU iostream library are backupbufs. ! 413: ! 414: class filebuf : public streambuf { ! 415: protected: ! 416: void init(); ! 417: public: ! 418: static const int openprot; // Non-ANSI AT&T-ism: Default open protection. ! 419: filebuf(); ! 420: filebuf(int fd); ! 421: filebuf(int fd, char* p, int len); ! 422: static filebuf *__new(); ! 423: ~filebuf(); ! 424: filebuf* attach(int fd); ! 425: filebuf* open(const char *filename, const char *mode); ! 426: filebuf* open(const char *filename, ios::openmode mode, int prot = 0664); ! 427: virtual int underflow(); ! 428: virtual int overflow(int c = EOF); ! 429: int is_open() const { return _fileno >= 0; } ! 430: int fd() const { return is_open() ? _fileno : EOF; } ! 431: filebuf* close(); ! 432: virtual int doallocate(); ! 433: virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); ! 434: virtual streambuf* setbuf(char* p, int len); ! 435: streamsize xsputn(const char* s, streamsize n); ! 436: streamsize xsgetn(char* s, streamsize n); ! 437: virtual int sync(); ! 438: protected: // See documentation in filebuf.C. ! 439: // virtual int pbackfail(int c); ! 440: int is_reading() { return eback() != egptr(); } ! 441: char* cur_ptr() { return is_reading() ? gptr() : pptr(); } ! 442: /* System's idea of pointer */ ! 443: char* file_ptr() { return eGptr(); } ! 444: int do_write(const char *data, int to_do); ! 445: // Low-level operations (Usually invoke system calls.) ! 446: virtual streamsize sys_read(char* buf, streamsize size); ! 447: virtual streampos sys_seek(streamoff, _seek_dir); ! 448: virtual streamsize sys_write(const char*, streamsize); ! 449: virtual int sys_stat(void*); // Actually, a (struct stat*) ! 450: virtual int sys_close(); ! 451: }; ! 452: ! 453: inline ios::ios(streambuf* sb /* = 0 */, ostream* tie_to /* = 0 */) { ! 454: _state = sb ? ios::goodbit : ios::badbit; _exceptions=0; ! 455: _strbuf=sb; _tie = tie_to; _width=0; _fill=' '; ! 456: _flags=ios::skipws|ios::dec; _precision=6; _arrays = 0; } ! 457: ! 458: inline streambuf* ios::rdbuf() const ! 459: { ! 460: if (_strbuf && _strbuf->_vtable() == 0) ! 461: _IO_fix_vtable(); ! 462: return _strbuf; ! 463: } ! 464: ! 465: inline ios::~ios() { ! 466: if (!(_flags & (unsigned int)ios::dont_close)) delete rdbuf(); } ! 467: #endif /* _STREAMBUF_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.