home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 22 gnu / 22-gnu.zip / cplus261.zip / gcc2 / gppincl / streambu.h < prev    next >
C/C++ Source or Header  |  1994-11-03  |  17KB  |  475 lines

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