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 this library; see the file COPYING. If not, write to the Free 17 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 #endif 30 31 /* #define _G_IO_THROW */ /* Not implemented: ios::failure */ 32 33 #define _IO_NEW_STREAMS // new optimizated stream representation 34 35 extern "C" { 36 #include <libio.h> 37 } 38 //#include <_G_config.h> 39 #ifdef _G_NEED_STDARG_H 40 #include <stdarg.h> 41 #endif 42 #ifndef _IO_va_list 43 #define _IO_va_list char * 44 #endif 45 46 #ifndef EOF 47 #define EOF (-1) 48 #endif 49 #ifndef NULL 50 #ifdef __GNUG__ 51 #define NULL (__null) 52 #else 53 #define NULL (0) 54 #endif 55 #endif 56 57 #ifndef _IO_wchar_t 58 #if _G_IO_IO_FILE_VERSION == 0x20001 59 #define _IO_wchar_t _G_wchar_t 60 #else 61 #define _IO_wchar_t short 62 #endif 63 #endif 64 65 extern "C++" { 66 class istream; /* Work-around for a g++ name mangling bug. Fixed in 2.6. */ 67 class ostream; class streambuf; 68 69 // In case some header files defines these as macros. 70 #undef open 71 #undef close 72 73 #if defined(_G_IO_IO_FILE_VERSION) && _G_IO_IO_FILE_VERSION == 0x20001 74 typedef _IO_off64_t streamoff; 75 typedef _IO_off64_t streampos; 76 #else 77 typedef _IO_off_t streamoff; 78 typedef _IO_off_t streampos; 79 #endif 80 typedef _IO_ssize_t streamsize; 81 82 typedef unsigned long __fmtflags; 83 typedef unsigned char __iostate; 84 85 struct _ios_fields 86 { // The data members of an ios. 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 ios& operator=(ios&); /* Not allowed! */ 128 ios (const ios&); /* Not allowed! */ 129 public: 130 typedef __fmtflags fmtflags; 131 typedef int iostate; 132 typedef int openmode; 133 typedef _IO_ssize_t streamsize; 134 enum io_state { 135 goodbit = _IOS_GOOD, 136 eofbit = _IOS_EOF, 137 failbit = _IOS_FAIL, 138 badbit = _IOS_BAD }; 139 enum open_mode { 140 in = _IO_INPUT, 141 out = _IO_OUTPUT, 142 ate = _IO_ATEND, 143 app = _IO_APPEND, 144 trunc = _IO_TRUNC, 145 nocreate = _IO_NOCREATE, 146 noreplace = _IO_NOREPLACE, 147 bin = _IOS_BIN, // Deprecated - ANSI uses ios::binary. 148 binary = _IOS_BIN }; 149 enum seek_dir { beg, cur, end}; 150 typedef enum seek_dir seekdir; 151 // NOTE: If adding flags here, before to update ios::bitalloc(). 152 enum { skipws=_IO_SKIPWS, 153 left=_IO_LEFT, right=_IO_RIGHT, internal=_IO_INTERNAL, 154 dec=_IO_DEC, oct=_IO_OCT, hex=_IO_HEX, 155 showbase=_IO_SHOWBASE, showpoint=_IO_SHOWPOINT, 156 uppercase=_IO_UPPERCASE, showpos=_IO_SHOWPOS, 157 scientific=_IO_SCIENTIFIC, fixed=_IO_FIXED, 158 unitbuf=_IO_UNITBUF, stdio=_IO_STDIO 159 #ifndef _IO_NEW_STREAMS 160 , dont_close=_IO_DONT_CLOSE // Don't delete streambuf on stream destruction 161 #endif 162 }; 163 enum { // Masks. 164 basefield=dec+oct+hex, 165 floatfield = scientific+fixed, 166 adjustfield = left+right+internal 167 }; 168 169 #ifdef _IO_THROW 170 class failure : public xmsg { 171 ios* _stream; 172 public: failure(ios * stream)173 failure(ios* stream) { _stream = stream; } failure(string cause,ios * stream)174 failure(string cause, ios* stream) { _stream = stream; } rdios()175 ios* rdios() const { return _stream; } 176 }; 177 #endif 178 179 - ostream* tie() const { return _tie; } 180 - ostream* tie(ostream* val) { ostream* save=_tie; _tie=val; return save; } 181 182 // Methods to change the format state. 183 - _IO_wchar_t fill() const { return _fill; } 184 _IO_wchar_t fill(_IO_wchar_t newf) 185 - {_IO_wchar_t oldf = _fill; _fill = newf; return oldf;} 186 - fmtflags flags() const { return _flags; } 187 - fmtflags flags(fmtflags new_val) { 188 - fmtflags old_val = _flags; _flags = new_val; return old_val; } 189 - int precision() const { return _precision; } 190 - int precision(int newp) { 191 - unsigned short oldp = _precision; _precision = (unsigned short)newp; 192 - return oldp; } 193 - fmtflags setf(fmtflags val) { 194 - fmtflags oldbits = _flags; 195 - _flags |= val; return oldbits; } 196 - fmtflags setf(fmtflags val, fmtflags mask) { 197 - fmtflags oldbits = _flags; 198 - _flags = (_flags & ~mask) | (val & mask); return oldbits; } 199 - fmtflags unsetf(fmtflags mask) { 200 - fmtflags oldbits = _flags; 201 - _flags &= ~mask; return oldbits; } 202 - int width() const { return _width; } 203 - int width(int val) { int save = _width; _width = val; return save; } 204 205 #ifdef _IO_THROW _throw_failure()206 void _throw_failure() const { throw new ios::failure(this); } 207 #else 208 - void _throw_failure() const { } 209 #endif 210 - void clear(iostate state = 0) { 211 - _state = _strbuf ? state : state|badbit; 212 - if (_state & _exceptions) _throw_failure(); } 213 - void set(iostate flag) { _state |= flag; 214 - if (_state & _exceptions) _throw_failure(); } 215 - void setstate(iostate flag) { _state |= flag; // ANSI 216 - if (_state & _exceptions) _throw_failure(); } 217 - int good() const { return _state == 0; } 218 - int eof() const { return _state & ios::eofbit; } 219 - int fail() const { return _state & (ios::badbit|ios::failbit); } 220 - int bad() const { return _state & ios::badbit; } 221 - iostate rdstate() const { return _state; } 222 - operator void*() const { return fail() ? (void*)0 : (void*)(-1); } 223 - int operator!() const { return fail(); } 224 - iostate exceptions() const { return _exceptions; } 225 - void exceptions(iostate enable) { 226 - _exceptions = enable; 227 - if (_state & _exceptions) _throw_failure(); } 228 229 - streambuf* rdbuf() const { return _strbuf; } 230 - streambuf* rdbuf(streambuf *_s) { 231 - streambuf *_old = _strbuf; _strbuf = _s; clear (); return _old; } 232 233 static int sync_with_stdio(int on); 234 - static void sync_with_stdio() { sync_with_stdio(1); } 235 static fmtflags bitalloc(); 236 static int xalloc(); 237 void*& pword(int); 238 void* pword(int) const; 239 long& iword(int); 240 long iword(int) const; 241 242 #ifdef _STREAM_COMPAT unset(state_value flag)243 void unset(state_value flag) { _state &= ~flag; } 244 void close(); 245 int is_open(); 246 int readable(); 247 int writable(); 248 #endif 249 250 // Used to initialize standard streams. Not needed in this implementation. 251 class Init { 252 public: 253 - Init () { } 254 }; 255 256 protected: 257 inline ios(streambuf* sb = 0, ostream* tie_to = 0); 258 inline virtual ~ios(); 259 inline void init(streambuf* sb, ostream* tie = 0); 260 }; 261 262 #if __GNUG__==1 263 typedef int _seek_dir; 264 #else 265 typedef ios::seek_dir _seek_dir; 266 #endif 267 268 // Magic numbers and bits for the _flags field. 269 // The magic numbers use the high-order bits of _flags; 270 // the remaining bits are abailable for variable flags. 271 // Note: The magic numbers must all be negative if stdio 272 // emulation is desired. 273 274 // A streammarker remembers a position in a buffer. 275 // You are guaranteed to be able to seek back to it if it is saving(). 276 class streammarker : private _IO_marker { 277 friend class streambuf; 278 - void set_offset(int offset) { _pos = offset; } 279 public: 280 streammarker(streambuf *sb); 281 ~streammarker(); 282 - int saving() { return 1; } 283 int delta(streammarker&); 284 int delta(); 285 }; 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 *(const void**)((_IO_FILE*)this + 1); } 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() ? _IO_save_base : _IO_read_base; } 330 // The end of the main get area: 331 - char *eGptr() { return in_backup() ? _IO_save_end : _IO_read_end; } 332 // The start of the backup area: 333 - char *Bbase() { return in_backup() ? _IO_read_base : _IO_save_base; } 334 - char *Bptr() { return _IO_backup_base; } 335 // The end of the backup area: 336 - char *eBptr() { return in_backup() ? _IO_read_end : _IO_save_end; } 337 - char *Nbase() { return _IO_save_base; } 338 - char *eNptr() { return _IO_save_end; } 339 - int have_backup() { return _IO_save_base != 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 ~streambuf(); 351 virtual int overflow(int c = EOF); // Leave public for now 352 virtual int underflow(); // Leave public for now 353 virtual int uflow(); // Leave public for now 354 virtual int pbackfail(int c); 355 // virtual int showmany (); 356 virtual streamsize xsputn(const char* s, streamsize n); 357 virtual streamsize xsgetn(char* s, streamsize n); 358 virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); 359 virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out); 360 361 streampos pubseekoff(streamoff o, _seek_dir d, int mode=ios::in|ios::out) 362 - { return _IO_seekoff (this, o, d, mode); } 363 streampos pubseekpos(streampos pos, int mode = ios::in|ios::out) 364 - { return _IO_seekpos (this, pos, mode); } 365 streampos sseekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); 366 streampos sseekpos(streampos pos, int mode = ios::in|ios::out); 367 virtual streambuf* setbuf(char* p, int len); 368 virtual int sync(); 369 virtual int doallocate(); 370 371 int seekmark(streammarker& mark, int delta = 0); 372 int sputbackc(char c); 373 int sungetc(); 374 - int unbuffered() { return _flags & _IO_UNBUFFERED ? 1 : 0; } 375 - int linebuffered() { return _flags & _IO_LINE_BUF ? 1 : 0; } 376 void unbuffered(int i) 377 - { if (i) _flags |= _IO_UNBUFFERED; else _flags &= ~_IO_UNBUFFERED; } 378 void linebuffered(int i) 379 - { if (i) _flags |= _IO_LINE_BUF; else _flags &= ~_IO_LINE_BUF; } 380 - int allocate() { // For AT&T compatibility 381 - if (base() || unbuffered()) return 0; 382 - else return doallocate(); } 383 // Allocate a buffer if needed; use _shortbuf if appropriate. 384 - void allocbuf() { if (base() == NULL) doallocbuf(); } 385 void doallocbuf(); 386 - int in_avail() { return _IO_read_end - _IO_read_ptr; } 387 - int out_waiting() { return _IO_write_ptr - _IO_write_base; } 388 - streamsize sputn(const char* s, streamsize n) { return xsputn(s, n); } 389 - streamsize padn(char pad, streamsize n) { return _IO_padn(this, pad, n); } 390 - streamsize sgetn(char* s, streamsize n) { return _IO_sgetn(this, s, n); } 391 int ignore(int); 392 int get_column(); 393 int set_column(int); 394 long sgetline(char* buf, _IO_size_t n, char delim, int putback_delim); 395 - int sputc(int c) { return _IO_putc(c, this); } 396 - int sbumpc() { return _IO_getc(this); } 397 - int sgetc() { return _IO_peekc(this); } 398 - int snextc() { 399 - if (_IO_read_ptr >= _IO_read_end && __underflow(this) == EOF) 400 - return EOF; 401 - else return _IO_read_ptr++, sgetc(); } 402 - void stossc() { if (_IO_read_ptr < _IO_read_end) _IO_read_ptr++; } 403 int vscan(char const *fmt0, _IO_va_list ap, ios* stream = NULL); 404 int scan(char const *fmt0 ...); 405 int vform(char const *fmt0, _IO_va_list ap); 406 int form(char const *fmt0 ...); 407 #if 0 /* Work in progress */ 408 int column(); // Current column number (of put pointer). -1 is unknown. 409 void column(int c); // Set column number of put pointer to c. 410 #endif 411 virtual streamsize sys_read(char* buf, streamsize size); 412 virtual streamsize sys_write(const char*, streamsize); 413 virtual streampos sys_seek(streamoff, _seek_dir); 414 virtual int sys_close(); 415 virtual int sys_stat(void*); // Actually, a (struct stat*) 416 #if _G_IO_IO_FILE_VERSION == 0x20001 417 virtual int showmanyc(); 418 virtual void imbue(void *); 419 #endif 420 }; 421 422 // A backupbuf is a streambuf with full backup and savepoints on reading. 423 // All standard streambufs in the GNU iostream library are backupbufs. 424 425 class filebuf : public streambuf { 426 protected: 427 void init(); 428 public: 429 static const int openprot; // Non-ANSI AT&T-ism: Default open protection. 430 filebuf(); 431 filebuf(int fd); 432 filebuf(int fd, char* p, int len); 433 #if !_IO_UNIFIED_JUMPTABLES 434 static filebuf *__new(); 435 #endif 436 ~filebuf(); 437 filebuf* attach(int fd); 438 filebuf* open(const char *filename, const char *mode); 439 filebuf* open(const char *filename, ios::openmode mode, int prot = 0664); 440 virtual int underflow(); 441 virtual int overflow(int c = EOF); 442 - int is_open() const { return _fileno >= 0; } 443 - int fd() const { return is_open() ? _fileno : EOF; } 444 filebuf* close(); 445 virtual int doallocate(); 446 virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); 447 virtual streambuf* setbuf(char* p, int len); 448 streamsize xsputn(const char* s, streamsize n); 449 streamsize xsgetn(char* s, streamsize n); 450 virtual int sync(); 451 protected: // See documentation in filebuf.C. 452 // virtual int pbackfail(int c); 453 - int is_reading() { return eback() != egptr(); } 454 - char* cur_ptr() { return is_reading() ? gptr() : pptr(); } 455 /* System's idea of pointer */ 456 - char* file_ptr() { return eGptr(); } 457 // Low-level operations (Usually invoke system calls.) 458 virtual streamsize sys_read(char* buf, streamsize size); 459 virtual streampos sys_seek(streamoff, _seek_dir); 460 virtual streamsize sys_write(const char*, streamsize); 461 virtual int sys_stat(void*); // Actually, a (struct stat*) 462 virtual int sys_close(); 463 #if 0 464 virtual uflow; 465 virtual showmany; 466 #endif 467 }; 468 469 -inline void ios::init(streambuf* sb, ostream* tie_to) { 470 - _state = sb ? ios::goodbit : ios::badbit; _exceptions=0; 471 - _strbuf=sb; _tie = tie_to; _width=0; _fill=' '; 472 #ifdef _IO_NEW_STREAMS 473 - _flags=ios::skipws|ios::dec; 474 #else 475 _flags=ios::skipws|ios::dec|ios::dont_close; 476 #endif 477 - _precision=6; _arrays = 0; } 478 479 -inline ios::ios(streambuf* sb, ostream* tie_to) { init(sb, tie_to); } 480 481 -inline ios::~ios() { 482 #ifndef _IO_NEW_STREAMS 483 if (!(_flags & (unsigned int)ios::dont_close)) delete rdbuf(); 484 #endif 485 // It is safe to use naked operator delete[] as we know elements have no 486 // dtor, and g++ does not add a new[] cookie for such cases. 487 - operator delete[] (_arrays); 488 } 489 } // extern "C++" 490 #endif /* _STREAMBUF_H */ 491 492