61d5ffaf10
issues in these areas: .h's installed .hP's installed -lcurses interaction files needed in ~/legal for copyleft reasons.
342 lines
8.2 KiB
C++
342 lines
8.2 KiB
C++
/* This is part of libio/iostream, providing -*- C++ -*- input/output.
|
|
Copyright (C) 1991, 1992, 1993 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 GNU CC; see the file COPYING. If not, write to
|
|
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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::overflow(int c /* = 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()
|
|
{
|
|
if (pptr() == pbase())
|
|
return 0;
|
|
return EOF;
|
|
}
|
|
|
|
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, convert_to_seekflags (0, 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); }
|
|
|
|
/* 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, _IO_seekflags m)
|
|
{
|
|
int mode = ((m & _IO_seek_not_in) ? 0 : ios::in)
|
|
+ ((m & _IO_seek_not_out) ? 0 : ios::out);
|
|
return ((streambuf*)fp)->seekoff(pos, (_seek_dir)((int)m & 3), mode);
|
|
}
|
|
|
|
static _IO_pos_t _IO_sb_seekpos(_IO_FILE *fp, _IO_pos_t pos, _IO_seekflags m)
|
|
{
|
|
int mode = ((m & _IO_seek_not_in) ? 0 : ios::in)
|
|
+ ((m & _IO_seek_not_out) ? 0 : ios::out);
|
|
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 int _IO_sb_setbuf(_IO_FILE *fp, char *buf, _IO_ssize_t n)
|
|
{ return ((streambuf*)fp)->setbuf(buf, n) == NULL ? EOF : 0; }
|
|
|
|
/* 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 = {
|
|
_IO_sb_overflow,
|
|
_IO_sb_underflow,
|
|
_IO_sb_xsputn,
|
|
_IO_sb_xsgetn,
|
|
_IO_sb_read,
|
|
_IO_sb_write,
|
|
_IO_sb_doallocate,
|
|
_IO_sb_pbackfail,
|
|
_IO_sb_setbuf,
|
|
_IO_sb_sync,
|
|
_IO_sb_finish,
|
|
_IO_sb_close,
|
|
_IO_sb_stat,
|
|
_IO_sb_seek,
|
|
_IO_sb_seekoff,
|
|
_IO_sb_seekpos,
|
|
_IO_default_uflow
|
|
};
|
|
|
|
streambuf::streambuf(int flags)
|
|
{
|
|
_IO_init(this, flags);
|
|
_jumps = &_IO_streambuf_jumps;
|
|
}
|
|
|
|
streambuf::~streambuf() { _IO_default_finish(this); }
|
|
|
|
streampos
|
|
streambuf::seekoff(streamoff, _seek_dir, int mode /*=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, convert_to_seekflags (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
|