btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / headers / cpp / streambuf.h
blob52f5a963ee066e919eaef5f7ec0e8608e4ac71ba
1 /* This is part of libio/iostream, providing -*- C++ -*- input/output.
2 Copyright (C) 1993 Free Software Foundation
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.
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.
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.
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. */
25 #ifndef _STREAMBUF_H
26 #define _STREAMBUF_H
27 #ifdef __GNUG__
28 #pragma interface
29 #endif
31 /* #define _G_IO_THROW */ /* Not implemented: ios::failure */
33 #define _IO_NEW_STREAMS // new optimizated stream representation
35 extern "C" {
36 #include <libio.h>
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
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
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 wchar_t
62 #endif
63 #endif
65 extern "C++" {
66 class istream; /* Work-around for a g++ name mangling bug. Fixed in 2.6. */
67 class ostream; class streambuf;
69 // In case some header files defines these as macros.
70 #undef open
71 #undef close
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;
82 typedef unsigned long __fmtflags;
83 typedef unsigned char __iostate;
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;
96 void *_arrays; /* Support for ios::iword and ios::pword. */
99 #define _IOS_GOOD 0
100 #define _IOS_EOF 1
101 #define _IOS_FAIL 2
102 #define _IOS_BAD 4
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
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
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
163 enum { // Masks.
164 basefield=dec+oct+hex,
165 floatfield = scientific+fixed,
166 adjustfield = left+right+internal
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; }
177 #endif
179 ostream* tie() const { return _tie; }
180 ostream* tie(ostream* val) { ostream* save=_tie; _tie=val; return save; }
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; }
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(); }
229 streambuf* rdbuf() const { return _strbuf; }
230 streambuf* rdbuf(streambuf *_s) {
231 streambuf *_old = _strbuf; _strbuf = _s; clear (); return _old; }
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;
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
250 // Used to initialize standard streams. Not needed in this implementation.
251 class Init {
252 public:
253 Init () { }
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);
262 #if __GNUG__==1
263 typedef int _seek_dir;
264 #else
265 typedef ios::seek_dir _seek_dir;
266 #endif
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.
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();
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; }
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();
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);
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();
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
422 // A backupbuf is a streambuf with full backup and savepoints on reading.
423 // All standard streambufs in the GNU iostream library are backupbufs.
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
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; }
479 inline ios::ios(streambuf* sb, ostream* tie_to) { init(sb, tie_to); }
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);
489 } // extern "C++"
490 #endif /* _STREAMBUF_H */