summaryrefslogtreecommitdiff
path: root/libio/streambuf.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libio/streambuf.cc')
-rw-r--r--libio/streambuf.cc343
1 files changed, 343 insertions, 0 deletions
diff --git a/libio/streambuf.cc b/libio/streambuf.cc
new file mode 100644
index 00000000000..d66af097aa5
--- /dev/null
+++ b/libio/streambuf.cc
@@ -0,0 +1,343 @@
+/* This is part of libio/iostream, providing -*- C++ -*- input/output.
+Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation
+
+This file is part of the GNU IO Library. This library is free
+software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this does not cause
+the resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License. */
+
+/* Written by Per Bothner (bothner@cygnus.com). */
+
+#define _STREAM_COMPAT
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "iostreamP.h"
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
+void streambuf::_un_link() { _IO_un_link(this); }
+
+void streambuf::_link_in() { _IO_link_in(this); }
+
+int streambuf::switch_to_get_mode()
+{ return _IO_switch_to_get_mode(this); }
+
+void streambuf::free_backup_area()
+{ _IO_free_backup_area(this); }
+
+#if 0
+int streambuf::switch_to_put_mode()
+{ return _IO_:switch_to_put_mode(this); }
+#endif
+
+int __overflow(streambuf* sb, int c)
+{
+ return sb->overflow(c);
+}
+
+int streambuf::underflow()
+{ return EOF; }
+
+int streambuf::uflow()
+{ return _IO_default_uflow (this); }
+
+int streambuf::overflow(int /* = EOF */)
+{ return EOF; }
+
+streamsize streambuf::xsputn(register const char* s, streamsize n)
+{ return _IO_default_xsputn(this, s, n); }
+
+streamsize streambuf::xsgetn(char* s, streamsize n)
+{ return _IO_default_xsgetn(this, s, n); }
+
+int streambuf::ignore(int n)
+{
+ register int more = n;
+ for (;;) {
+ int count = _IO_read_end - _IO_read_ptr; // Data available.
+ if (count > 0) {
+ if (count > more)
+ count = more;
+ _IO_read_ptr += count;
+ more -= count;
+ }
+ if (more == 0 || __underflow(this) == EOF)
+ break;
+ }
+ return n - more;
+}
+
+int streambuf::sync()
+{
+ return 0;
+}
+
+int streambuf::pbackfail(int c)
+{
+ return _IO_default_pbackfail(this, c);
+}
+
+streambuf* streambuf::setbuf(char* p, int len)
+{
+ if (sync() == EOF)
+ return NULL;
+ if (p == NULL || len == 0) {
+ unbuffered(1);
+ setb(_shortbuf, _shortbuf+1, 0);
+ }
+ else {
+ unbuffered(0);
+ setb(p, p+len, 0);
+ }
+ setp(0, 0);
+ setg(0, 0, 0);
+ return this;
+}
+
+streampos streambuf::seekpos(streampos pos, int mode)
+{
+ return seekoff(pos, ios::beg, mode);
+}
+
+streampos streambuf::sseekpos(streampos pos, int mode)
+{
+ return _IO_seekpos (this, pos, mode);
+}
+
+void streambuf::setb(char* b, char* eb, int a)
+{ _IO_setb(this, b, eb, a); }
+
+int streambuf::doallocate() { return _IO_default_doallocate(this); }
+
+void streambuf::doallocbuf() { _IO_doallocbuf(this); }
+
+#if !_IO_UNIFIED_JUMPTABLES
+/* The following are jump table entries that just call the virtual method */
+
+static int _IO_sb_overflow(_IO_FILE *fp, int c)
+{ return ((streambuf*)fp)->overflow(c); }
+static int _IO_sb_underflow(_IO_FILE *fp)
+{ return ((streambuf*)fp)->underflow(); }
+static _IO_size_t _IO_sb_xsputn(_IO_FILE *fp, const void *s, _IO_size_t n)
+{ return ((streambuf*)fp)->xsputn((const char*)s, n); }
+static _IO_size_t _IO_sb_xsgetn(_IO_FILE *fp, void *s, _IO_size_t n)
+{ return ((streambuf*)fp)->xsgetn((char*)s, n); }
+static int _IO_sb_close(_IO_FILE *fp)
+{ return ((streambuf*)fp)->sys_close(); }
+static int _IO_sb_stat(_IO_FILE *fp, void *b)
+{ return ((streambuf*)fp)->sys_stat(b); }
+static int _IO_sb_doallocate(_IO_FILE *fp)
+{ return ((streambuf*)fp)->doallocate(); }
+
+static _IO_pos_t _IO_sb_seekoff(_IO_FILE *fp, _IO_off_t pos, int dir, int mode)
+{
+ return ((streambuf*)fp)->seekoff(pos, (ios::seek_dir)dir, mode);
+}
+
+static _IO_pos_t _IO_sb_seekpos(_IO_FILE *fp, _IO_pos_t pos, int mode)
+{
+ return ((streambuf*)fp)->seekpos(pos, mode);
+}
+
+static int _IO_sb_pbackfail(_IO_FILE *fp, int ch)
+{ return ((streambuf*)fp)->pbackfail(ch); }
+static void _IO_sb_finish(_IO_FILE *fp)
+{ ((streambuf*)fp)->~streambuf(); }
+static _IO_ssize_t _IO_sb_read(_IO_FILE *fp, void *buf, _IO_ssize_t n)
+{ return ((streambuf*)fp)->sys_read((char*)buf, n); }
+static _IO_ssize_t _IO_sb_write(_IO_FILE *fp, const void *buf, _IO_ssize_t n)
+{ return ((streambuf*)fp)->sys_write((const char*)buf, n); }
+static int _IO_sb_sync(_IO_FILE *fp)
+{ return ((streambuf*)fp)->sync(); }
+static _IO_pos_t _IO_sb_seek(_IO_FILE *fp, _IO_off_t off, int dir)
+{ return ((streambuf*)fp)->sys_seek(off, (_seek_dir)dir); }
+static _IO_FILE* _IO_sb_setbuf(_IO_FILE *fp, char *buf, _IO_ssize_t n)
+{ return ((streambuf*)fp)->setbuf(buf, n); }
+
+/* This callbacks in this jumptable just call the corresponding
+ virtual function, so that C functions can access (potentially user-defined)
+ streambuf-derived objects.
+ Contrast the builtinbuf class, which does the converse: Allow
+ C++ virtual calls to to be used on _IO_FILE objects that are builtin
+ (or defined by C code). */
+
+
+struct _IO_jump_t _IO_streambuf_jumps = {
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_sb_finish),
+ JUMP_INIT(overflow, _IO_sb_overflow),
+ JUMP_INIT(underflow, _IO_sb_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_sb_pbackfail),
+ JUMP_INIT(xsputn, _IO_sb_xsputn),
+ JUMP_INIT(xsgetn, _IO_sb_xsgetn),
+ JUMP_INIT(seekoff, _IO_sb_seekoff),
+ JUMP_INIT(seekpos, _IO_sb_seekpos),
+ JUMP_INIT(setbuf, _IO_sb_setbuf),
+ JUMP_INIT(sync, _IO_sb_sync),
+ JUMP_INIT(doallocate, _IO_sb_doallocate),
+ JUMP_INIT(read, _IO_sb_read),
+ JUMP_INIT(write, _IO_sb_write),
+ JUMP_INIT(seek, _IO_sb_seek),
+ JUMP_INIT(close, _IO_sb_close),
+ JUMP_INIT(stat, _IO_sb_stat)
+};
+#endif
+
+streambuf::streambuf(int flags)
+{
+ _IO_init(this, flags);
+#if !_IO_UNIFIED_JUMPTABLES
+ _jumps = &_IO_streambuf_jumps;
+#endif
+}
+
+streambuf::~streambuf() { _IO_default_finish(this); }
+
+streampos
+streambuf::seekoff(streamoff, _seek_dir, int /*=ios::in|ios::out*/)
+{
+ return EOF;
+}
+
+streampos
+streambuf::sseekoff(streamoff o , _seek_dir d, int m /*=ios::in|ios::out*/)
+{
+ return _IO_seekoff (this, o, d, m);
+}
+
+int streambuf::sputbackc(char c)
+{
+ return _IO_sputbackc(this, c);
+}
+
+int streambuf::sungetc()
+{
+ return _IO_sungetc(this);
+}
+
+#if 0 /* Work in progress */
+void streambuf::collumn(int c)
+{
+ if (c == -1)
+ _collumn = -1;
+ else
+ _collumn = c - (_IO_write_ptr - _IO_write_base);
+}
+#endif
+
+
+int streambuf::get_column()
+{
+ if (_cur_column)
+ return _IO_adjust_column(_cur_column - 1, pbase(), pptr() - pbase());
+ return -1;
+}
+
+int streambuf::set_column(int i)
+{
+ _cur_column = i+1;
+ return 0;
+}
+
+int streambuf::flush_all() { return _IO_flush_all (); }
+
+void streambuf::flush_all_linebuffered()
+{ _IO_flush_all_linebuffered(); }
+
+int streambuf::sys_stat(void *)
+{
+#ifdef EIO
+ errno = EIO;
+#endif
+ return -1;
+}
+
+streamsize streambuf::sys_read(char* /*buf*/, streamsize /*size*/)
+{
+ return 0;
+}
+
+streamsize streambuf::sys_write(const char* /*buf*/, streamsize /*size*/)
+{
+ return 0;
+}
+
+streampos streambuf::sys_seek(streamoff, _seek_dir)
+{
+ return EOF;
+}
+
+int streambuf::sys_close() { return 0; /* Suceess; do nothing */ }
+
+streammarker::streammarker(streambuf *sb)
+{
+ _IO_init_marker(this, sb);
+}
+
+streammarker::~streammarker()
+{
+ _IO_remove_marker(this);
+}
+
+#define BAD_DELTA EOF
+
+int streammarker::delta(streammarker& other_mark)
+{
+ return _IO_marker_difference(this, &other_mark);
+}
+
+int streammarker::delta()
+{
+ return _IO_marker_delta(this);
+}
+
+int streambuf::seekmark(streammarker& mark, int delta /* = 0 */)
+{
+ return _IO_seekmark(this, &mark, delta);
+}
+
+void streambuf::unsave_markers()
+{
+ _IO_unsave_markers(this);
+}
+
+int ios::readable() { return !(rdbuf()->_flags & _IO_NO_READS); }
+int ios::writable() { return !(rdbuf()->_flags & _IO_NO_WRITES); }
+int ios::is_open() { return rdbuf()
+ && (rdbuf()->_flags & _IO_NO_READS+_IO_NO_WRITES)
+ != _IO_NO_READS+_IO_NO_WRITES; }
+
+#if defined(linux)
+#define IO_CLEANUP
+#endif
+
+#ifdef IO_CLEANUP
+ IO_CLEANUP
+#else
+struct __io_defs {
+ ~__io_defs() { _IO_cleanup (); }
+};
+__io_defs io_defs__;
+#endif