OSDN Git Service

Reorg sethi_{hi,si} patterns.
[pf3gnuchains/gcc-fork.git] / libio / streambuf.h
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 #define _IO_wchar_t short
59 #endif
60
61 extern "C++" {
62 class istream; /* Work-around for a g++ name mangling bug. Fixed in 2.6. */
63 class ostream; class streambuf;
64
65 // In case some header files defines these as macros.
66 #undef open
67 #undef close
68
69 typedef _IO_off_t streamoff;
70 typedef _IO_fpos_t streampos;
71 typedef _IO_ssize_t streamsize;
72
73 typedef unsigned long __fmtflags;
74 typedef unsigned char __iostate;
75
76 struct _ios_fields
77 { // The data members of an ios.
78     streambuf *_strbuf;
79     ostream* _tie;
80     int _width;
81     __fmtflags _flags;
82     _IO_wchar_t _fill;
83     __iostate _state;
84     __iostate _exceptions;
85     int _precision;
86
87     void *_arrays; /* Support for ios::iword and ios::pword. */
88 };
89
90 #define _IOS_GOOD       0
91 #define _IOS_EOF        1
92 #define _IOS_FAIL       2
93 #define _IOS_BAD        4
94
95 #define _IO_INPUT       1
96 #define _IO_OUTPUT      2
97 #define _IO_ATEND       4
98 #define _IO_APPEND      8
99 #define _IO_TRUNC       16
100 #define _IO_NOCREATE    32
101 #define _IO_NOREPLACE   64
102 #define _IO_BIN         128
103
104 #ifdef _STREAM_COMPAT
105 enum state_value {
106     _good = _IOS_GOOD,
107     _eof = _IOS_EOF,
108     _fail = _IOS_FAIL,
109     _bad = _IOS_BAD };
110 enum open_mode {
111     input = _IO_INPUT,
112     output = _IO_OUTPUT,
113     atend = _IO_ATEND,
114     append = _IO_APPEND };
115 #endif
116
117 class ios : public _ios_fields {
118   ios& operator=(ios&);  /* Not allowed! */
119   ios (const ios&); /* Not allowed! */
120   public:
121     typedef __fmtflags fmtflags;
122     typedef int iostate;
123     typedef int openmode;
124     typedef int streamsize;
125     enum io_state {
126         goodbit = _IOS_GOOD,
127         eofbit = _IOS_EOF,
128         failbit = _IOS_FAIL,
129         badbit = _IOS_BAD };
130     enum open_mode {
131         in = _IO_INPUT,
132         out = _IO_OUTPUT,
133         ate = _IO_ATEND,
134         app = _IO_APPEND,
135         trunc = _IO_TRUNC,
136         nocreate = _IO_NOCREATE,
137         noreplace = _IO_NOREPLACE,
138         bin = _IOS_BIN, // Deprecated - ANSI uses ios::binary.
139         binary = _IOS_BIN };
140     enum seek_dir { beg, cur, end};
141     typedef enum seek_dir seekdir;
142     // NOTE: If adding flags here, before to update ios::bitalloc().
143     enum { skipws=_IO_SKIPWS,
144            left=_IO_LEFT, right=_IO_RIGHT, internal=_IO_INTERNAL,
145            dec=_IO_DEC, oct=_IO_OCT, hex=_IO_HEX,
146            showbase=_IO_SHOWBASE, showpoint=_IO_SHOWPOINT,
147            uppercase=_IO_UPPERCASE, showpos=_IO_SHOWPOS,
148            scientific=_IO_SCIENTIFIC, fixed=_IO_FIXED,
149            unitbuf=_IO_UNITBUF, stdio=_IO_STDIO
150 #ifndef _IO_NEW_STREAMS
151            , dont_close=_IO_DONT_CLOSE // Don't delete streambuf on stream destruction
152 #endif
153            };
154     enum { // Masks.
155         basefield=dec+oct+hex,
156         floatfield = scientific+fixed,
157         adjustfield = left+right+internal
158     };
159
160 #ifdef _IO_THROW
161     class failure : public xmsg {
162         ios* _stream;
163       public:
164         failure(ios* stream) { _stream = stream; }
165         failure(string cause, ios* stream) { _stream = stream; }
166         ios* rdios() const { return _stream; }
167     };
168 #endif
169
170     ostream* tie() const { return _tie; }
171     ostream* tie(ostream* val) { ostream* save=_tie; _tie=val; return save; }
172
173     // Methods to change the format state.
174     _IO_wchar_t fill() const { return (_IO_wchar_t)_fill; }
175     _IO_wchar_t fill(_IO_wchar_t newf)
176         {_IO_wchar_t oldf = (_IO_wchar_t)_fill; _fill = (char)newf; return oldf;}
177     fmtflags flags() const { return _flags; }
178     fmtflags flags(fmtflags new_val) {
179         fmtflags old_val = _flags; _flags = new_val; return old_val; }
180     int precision() const { return _precision; }
181     int precision(int newp) {
182         unsigned short oldp = _precision; _precision = (unsigned short)newp;
183         return oldp; }
184     fmtflags setf(fmtflags val) {
185         fmtflags oldbits = _flags;
186         _flags |= val; return oldbits; }
187     fmtflags setf(fmtflags val, fmtflags mask) {
188         fmtflags oldbits = _flags;
189         _flags = (_flags & ~mask) | (val & mask); return oldbits; }
190     fmtflags unsetf(fmtflags mask) {
191         fmtflags oldbits = _flags;
192         _flags &= ~mask; return oldbits; }
193     int width() const { return _width; }
194     int width(int val) { int save = _width; _width = val; return save; }
195
196 #ifdef _IO_THROW
197     void _throw_failure() const { throw new ios::failure(this); }
198 #else
199     void _throw_failure() const { }
200 #endif
201     void clear(iostate state = 0) {
202         _state = _strbuf ? state : state|badbit;
203         if (_state & _exceptions) _throw_failure(); }
204     void set(iostate flag) { _state |= flag;
205         if (_state & _exceptions) _throw_failure(); }
206     void setstate(iostate flag) { _state |= flag; // ANSI
207         if (_state & _exceptions) _throw_failure(); }
208     int good() const { return _state == 0; }
209     int eof() const { return _state & ios::eofbit; }
210     int fail() const { return _state & (ios::badbit|ios::failbit); }
211     int bad() const { return _state & ios::badbit; }
212     iostate rdstate() const { return _state; }
213     operator void*() const { return fail() ? (void*)0 : (void*)(-1); }
214     int operator!() const { return fail(); }
215     iostate exceptions() const { return _exceptions; }
216     void exceptions(iostate enable) {
217         _exceptions = enable;
218         if (_state & _exceptions) _throw_failure(); }
219
220     streambuf* rdbuf() const { return _strbuf; }
221     streambuf* rdbuf(streambuf *_s) {
222       streambuf *_old = _strbuf; _strbuf = _s; clear (); return _old; }
223
224     static int sync_with_stdio(int on);
225     static void sync_with_stdio() { sync_with_stdio(1); }
226     static fmtflags bitalloc();
227     static int xalloc();
228     void*& pword(int);
229     void* pword(int) const;
230     long& iword(int);
231     long iword(int) const;
232
233 #ifdef _STREAM_COMPAT
234     void unset(state_value flag) { _state &= ~flag; }
235     void close();
236     int is_open();
237     int readable();
238     int writable();
239 #endif
240
241     // Used to initialize standard streams. Not needed in this implementation.
242     class Init {
243     public:
244       Init () { }
245     };
246
247   protected:
248     inline ios(streambuf* sb = 0, ostream* tie_to = 0);
249     inline virtual ~ios();
250     inline void init(streambuf* sb, ostream* tie = 0);
251 };
252
253 #if __GNUG__==1
254 typedef int _seek_dir;
255 #else
256 typedef ios::seek_dir _seek_dir;
257 #endif
258
259 // Magic numbers and bits for the _flags field.
260 // The magic numbers use the high-order bits of _flags;
261 // the remaining bits are abailable for variable flags.
262 // Note: The magic numbers must all be negative if stdio
263 // emulation is desired.
264
265 // A streammarker remembers a position in a buffer.
266 // You are guaranteed to be able to seek back to it if it is saving().
267 class streammarker : private _IO_marker {
268     friend class streambuf;
269     void set_offset(int offset) { _pos = offset; }
270   public:
271     streammarker(streambuf *sb);
272     ~streammarker();
273     int saving() { return  1; }
274     int delta(streammarker&);
275     int delta();
276 };
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 *(const void**)((_IO_FILE*)this + 1); }
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() ? _IO_save_base : _IO_read_base; }
321     // The end of the main get area:
322     char *eGptr() { return in_backup() ? _IO_save_end : _IO_read_end; }
323     // The start of the backup area:
324     char *Bbase() { return in_backup() ? _IO_read_base : _IO_save_base; }
325     char *Bptr() { return _IO_backup_base; }
326     // The end of the backup area:
327     char *eBptr() { return in_backup() ? _IO_read_end : _IO_save_end; }
328     char *Nbase() { return _IO_save_base; }
329     char *eNptr() { return _IO_save_end; }
330     int have_backup() { return _IO_save_base != 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 ~streambuf();
342     virtual int overflow(int c = EOF); // Leave public for now
343     virtual int underflow(); // Leave public for now
344     virtual int uflow(); // Leave public for now
345     virtual int pbackfail(int c);
346 //    virtual int showmany ();
347     virtual streamsize xsputn(const char* s, streamsize n);
348     virtual streamsize xsgetn(char* s, streamsize n);
349     virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
350     virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
351
352     streampos pubseekoff(streamoff o, _seek_dir d, int mode=ios::in|ios::out)
353       { return _IO_seekoff (this, o, d, mode); }
354     streampos pubseekpos(streampos pos, int mode = ios::in|ios::out)
355       { return _IO_seekpos (this, pos, mode); }
356     streampos sseekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
357     streampos sseekpos(streampos pos, int mode = ios::in|ios::out);
358     virtual streambuf* setbuf(char* p, int len);
359     virtual int sync();
360     virtual int doallocate();
361
362     int seekmark(streammarker& mark, int delta = 0);
363     int sputbackc(char c);
364     int sungetc();
365     int unbuffered() { return _flags & _IO_UNBUFFERED ? 1 : 0; }
366     int linebuffered() { return _flags & _IO_LINE_BUF ? 1 : 0; }
367     void unbuffered(int i)
368         { if (i) _flags |= _IO_UNBUFFERED; else _flags &= ~_IO_UNBUFFERED; }
369     void linebuffered(int i)
370         { if (i) _flags |= _IO_LINE_BUF; else _flags &= ~_IO_LINE_BUF; }
371     int allocate() { // For AT&T compatibility
372         if (base() || unbuffered()) return 0;
373         else return doallocate(); }
374     // Allocate a buffer if needed; use _shortbuf if appropriate.
375     void allocbuf() { if (base() == NULL) doallocbuf(); }
376     void doallocbuf();
377     int in_avail() { return _IO_read_end - _IO_read_ptr; }
378     int out_waiting() { return _IO_write_ptr - _IO_write_base; }
379     streamsize sputn(const char* s, streamsize n) { return xsputn(s, n); }
380     streamsize padn(char pad, streamsize n) { return _IO_padn(this, pad, n); }
381     streamsize sgetn(char* s, streamsize n) { return _IO_sgetn(this, s, n); }
382     int ignore(int);
383     int get_column();
384     int set_column(int);
385     long sgetline(char* buf, _IO_size_t n, char delim, int putback_delim);
386     int sputc(int c) { return _IO_putc(c, this); }
387     int sbumpc() { return _IO_getc(this); }
388     int sgetc() { return _IO_peekc(this); }
389     int snextc() {
390         if (_IO_read_ptr >= _IO_read_end && __underflow(this) == EOF)
391           return EOF;
392         else return _IO_read_ptr++, sgetc(); }
393     void stossc() { if (_IO_read_ptr < _IO_read_end) _IO_read_ptr++; }
394     int vscan(char const *fmt0, _IO_va_list ap, ios* stream = NULL);
395     int scan(char const *fmt0 ...);
396     int vform(char const *fmt0, _IO_va_list ap);
397     int form(char const *fmt0 ...);
398 #if 0 /* Work in progress */
399     int column();  // Current column number (of put pointer). -1 is unknown.
400     void column(int c);  // Set column number of put pointer to c.
401 #endif
402     virtual streamsize sys_read(char* buf, streamsize size);
403     virtual streamsize sys_write(const char*, streamsize);
404     virtual streampos sys_seek(streamoff, _seek_dir);
405     virtual int sys_close();
406     virtual int sys_stat(void*); // Actually, a (struct stat*)
407 };
408
409 // A backupbuf is a streambuf with full backup and savepoints on reading.
410 // All standard streambufs in the GNU iostream library are backupbufs.
411
412 class filebuf : public streambuf {
413   protected:
414     void init();
415   public:
416     static const int openprot; // Non-ANSI AT&T-ism:  Default open protection.
417     filebuf();
418     filebuf(int fd);
419     filebuf(int fd, char* p, int len);
420 #if !_IO_UNIFIED_JUMPTABLES
421     static filebuf *__new();
422 #endif
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     // Low-level operations (Usually invoke system calls.)
445     virtual streamsize sys_read(char* buf, streamsize size);
446     virtual streampos sys_seek(streamoff, _seek_dir);
447     virtual streamsize sys_write(const char*, streamsize);
448     virtual int sys_stat(void*); // Actually, a (struct stat*)
449     virtual int sys_close();
450 #if 0
451     virtual uflow;
452     virtual showmany;
453 #endif
454 };
455
456 inline void ios::init(streambuf* sb, ostream* tie_to) {
457                 _state = sb ? ios::goodbit : ios::badbit; _exceptions=0;
458                 _strbuf=sb; _tie = tie_to; _width=0; _fill=' ';
459 #ifdef _IO_NEW_STREAMS
460                 _flags=ios::skipws|ios::dec;
461 #else
462                 _flags=ios::skipws|ios::dec|ios::dont_close;
463 #endif
464                 _precision=6; _arrays = 0; }
465
466 inline ios::ios(streambuf* sb, ostream* tie_to) { init(sb, tie_to); }
467
468 inline ios::~ios() {
469 #ifndef _IO_NEW_STREAMS
470     if (!(_flags & (unsigned int)ios::dont_close)) delete rdbuf();
471 #endif
472     if (_arrays) delete [] _arrays;
473 }
474 } // extern "C++"
475 #endif /* _STREAMBUF_H */