// This is part of the iostream library, providing input/output for C++. // Copyright (C) 1991, 1992 Per Bothner. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, 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 // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with this library; if not, write to the Free // Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #define _STREAM_COMPAT #ifdef __GNUG__ #pragma implementation #endif #include "ioprivat.h" #ifdef atarist // for the atari we take a hit here so that bin/text modes are taken care of // automatically by sputc/sbumpc size_t streambuf::sputn(const char* s, size_t n) // OPTIMIZE THIS! { size_t count = 0; for (; count < n; count++) { if (sputc(*s++) == EOF) break; } return count; } size_t streambuf::sgetn(char* s, size_t n) // OPTIMIZE THIS! { size_t count = 0; for (; count < n; count++) { int ch = sbumpc(); if (ch == EOF) break; *s++ = ch; } return count; } #else size_t streambuf::sputn(register const char* s, size_t n) { register size_t more = n; for (;;) { size_t count = _epptr - _pptr; // Space available. if (count > 0) { if (count > more) count = more; if (count > 20) { memcpy(_pptr, s, count); s += count; _pptr += count; } else if (count <= 0) count = 0; else { register char *p = _pptr; for (register long i = count; --i >= 0; ) *p++ = *s++; _pptr = p; } more -= count; } if (more == 0 || overflow(*s++) == EOF) break; more--; } return n - more; } size_t streambuf::sgetn(char* s, size_t n) { register size_t more = n; for (;;) { size_t count = _egptr - _gptr; // Data available. if (count > 0) { if (count > more) count = more; if (count > 20) { memcpy(s, _gptr, count); s += count; _gptr += count; } else if (count <= 0) count = 0; else { register char *p = _gptr; for (register long i = count; --i >= 0; ) *s++ = *p++; _gptr = p; } more -= count; } if (more == 0) break; int c = underflow(); if (c == EOF) break; *s++ = c; more--; } return n - more; } #endif int streambuf::sync() { if (gptr() == egptr() && pptr() == pbase()) return 0; return EOF; } int streambuf::pbackfail(int c) { return EOF; } int streambuf::ungetfail() { if (seekoff(-1, ios::cur, ios::in) == EOF) return EOF; return sgetc(); } streambuf* streambuf::setbuf(char* p, size_t len) { 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); } void streambuf::setb(char* b, char* eb, int a) { if (_base && (_flags & _S_USER_BUF)) FREE_BUF(_base); _base = b; _ebuf = eb; if (a) _flags &= ~_S_USER_BUF; else _flags |= _S_USER_BUF; } #ifdef atarist extern "C" { extern unsigned long __DEFAULT_BUFSIZ__; } int streambuf::doallocate() { char *buf = malloc((size_t)__DEFAULT_BUFSIZ__); if (buf == NULL) return EOF; setb(buf, buf+__DEFAULT_BUFSIZ__, 1); return 1; } #else int streambuf::doallocate() { char *buf = ALLOC_BUF(BUFSIZ); if (buf == NULL) return EOF; setb(buf, buf+BUFSIZ, 1); return 1; } #endif #ifdef atarist extern "C" extern int __default_mode__; #endif streambuf::streambuf() { #ifdef atarist _flags = _IO_MAGIC | ((__default_mode__)? _S_IS_BINARY : 0); #else _flags = _IO_MAGIC; #endif _base = NULL; _ebuf = NULL; _eback = NULL; _gptr = NULL; _egptr = NULL; _pbase = NULL; _pptr = NULL; _epptr = NULL; _chain = NULL; // Not necessary. } streambuf::~streambuf() { if (_base && !(_flags & _S_USER_BUF)) FREE_BUF(_base); } int streambuf::underflow() { return EOF; } int streambuf::overflow(int c = EOF) { return EOF; } streampos streambuf::seekoff(streamoff, _seek_dir, int mode /*=ios::in|ios::out*/) { return EOF; } int streambuf::sputbackc(char c) { if (gptr() <= eback()) return pbackfail(c); gbump(-1); if (*gptr() != c) *gptr() = c; return (unsigned char)c; } int streambuf::sungetc() { if (gptr() > eback()) { gbump(-1); return (unsigned char)*gptr(); } else return ungetfail(); } #if 0 /* Work in progress */ void streambuf::collumn(int c) { if (c == -1) _collumn = -1; else _collumn = c - (_pptr - _pbase); } #endif int streambuf::flush_all() { int result = 0; for (streambuf *sb = _list_all; sb != NULL; sb = sb->xchain()) if (sb->overflow(EOF) == EOF) result = EOF; return result; } void streambuf::flush_all_linebuffered() { for (streambuf *sb = _list_all; sb != NULL; sb = sb->xchain()) if (sb->linebuffered()) sb->sync(); } #ifdef IO_CLEANUP IO_CLEANUP #else struct __io_defs { __io_defs() { } ~__io_defs() { streambuf::flush_all(); } }; __io_defs io_defs__; #endif