Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

wvstream.h

00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  * 
00005  * Provides basic streaming I/O support.
00006  */ 
00007 #ifndef __WVSTREAM_H
00008 #define __WVSTREAM_H
00009 
00010 #include "iwvstream.h"
00011 #include "wvtimeutils.h"
00012 #include <errno.h>
00013 #include <limits.h>
00014 
00015 #ifdef _WIN32
00016 #include <time.h>
00017 #include <Winsock2.h>
00018 #include <ws2tcpip.h>
00019 #else
00020 #include <unistd.h> // not strictly necessary, but EVERYBODY uses this...
00021 #include <sys/time.h>
00022 #endif
00023 
00024 
00032 class WvStream: public IWvStream
00033 {
00034     IMPLEMENT_IOBJECT(WvStream);
00035 public:
00040     SelectRequest force;
00041     
00046     WvStream *read_requires_writable;
00047 
00052     WvStream *write_requires_readable;
00053     
00055     bool uses_continue_select;
00056 
00058     size_t personal_stack_size;
00059 
00064     bool alarm_was_ticking;
00065     
00067     bool stop_read, stop_write, closed;
00068     
00070     WvStream();
00071     virtual ~WvStream();
00072 
00080     virtual void close();
00081 
00083     virtual void seterr(int _errnum);
00084     void seterr(WvStringParm specialerr)
00085         { WvErrorBase::seterr(specialerr); }
00086     void seterr(WVSTRING_FORMAT_DECL)
00087         { seterr(WvString(WVSTRING_FORMAT_CALL)); }
00088     
00090     virtual bool isok() const;
00091     
00093     virtual size_t read(void *buf, size_t count);
00094 
00107     virtual size_t continue_read(time_t wait_msec, void *buf, size_t count);
00108 
00110     virtual size_t continue_read(time_t wait_msec, WvBuf &outbuf,
00111                                  size_t count);
00112 
00122     virtual size_t read(WvBuf &outbuf, size_t count);
00123 
00129     virtual void unread(WvBuf &outbuf, size_t count);
00130 
00137     virtual size_t write(const void *buf, size_t count);
00138 
00146     virtual size_t write(WvBuf &inbuf, size_t count = INT_MAX);
00147 
00157     void outbuf_limit(size_t size)
00158         { max_outbuf_size = size; }
00159 
00160     virtual void noread();
00161     virtual void nowrite();
00162     virtual void maybe_autoclose();
00163     
00164     virtual bool isreadable();
00165     virtual bool iswritable();
00166     
00174     virtual size_t uread(void *buf, size_t count)
00175         { return 0; /* basic WvStream doesn't actually do anything! */ }
00176 
00184     virtual size_t uwrite(const void *buf, size_t count)
00185         { return count; /* basic WvStream doesn't actually do anything! */ }
00186     
00207     char *getline(time_t wait_msec, char separator = '\n',
00208                   int readahead = 1024);
00209     
00227     size_t read_until(void *buf, size_t count, time_t wait_msec,
00228                       char separator);
00229 
00237     void queuemin(size_t count)
00238         { queue_min = count; }
00239 
00244     void drain();
00245     
00251     void delay_output(bool is_delayed)
00252     {
00253         outbuf_delayed_flush = is_delayed;
00254         want_to_flush = !is_delayed;
00255     }
00256 
00263     void auto_flush(bool is_automatic)
00264         { is_auto_flush = is_automatic; }
00265 
00272     virtual bool flush(time_t msec_timeout);
00273 
00274     virtual bool should_flush();
00275 
00282     void flush_then_close(int msec_timeout);
00283     
00305     virtual bool pre_select(SelectInfo &si);
00306     
00311     bool pre_select(SelectInfo &si, const SelectRequest &r)
00312     {
00313         SelectRequest oldwant = si.wants;
00314         si.wants = r;
00315         bool val = pre_select(si);
00316         si.wants = oldwant;
00317         return val;
00318     }
00319     
00324     bool xpre_select(SelectInfo &si, const SelectRequest &r)
00325         { return pre_select(si, r); }
00326     
00339     virtual bool post_select(SelectInfo &si);
00340 
00345     bool xpost_select(SelectInfo &si, const SelectRequest &r)
00346         { return post_select(si, r); }
00347     
00352     bool post_select(SelectInfo &si, const SelectRequest &r)
00353     {
00354         SelectRequest oldwant = si.wants;
00355         si.wants = r;
00356         bool val = post_select(si);
00357         si.wants = oldwant;
00358         return val;
00359     }
00360     
00382     bool select(time_t msec_timeout)
00383         { return _select(msec_timeout, false, false, false, true); }
00384     
00397     void runonce(time_t msec_timeout = -1)
00398         { if (select(msec_timeout)) callback(); }
00399     
00421     bool select(time_t msec_timeout,
00422                 bool readable, bool writable, bool isex = false)
00423         { return _select(msec_timeout, readable, writable, isex, false); }
00424     
00433     void force_select(bool readable, bool writable, bool isexception = false);
00434     
00439     void undo_force_select(bool readable, bool writable,
00440                            bool isexception = false);
00441     
00459     bool continue_select(time_t msec_timeout);
00460     
00466     void terminate_continue_select();
00467 
00472     virtual const WvAddr *src() const;
00473     
00478     void setcallback(WvStreamCallback _callfunc, void *_userdata);
00479         
00481     void setclosecallback(WvStreamCallback _callfunc, void *_userdata);
00482 
00488     void autoforward(WvStream &s);
00489 
00491     void noautoforward();
00492     static void autoforward_callback(WvStream &s, void *userdata);
00493     
00497     void *_callwrap(void *);
00498     
00502     void _callback();
00503     
00508     virtual void callback();
00509     
00514     void alarm(time_t msec_timeout);
00515 
00521     time_t alarm_remaining();
00522 
00527     size_t write(WvStringParm s)
00528         { return write(s.cstr(), s.len()); }
00529     size_t print(WvStringParm s)
00530         { return write(s); }
00531     size_t operator() (WvStringParm s)
00532         { return write(s); }
00533 
00535     size_t print(WVSTRING_FORMAT_DECL)
00536         { return write(WvString(WVSTRING_FORMAT_CALL)); }
00537     size_t operator() (WVSTRING_FORMAT_DECL)
00538         { return write(WvString(WVSTRING_FORMAT_CALL)); }
00539 
00540 protected:
00541     // builds the SelectInfo data structure (runs pre_select)
00542     // returns true if there are callbacks to be dispatched
00543     //
00544     // all of the fields are filled in with new values
00545     // si.msec_timeout contains the time until the next alarm expires
00546     bool _build_selectinfo(SelectInfo &si, time_t msec_timeout,
00547         bool readable, bool writable, bool isexcept,
00548         bool forceable);
00549 
00550     // runs the actual select() function over the given
00551     // SelectInfo data structure, returns the number of descriptors
00552     // in the set, and sets the error code if a problem occurs
00553     int _do_select(SelectInfo &si);
00554 
00555     // processes the SelectInfo data structure (runs post_select)
00556     // returns true if there are callbacks to be dispatched
00557     bool _process_selectinfo(SelectInfo &si, bool forceable);
00558 
00559     // tries to empty the output buffer if the stream is writable
00560     // not quite the same as flush() since it merely empties the output
00561     // buffer asynchronously whereas flush() might have other semantics
00562     // also handles autoclose (eg. after flush)
00563     bool flush_outbuf(time_t msec_timeout);
00564 
00565     // called once flush() has emptied outbuf to ensure that any other
00566     // internal stream buffers actually do get flushed before it returns
00567     virtual bool flush_internal(time_t msec_timeout);
00568     
00569     // the real implementations for these are actually in WvFDStream, which
00570     // is where they belong.  By IWvStream needs them to exist for now, so
00571     // it's a hack.  In standard WvStream they return -1.
00572     virtual int getrfd() const;
00573     virtual int getwfd() const;
00574     
00575 private:
00577     bool _select(time_t msec_timeout,
00578                  bool readable, bool writable, bool isexcept,
00579                  bool forceable);
00580 
00581 
00582 protected:
00583     WvDynBuf inbuf, outbuf;
00584     WvStreamCallback callfunc, closecb_func;
00585     WvCallback<void*,void*> call_ctx;
00586     void *userdata;
00587     void *closecb_data;
00588     size_t max_outbuf_size;
00589     bool outbuf_delayed_flush;
00590     bool is_auto_flush;
00591 
00592     // Used to guard against excessive flushing when using delay_flush
00593     bool want_to_flush;
00594 
00595     // Used to ensure we don't flush recursively.
00596     bool is_flushing;
00597 
00598     size_t queue_min;           // minimum bytes to read()
00599     time_t autoclose_time;      // close eventually, even if output is queued
00600     WvTime alarm_time;          // select() returns true at this time
00601     WvTime last_alarm_check;    // last time we checked the alarm_remaining
00602     bool wvstream_execute_called;
00603     
00605     WvStream(const WvStream &s) { }
00606     WvStream& operator= (const WvStream &s) { return *this; }
00607 
00618     virtual void execute();
00619     
00620     // every call to select() selects on the globalstream.
00621     static WvStream *globalstream;
00622 };
00623 
00630 extern WvStream *wvcon; // tied stdin and stdout stream
00631 extern WvStream *wvin;  // stdin stream
00632 extern WvStream *wvout; // stdout stream
00633 extern WvStream *wverr; // stderr stream
00634 
00635 #endif // __WVSTREAM_H

Generated on Sun Jul 10 15:34:14 2005 for WvStreams by  doxygen 1.4.0