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