00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
00113 if(this->sync() < 0)
00114 return traits_type::eof();
00115 if(traits_type::eq_int_type(ch, traits_type::eof()))
00116
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