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 "compiler.h"
00024 #include "iostream_decls.h"
00025
00026 template<class C, class T>
00027 BasicScheduledStreambuf<C, T>::BasicScheduledStreambuf(int f,
00028 BaseScheduler &s, std::ios_base::openmode m,
00029 std::streamsize insize, std::streamsize outsize) : fd(f),
00030 sched(s), mode(m) {
00031
00032 assert(this->mode & (std::ios_base::in|std::ios_base::out));
00033 this->ibufsize = insize;
00034 if(this->mode & std::ios_base::in)
00035 this->ibuf = new char_type[insize];
00036 else
00037 this->ibuf = NULL;
00038 this->setg(this->ibuf, this->ibuf, this->ibuf);
00039 if(this->mode & std::ios_base::out) {
00040 this->obuf = new char_type[outsize];
00041 this->setp(this->obuf, this->obuf + outsize);
00042 } else {
00043 this->obuf = NULL;
00044 this->setp(NULL, NULL);
00045 }
00046 }
00047
00048 template<class C, class T>
00049 BasicScheduledStreambuf<C, T>::~BasicScheduledStreambuf() {
00050 if(this->mode & std::ios_base::in)
00051 delete[] this->ibuf;
00052 if(this->mode & std::ios_base::out) {
00053 this->sync();
00054 delete[] this->obuf;
00055 }
00056 }
00057
00058 template<class C, class T> typename BasicScheduledStreambuf<C, T>::int_type
00059 BasicScheduledStreambuf<C, T>::underflow() {
00060 assert(this->mode & std::ios_base::in);
00061 if(this->gptr() < this->egptr())
00062 return traits_type::to_int_type(*this->gptr());
00063 assert(this->ibufsize > 0);
00064 const int r(this->sched.read(this->fd, this->ibuf,
00065 this->ibufsize * sizeof(char_type)));
00066 if(unlikely(r <= 0))
00067 return traits_type::eof();
00068
00069 assert(r % sizeof(char_type) == 0);
00070 this->setg(this->ibuf, this->ibuf, static_cast<char_type*>(
00071 static_cast<char*>(this->ibuf) + r));
00072 return traits_type::to_int_type(*this->gptr());
00073 }
00074
00075 template<class C, class T> typename BasicScheduledStreambuf<C, T>::int_type
00076 BasicScheduledStreambuf<C, T>::pbackfail(int_type ch) {
00077 assert(this->mode & std::ios_base::in);
00078 if(likely(this->gptr() != this->eback())) {
00079 this->gbump(-1);
00080 if(!traits_type::eq_int_type(ch, traits_type::eof()))
00081 *this->gptr() = traits_type::not_eof(ch);
00082 return traits_type::not_eof(ch);
00083 }
00084 return traits_type::eof();
00085 }
00086
00087 template<class C, class T> int BasicScheduledStreambuf<C, T>::sync() {
00088 assert(this->mode & std::ios_base::out);
00089 const int bump(static_cast<int>(this->pptr() - this->pbase()));
00090 char *data(static_cast<char*>(this->pbase()));
00091 size_t n(static_cast<size_t>(static_cast<char*>(this->pptr()) - data));
00092 if(n == 0)
00093 return 0;
00094 int r(this->sched.write(this->fd, data, n));
00095 if(unlikely(r <= 0))
00096 return -1;
00097 assert(n >= (size_t)r);
00098 while((size_t)r != n) {
00099 r = this->sched.write(this->fd, data, n);
00100 if(unlikely(r <= 0))
00101 return -1;
00102 assert(n >= (size_t)r);
00103 data += r;
00104 n -= r;
00105 }
00106 this->pbump(-bump);
00107 return 0;
00108 }
00109
00110 template<class C, class T> typename BasicScheduledStreambuf<C, T>::int_type
00111 BasicScheduledStreambuf<C, T>::overflow(int_type ch) {
00112 assert(this->mode & std::ios_base::out);
00113
00114 if(unlikely(this->sync() < 0))
00115 return traits_type::eof();
00116 if(traits_type::eq_int_type(ch, traits_type::eof()))
00117
00118 return traits_type::not_eof(ch);
00119 return this->sputc(traits_type::to_char_type(ch));
00120 }
00121
00122 #if 0
00123 template<class C, class T> std::streamsize
00124 BasicScheduledStreambuf<C, T>::xsputn(const char_type *str,
00125 std::streamsize n) {
00126 assert(this->mode & std::ios_base::out);
00127 if(this->sync() < 0)
00128 return 0;
00129 const int r(this->sched.write(this->fd, str, n * sizeof(char_type)));
00130 if(r < 0)
00131 return 0;
00132 return r / sizeof(char_type);
00133 }
00134 #endif
00135
00136 template<class C, class T> inline BasicScheduledStreambuf<C, T>::operator int()
00137 const {
00138 return this->fd;
00139 }
00140
00141 template<class C, class T> BasicScheduledIStream<C, T>::BasicScheduledIStream(
00142 int f, BaseScheduler &s, std::streamsize size)
00143 : std::basic_istream<C, T>(NULL),
00144 streambuf(f, s, std::ios_base::in, size) {
00145 this->init(&this->streambuf);
00146 }
00147
00148 template<class C, class T> inline BasicScheduledIStream<C, T>::operator int()
00149 const {
00150 return (int)this->streambuf;
00151 }
00152
00153 template<class C, class T> BasicScheduledOStream<C, T>::BasicScheduledOStream(
00154 int f, BaseScheduler &s, std::streamsize size)
00155 : std::basic_ostream<C, T>(NULL),
00156 streambuf(f, s, std::ios_base::out, 0, size) {
00157 this->init(&this->streambuf);
00158 }
00159
00160 template<class C, class T> inline BasicScheduledOStream<C, T>::operator int()
00161 const {
00162 return (int)this->streambuf;
00163 }
00164
00165 template<class C, class T> BasicScheduledIOStream<C, T>::BasicScheduledIOStream(
00166 int f, BaseScheduler &s, std::streamsize insize,
00167 std::streamsize outsize) : std::basic_iostream<C, T>(NULL),
00168 streambuf(f, s, std::ios_base::in | std::ios_base::out, insize,
00169 outsize) {
00170 this->init(&this->streambuf);
00171 }
00172
00173 template<class C, class T> inline BasicScheduledIOStream<C, T>::operator int()
00174 const {
00175 return (int)this->streambuf;
00176 }
00177
00178 #endif