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