de-errno
[dragonfly.git] / contrib / 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 #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:
173         failure(ios* stream) { _stream = stream; }
174         failure(string cause, ios* stream) { _stream = stream; }
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
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
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 */