00001
00002
00003
00004
00005 #ifndef __WVSTREAM_H
00006 #define __WVSTREAM_H
00007
00008 #include "wvstring.h"
00009 #include "wvbuffer.h"
00010 #include "wvcallback.h"
00011 #include <unistd.h>
00012 #include <sys/time.h>
00013 #include <errno.h>
00014
00015 class WvAddr;
00016 class WvTask;
00017 class WvTaskMan;
00018 class WvStream;
00019
00020
00021 DeclareWvCallback(2, void, WvStreamCallback, WvStream &, void *);
00022
00030 class WvStream
00031 {
00032 public:
00038 WvStream(int _fd);
00039 virtual ~WvStream();
00040
00045 WvStream(const WvStream &s);
00046 WvStream& operator= (const WvStream &s);
00047
00055 virtual void close();
00056
00060 virtual int getrfd() const;
00061
00065 virtual int getwfd() const;
00066
00070 int getfd() const;
00071
00075 virtual bool isok() const;
00076
00083 virtual int geterr() const;
00084 virtual const char *errstr() const;
00085
00089 size_t read(void *buf, size_t count);
00090
00094 size_t write(const void *buf, size_t count);
00095
00102 void outbuf_limit(size_t size)
00103 { max_outbuf_size = size; }
00104
00110 virtual size_t uread(void *buf, size_t count);
00111
00117 virtual size_t uwrite(const void *buf, size_t count);
00118
00133 char *getline(time_t wait_msec, char separator = '\n');
00134
00147 void queuemin(size_t count)
00148 { queue_min = count; }
00149
00154 void drain();
00155
00161 void delay_output(bool is_delayed)
00162 { outbuf_delayed_flush = is_delayed; }
00163
00168 void flush(time_t msec_timeout);
00169
00176 void flush_then_close(int msec_timeout);
00177
00183 struct SelectRequest {
00184 bool readable, writable, isexception;
00185
00186 SelectRequest() { }
00187 SelectRequest(bool r, bool w, bool x = false)
00188 { readable = r; writable = w; isexception = x; }
00189
00190 SelectRequest &operator |= (const SelectRequest &r)
00191 { readable |= r.readable; writable |= r.writable;
00192 isexception |= r.isexception; return *this; }
00193 };
00194
00199 SelectRequest force;
00200
00205 WvStream *read_requires_writable;
00206
00211 WvStream *write_requires_readable;
00212
00217 struct SelectInfo {
00218 fd_set read, write, except;
00219 SelectRequest wants;
00220 int max_fd;
00221 time_t msec_timeout;
00222 bool inherit_request;
00223 };
00224
00246 virtual bool pre_select(SelectInfo &si);
00247
00252 bool pre_select(SelectInfo &si, const SelectRequest &r)
00253 {
00254 SelectRequest oldwant = si.wants;
00255 si.wants = r;
00256 bool val = pre_select(si);
00257 si.wants = oldwant;
00258 return val;
00259 }
00260
00274 virtual bool post_select(SelectInfo &si);
00275
00280 bool post_select(SelectInfo &si, const SelectRequest &r)
00281 {
00282 SelectRequest oldwant = si.wants;
00283 si.wants = r;
00284 bool val = post_select(si);
00285 si.wants = oldwant;
00286 return val;
00287 }
00288
00308 bool select(time_t msec_timeout)
00309 { return _select(msec_timeout, false, false, false, true); }
00310
00324 bool select(time_t msec_timeout,
00325 bool readable, bool writable, bool isex = false)
00326 { return _select(msec_timeout, readable, writable, isex, false); }
00327
00336 void force_select(bool readable, bool writable, bool isexception = false);
00337
00342 void undo_force_select(bool readable, bool writable,
00343 bool isexception = false);
00344
00362 bool uses_continue_select;
00363 size_t personal_stack_size;
00364 bool continue_select(time_t msec_timeout);
00365
00371 void terminate_continue_select();
00372
00377 virtual const WvAddr *src() const;
00378
00383 void setcallback(WvStreamCallback _callfunc, void *_userdata)
00384 { callfunc = _callfunc; userdata = _userdata; }
00385
00391 void autoforward(WvStream &s)
00392 { setcallback(autoforward_callback, &s); read_requires_writable = &s; }
00393 static void autoforward_callback(WvStream &s, void *userdata);
00394
00399 void callback();
00400
00405 void alarm(time_t msec_timeout);
00406
00412 time_t alarm_remaining();
00413
00418 size_t write(const WvString &s)
00419 { return write(s, strlen(s)); }
00420 size_t print(const WvString &s)
00421 { return write(s); }
00422
00426 size_t print(WVSTRING_FORMAT_DECL)
00427 { return write(WvString(WVSTRING_FORMAT_CALL)); }
00428 size_t operator() (const WvString &s)
00429 { return write(s); }
00430 size_t operator() (WVSTRING_FORMAT_DECL)
00431 { return write(WvString(WVSTRING_FORMAT_CALL)); }
00432
00433 private:
00434 void init();
00435 bool wvstream_execute_called;
00436
00440 bool _select(time_t msec_timeout,
00441 bool readable, bool writable, bool isexcept,
00442 bool forceable);
00443
00444 protected:
00445 WvStreamCallback callfunc;
00446 void *userdata;
00447 int rwfd, errnum;
00448 WvString errstring;
00449 WvBuffer inbuf, outbuf;
00450 size_t max_outbuf_size;
00451 bool outbuf_delayed_flush, alarm_was_ticking;
00452 size_t queue_min;
00453 time_t autoclose_time;
00454 struct timeval alarm_time;
00455 bool running_callback;
00456
00457 static WvTaskMan *taskman;
00458 WvTask *task;
00459
00463 WvStream() : callfunc(NULL)
00464 { init(); rwfd = -1; }
00465
00469 void seterr(int _errnum);
00470 void seterr(const WvString &specialerr);
00471
00477 static void _callback(void *stream);
00478
00489 virtual void execute();
00490 };
00491
00492
00498 extern WvStream *wvcon;
00499
00500 #endif // __WVSTREAM_H