xref: /haiku/src/libs/stdc++/legacy/streambuf.cc (revision 16d5c24e533eb14b7b8a99ee9f3ec9ba66335b1e)
1 /* This is part of libio/iostream, providing -*- C++ -*- input/output.
2 Copyright (C) 1991, 1992, 1993, 1995 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 /* Written by Per Bothner (bothner@cygnus.com). */
26 
27 #define _STREAM_COMPAT
28 #ifdef __GNUG__
29 #pragma implementation
30 #endif
31 #include "iostreamP.h"
32 #include <string.h>
33 #include <stdarg.h>
34 #include <errno.h>
35 #ifndef errno
36 extern int errno;
37 #endif
38 
_un_link()39 void streambuf::_un_link() { _IO_un_link(reinterpret_cast<_IO_FILE_plus*>(this)); }
40 
_link_in()41 void streambuf::_link_in() { _IO_link_in(reinterpret_cast<_IO_FILE_plus*>(this)); }
42 
switch_to_get_mode()43 int streambuf::switch_to_get_mode()
44 { return _IO_switch_to_get_mode(this); }
45 
free_backup_area()46 void streambuf::free_backup_area()
47 { _IO_free_backup_area(this); }
48 
49 #if 0
50 int streambuf::switch_to_put_mode()
51 { return _IO_:switch_to_put_mode(this); }
52 #endif
53 
__overflow(streambuf * sb,int c)54 int __overflow(streambuf* sb, int c)
55 {
56     return sb->overflow(c);
57 }
58 
underflow()59 int streambuf::underflow()
60 { return EOF; }
61 
uflow()62 int streambuf::uflow()
63 { return _IO_default_uflow (this); }
64 
overflow(int)65 int streambuf::overflow(int /* = EOF */)
66 { return EOF; }
67 
xsputn(register const char * s,streamsize n)68 streamsize streambuf::xsputn(register const char* s, streamsize n)
69 { return _IO_default_xsputn(this, s, n); }
70 
xsgetn(char * s,streamsize n)71 streamsize streambuf::xsgetn(char* s, streamsize n)
72 { return _IO_default_xsgetn(this, s, n); }
73 
ignore(int n)74 int streambuf::ignore(int n)
75 {
76     register int more = n;
77     for (;;) {
78 	int count = _IO_read_end - _IO_read_ptr; // Data available.
79 	if (count > 0) {
80 	    if (count > more)
81 		count = more;
82 	    _IO_read_ptr += count;
83 	    more -= count;
84 	}
85 	if (more == 0 || __underflow(this) == EOF)
86 	    break;
87     }
88     return n - more;
89 }
90 
sync()91 int streambuf::sync()
92 {
93   return 0;
94 }
95 
pbackfail(int c)96 int streambuf::pbackfail(int c)
97 {
98   return _IO_default_pbackfail(this, c);
99 }
100 
setbuf(char * p,int len)101 streambuf* streambuf::setbuf(char* p, int len)
102 {
103     if (sync() == EOF)
104 	return NULL;
105     if (p == NULL || len == 0) {
106 	unbuffered(1);
107 	setb(_shortbuf, _shortbuf+1, 0);
108     }
109     else {
110 	unbuffered(0);
111 	setb(p, p+len, 0);
112     }
113     setp(0, 0);
114     setg(0, 0, 0);
115     return this;
116 }
117 
seekpos(streampos pos,int mode)118 streampos streambuf::seekpos(streampos pos, int mode)
119 {
120     return seekoff(pos, ios::beg, mode);
121 }
122 
sseekpos(streampos pos,int mode)123 streampos streambuf::sseekpos(streampos pos, int mode)
124 {
125   return _IO_seekpos (this, pos, mode);
126 }
127 
setb(char * b,char * eb,int a)128 void streambuf::setb(char* b, char* eb, int a)
129 { _IO_setb(this, b, eb, a); }
130 
doallocate()131 int streambuf::doallocate() { return _IO_default_doallocate(this); }
132 
doallocbuf()133 void streambuf::doallocbuf() { _IO_doallocbuf(this); }
134 
135 #if !_IO_UNIFIED_JUMPTABLES
136 /* The following are jump table entries that just call the virtual method */
137 
_IO_sb_overflow(_IO_FILE * fp,int c)138 static int _IO_sb_overflow(_IO_FILE *fp, int c)
139 { return ((streambuf*)fp)->overflow(c); }
_IO_sb_underflow(_IO_FILE * fp)140 static int _IO_sb_underflow(_IO_FILE *fp)
141 { return ((streambuf*)fp)->underflow(); }
_IO_sb_xsputn(_IO_FILE * fp,const void * s,_IO_size_t n)142 static _IO_size_t _IO_sb_xsputn(_IO_FILE *fp, const void *s, _IO_size_t n)
143 { return ((streambuf*)fp)->xsputn((const char*)s, n); }
_IO_sb_xsgetn(_IO_FILE * fp,void * s,_IO_size_t n)144 static _IO_size_t _IO_sb_xsgetn(_IO_FILE *fp, void *s, _IO_size_t n)
145 { return ((streambuf*)fp)->xsgetn((char*)s, n); }
_IO_sb_close(_IO_FILE * fp)146 static int _IO_sb_close(_IO_FILE *fp)
147 { return ((streambuf*)fp)->sys_close(); }
_IO_sb_stat(_IO_FILE * fp,void * b)148 static int _IO_sb_stat(_IO_FILE *fp, void *b)
149 { return ((streambuf*)fp)->sys_stat(b); }
_IO_sb_doallocate(_IO_FILE * fp)150 static int _IO_sb_doallocate(_IO_FILE *fp)
151 { return ((streambuf*)fp)->doallocate(); }
152 
_IO_sb_seekoff(_IO_FILE * fp,_IO_off_t pos,int dir,int mode)153 static _IO_pos_t _IO_sb_seekoff(_IO_FILE *fp, _IO_off_t pos, int dir, int mode)
154 {
155   return ((streambuf*)fp)->seekoff(pos, (ios::seek_dir)dir, mode);
156 }
157 
_IO_sb_seekpos(_IO_FILE * fp,_IO_pos_t pos,int mode)158 static _IO_pos_t _IO_sb_seekpos(_IO_FILE *fp, _IO_pos_t pos, int mode)
159 {
160   return ((streambuf*)fp)->seekpos(pos, mode);
161 }
162 
_IO_sb_pbackfail(_IO_FILE * fp,int ch)163 static int _IO_sb_pbackfail(_IO_FILE *fp, int ch)
164 { return ((streambuf*)fp)->pbackfail(ch); }
_IO_sb_finish(_IO_FILE * fp,int)165 static void _IO_sb_finish(_IO_FILE *fp, int)
166 { ((streambuf*)fp)->~streambuf(); }
_IO_sb_read(_IO_FILE * fp,void * buf,_IO_ssize_t n)167 static _IO_ssize_t _IO_sb_read(_IO_FILE *fp, void *buf, _IO_ssize_t n)
168 { return ((streambuf*)fp)->sys_read((char*)buf, n); }
_IO_sb_write(_IO_FILE * fp,const void * buf,_IO_ssize_t n)169 static _IO_ssize_t _IO_sb_write(_IO_FILE *fp, const void *buf, _IO_ssize_t n)
170 { return ((streambuf*)fp)->sys_write((const char*)buf, n); }
_IO_sb_sync(_IO_FILE * fp)171 static int _IO_sb_sync(_IO_FILE *fp)
172 { return ((streambuf*)fp)->sync(); }
_IO_sb_seek(_IO_FILE * fp,_IO_off_t off,int dir)173 static _IO_pos_t _IO_sb_seek(_IO_FILE *fp, _IO_off_t off, int dir)
174 { return ((streambuf*)fp)->sys_seek(off, (_seek_dir)dir); }
_IO_sb_setbuf(_IO_FILE * fp,char * buf,_IO_ssize_t n)175 static _IO_FILE* _IO_sb_setbuf(_IO_FILE *fp, char *buf, _IO_ssize_t n)
176 { return ((streambuf*)fp)->setbuf(buf, n); }
177 
178 /* This callbacks in this jumptable just call the corresponding
179    virtual function, so that C functions can access (potentially user-defined)
180    streambuf-derived objects.
181    Contrast the builtinbuf class, which does the converse:  Allow
182    C++ virtual calls to be used on _IO_FILE objects that are builtin
183    (or defined by C code). */
184 
185 
186 struct _IO_jump_t _IO_streambuf_jumps = {
187   JUMP_INIT_DUMMY,
188   JUMP_INIT(finish, _IO_sb_finish),
189   JUMP_INIT(overflow, _IO_sb_overflow),
190   JUMP_INIT(underflow, _IO_sb_underflow),
191   JUMP_INIT(uflow, _IO_default_uflow),
192   JUMP_INIT(pbackfail, _IO_sb_pbackfail),
193   JUMP_INIT(xsputn, _IO_sb_xsputn),
194   JUMP_INIT(xsgetn, _IO_sb_xsgetn),
195   JUMP_INIT(seekoff, _IO_sb_seekoff),
196   JUMP_INIT(seekpos, _IO_sb_seekpos),
197   JUMP_INIT(setbuf, _IO_sb_setbuf),
198   JUMP_INIT(sync, _IO_sb_sync),
199   JUMP_INIT(doallocate, _IO_sb_doallocate),
200   JUMP_INIT(read, _IO_sb_read),
201   JUMP_INIT(write, _IO_sb_write),
202   JUMP_INIT(seek, _IO_sb_seek),
203   JUMP_INIT(close, _IO_sb_close),
204   JUMP_INIT(stat, _IO_sb_stat)
205 };
206 #endif
207 
streambuf(int flags)208 streambuf::streambuf(int flags)
209 {
210 #ifdef _IO_MTSAFE_IO
211   _lock = new _IO_lock_t;
212 #endif
213   _IO_init(this, flags);
214 #if !_IO_UNIFIED_JUMPTABLES
215   _jumps = &_IO_streambuf_jumps;
216 #endif
217 }
218 
~streambuf()219 streambuf::~streambuf()
220 {
221   _IO_default_finish(this,0);
222 #ifdef _IO_MTSAFE_IO
223   if (this != _IO_stdin && this != _IO_stdout && this != _IO_stderr)
224     delete _lock;
225 #endif
226 }
227 
228 streampos
seekoff(streamoff,_seek_dir,int)229 streambuf::seekoff(streamoff, _seek_dir, int /*=ios::in|ios::out*/)
230 {
231     return EOF;
232 }
233 
234 streampos
sseekoff(streamoff o,_seek_dir d,int m)235 streambuf::sseekoff(streamoff o , _seek_dir d, int m /*=ios::in|ios::out*/)
236 {
237   return _IO_seekoff (this, o, d, m);
238 }
239 
sputbackc(char c)240 int streambuf::sputbackc(char c)
241 {
242   return _IO_sputbackc(this, c);
243 }
244 
sungetc()245 int streambuf::sungetc()
246 {
247   return _IO_sungetc(this);
248 }
249 
250 #if 0 /* Work in progress */
251 void streambuf::collumn(int c)
252 {
253     if (c == -1)
254 	_collumn = -1;
255     else
256 	_collumn = c - (_IO_write_ptr - _IO_write_base);
257 }
258 #endif
259 
260 
get_column()261 int streambuf::get_column()
262 {
263     if (_cur_column)
264 	return _IO_adjust_column(_cur_column - 1, pbase(), pptr() - pbase());
265     return -1;
266 }
267 
set_column(int i)268 int streambuf::set_column(int i)
269 {
270     _cur_column = i+1;
271     return 0;
272 }
273 
flush_all()274 int streambuf::flush_all() { return _IO_flush_all (); }
275 
flush_all_linebuffered()276 void streambuf::flush_all_linebuffered()
277 { _IO_flush_all_linebuffered(); }
278 
sys_stat(void *)279 int streambuf::sys_stat(void *)
280 {
281 #ifdef EIO
282   errno = EIO;
283 #endif
284   return -1;
285 }
286 
sys_read(char *,streamsize)287 streamsize streambuf::sys_read(char* /*buf*/, streamsize /*size*/)
288 {
289   return 0;
290 }
291 
sys_write(const char *,streamsize)292 streamsize streambuf::sys_write(const char* /*buf*/, streamsize /*size*/)
293 {
294   return 0;
295 }
296 
sys_seek(streamoff,_seek_dir)297 streampos streambuf::sys_seek(streamoff, _seek_dir)
298 {
299   return EOF;
300 }
301 
sys_close()302 int streambuf::sys_close() { return 0; /* Suceess; do nothing */ }
303 
304 #if _G_IO_IO_FILE_VERSION == 0x20001
showmanyc()305 int streambuf::showmanyc()
306 {
307   return -1;
308 }
309 
imbue(void *)310 void streambuf::imbue(void *)
311 {
312 }
313 #endif
314 
streammarker(streambuf * sb)315 streammarker::streammarker(streambuf *sb)
316 {
317   _IO_init_marker(this, sb);
318 }
319 
~streammarker()320 streammarker::~streammarker()
321 {
322   _IO_remove_marker(this);
323 }
324 
325 #define BAD_DELTA EOF
326 
delta(streammarker & other_mark)327 int streammarker::delta(streammarker& other_mark)
328 {
329   return _IO_marker_difference(this, &other_mark);
330 }
331 
delta()332 int streammarker::delta()
333 {
334   return _IO_marker_delta(this);
335 }
336 
seekmark(streammarker & mark,int delta)337 int streambuf::seekmark(streammarker& mark, int delta /* = 0 */)
338 {
339   return _IO_seekmark(this, &mark, delta);
340 }
341 
unsave_markers()342 void streambuf::unsave_markers()
343 {
344   _IO_unsave_markers(this);
345 }
346 
readable()347 int ios::readable() { return !(rdbuf()->_flags & _IO_NO_READS); }
writable()348 int ios::writable() { return !(rdbuf()->_flags & _IO_NO_WRITES); }
is_open()349 int ios::is_open() { return rdbuf()
350 			 && (rdbuf()->_flags & _IO_NO_READS+_IO_NO_WRITES)
351 			     != _IO_NO_READS+_IO_NO_WRITES; }
352 
353 #if defined(linux)
354 #define IO_CLEANUP
355 #endif
356 
357 #ifdef IO_CLEANUP
358   IO_CLEANUP
359 #else
360 struct __io_defs {
361     ~__io_defs() { _IO_cleanup (); }
362 };
363 __io_defs io_defs__;
364 #endif
365