iostream.h

00001 /*
00002  *  Copyright (C) 2006  Helmut Grohne
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 #ifndef LIBMUTH_IOSTREAM_H
00020 #define LIBMUTH_IOSTREAM_H
00021 
00022 #include <assert.h>
00023 #include "iostream_decls.h"
00024 
00025 template<class C, class T>
00026                 BasicScheduledStreambuf<C, T>::BasicScheduledStreambuf(int f,
00027                 BaseScheduler &s, std::ios_base::openmode m,
00028                 std::streamsize insize, std::streamsize outsize) : fd(f),
00029                 sched(s), mode(m) {
00030         // Do not allow opening a stream neither for reading nor for writing.
00031         assert(this->mode & (std::ios_base::in|std::ios_base::out));
00032         this->ibufsize = insize;
00033         if(this->mode & std::ios_base::in)
00034                 this->ibuf = new char_type[insize];
00035         else
00036                 this->ibuf = NULL;
00037         this->setg(this->ibuf, this->ibuf, this->ibuf);
00038         if(this->mode & std::ios_base::out) {
00039                 this->obuf = new char_type[outsize];
00040                 this->setp(this->obuf, this->obuf + outsize);
00041         } else {
00042                 this->obuf = NULL;
00043                 this->setp(NULL, NULL);
00044         }
00045 }
00046 
00047 template<class C, class T>
00048                 BasicScheduledStreambuf<C, T>::~BasicScheduledStreambuf() {
00049         if(this->mode & std::ios_base::in)
00050                 delete[] this->ibuf;
00051         if(this->mode & std::ios_base::out) {
00052                 this->sync();
00053                 delete[] this->obuf;
00054         }
00055 }
00056 
00057 template<class C, class T> typename BasicScheduledStreambuf<C, T>::int_type
00058                 BasicScheduledStreambuf<C, T>::underflow() {
00059         assert(this->mode & std::ios_base::in);
00060         if(this->gptr() < this->egptr())
00061                 return traits_type::to_int_type(*this->gptr());
00062         assert(this->ibufsize > 0);
00063         const int r(this->sched.read(this->fd, this->ibuf,
00064                         this->ibufsize * sizeof(char_type)));
00065         if(r <= 0)
00066                 return traits_type::eof();
00067         /* FIXME: this will result in problems showed by assertions: */
00068         assert(r % sizeof(char_type) == 0);
00069         this->setg(this->ibuf, this->ibuf, static_cast<char_type*>(
00070                         static_cast<char*>(this->ibuf) + r));
00071         return traits_type::to_int_type(*this->gptr());
00072 }
00073 
00074 template<class C, class T> typename BasicScheduledStreambuf<C, T>::int_type
00075                 BasicScheduledStreambuf<C, T>::pbackfail(int_type ch) {
00076         assert(this->mode & std::ios_base::in);
00077         if(this->gptr() != this->eback()) {
00078                 this->gbump(-1);
00079                 if(!traits_type::eq_int_type(ch, traits_type::eof()))
00080                         *this->gptr() = traits_type::not_eof(ch);
00081                 return traits_type::not_eof(ch);
00082         }
00083         return traits_type::eof();
00084 }
00085 
00086 template<class C, class T> int BasicScheduledStreambuf<C, T>::sync() {
00087         assert(this->mode & std::ios_base::out);
00088         const int bump(static_cast<int>(this->pptr() - this->pbase()));
00089         char *data(static_cast<char*>(this->pbase()));
00090         size_t n(static_cast<size_t>(static_cast<char*>(this->pptr()) - data));
00091         if(n == 0)
00092                 return 0;
00093         int r(this->sched.write(this->fd, data, n));
00094         if(r <= 0)
00095                 return -1;
00096         assert(n >= (size_t)r);
00097         while((size_t)r != n) {
00098                 r = this->sched.write(this->fd, data, n);
00099                 if(r <= 0)
00100                         return -1;
00101                 assert(n < (size_t)r);
00102                 data += r;
00103                 n -= r;
00104         }
00105         this->pbump(-bump);
00106         return 0;
00107 }
00108 
00109 template<class C, class T> typename BasicScheduledStreambuf<C, T>::int_type
00110                 BasicScheduledStreambuf<C, T>::overflow(int_type ch) {
00111         assert(this->mode & std::ios_base::out);
00112         /* FIXME: maybe not really sync but write parts of the buffer. */
00113         if(this->sync() < 0)
00114                 return traits_type::eof();
00115         if(traits_type::eq_int_type(ch, traits_type::eof()))
00116                 /* FIXME: find out why we return not_eof(eof()). */
00117                 return traits_type::not_eof(ch);
00118         return this->sputc(traits_type::to_char_type(ch));
00119 }
00120 
00121 #if 0
00122 template<class C, class T> std::streamsize
00123                 BasicScheduledStreambuf<C, T>::xsputn(const char_type *str,
00124                 std::streamsize n) {
00125         assert(this->mode & std::ios_base::out);
00126         if(this->sync() < 0)
00127                 return 0;
00128         const int r(this->sched.write(this->fd, str, n * sizeof(char_type)));
00129         if(r < 0)
00130                 return 0;
00131         return r / sizeof(char_type);
00132 }
00133 #endif
00134 
00135 template<class C, class T> inline BasicScheduledStreambuf<C, T>::operator int()
00136                 const {
00137         return this->fd;
00138 }
00139 
00140 template<class C, class T> BasicScheduledIStream<C, T>::BasicScheduledIStream(
00141                 int f, BaseScheduler &s, std::streamsize size)
00142                 : std::basic_istream<C, T>(NULL),
00143                 streambuf(f, s, std::ios_base::in, size) {
00144         this->init(&this->streambuf);
00145 }
00146 
00147 template<class C, class T> inline BasicScheduledIStream<C, T>::operator int()
00148                 const {
00149         return (int)this->streambuf;
00150 }
00151 
00152 template<class C, class T> BasicScheduledOStream<C, T>::BasicScheduledOStream(
00153                 int f, BaseScheduler &s, std::streamsize size)
00154                 : std::basic_ostream<C, T>(NULL),
00155                 streambuf(f, s, std::ios_base::out, 0, size) {
00156         this->init(&this->streambuf);
00157 }
00158 
00159 template<class C, class T> inline BasicScheduledOStream<C, T>::operator int()
00160                 const {
00161         return (int)this->streambuf;
00162 }
00163 
00164 template<class C, class T> BasicScheduledIOStream<C, T>::BasicScheduledIOStream(
00165                 int f, BaseScheduler &s, std::streamsize insize,
00166                 std::streamsize outsize) : std::basic_iostream<C, T>(NULL),
00167                 streambuf(f, s, std::ios_base::in | std::ios_base::out, insize,
00168                 outsize) {
00169         this->init(&this->streambuf);
00170 }
00171 
00172 template<class C, class T> inline BasicScheduledIOStream<C, T>::operator int()
00173                 const {
00174         return (int)this->streambuf;
00175 }
00176 
00177 #endif

Generated on Thu Feb 14 13:30:30 2008 by  doxygen 1.5.1