00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * WvStreamClone simply forwards all requests to the "cloned" stream. 00006 * 00007 * NOTE: this file is a pain to maintain, because many of these functions 00008 * are almost (but not quite) exactly like the ones in WvStream. If 00009 * WvStream changes, you need to change this too. 00010 * 00011 * See wvstreamclone.h. 00012 */ 00013 #include "wvstreamclone.h" 00014 #include <errno.h> 00015 #include <time.h> 00016 00017 00018 WvStreamClone::~WvStreamClone() 00019 { 00020 // do NOT close the cloned stream! 00021 } 00022 00023 00024 void WvStreamClone::close() 00025 { 00026 if (s()) 00027 s()->close(); 00028 } 00029 00030 00031 int WvStreamClone::getrfd() const 00032 { 00033 if (s()) 00034 return s()->getrfd(); 00035 return -1; 00036 } 00037 00038 00039 int WvStreamClone::getwfd() const 00040 { 00041 if (s()) 00042 return s()->getwfd(); 00043 return -1; 00044 } 00045 00046 00047 size_t WvStreamClone::uread(void *buf, size_t size) 00048 { 00049 if (s()) 00050 return s()->read(buf, size); 00051 else 00052 return 0; 00053 } 00054 00055 00056 size_t WvStreamClone::uwrite(const void *buf, size_t size) 00057 { 00058 // we use s()->uwrite() here, not write(), since we want the _clone_ 00059 // to own the output buffer, not the main stream. 00060 if (s()) 00061 return s()->uwrite(buf, size); 00062 else 00063 return 0; 00064 } 00065 00066 00067 bool WvStreamClone::isok() const 00068 { 00069 if (errnum) 00070 return false; 00071 if (s()) 00072 return s()->isok(); 00073 return false; 00074 } 00075 00076 00077 int WvStreamClone::geterr() const 00078 { 00079 if (errnum) 00080 return errnum; 00081 if (s()) 00082 return s()->geterr(); 00083 return EIO; 00084 } 00085 00086 00087 const char *WvStreamClone::errstr() const 00088 { 00089 if (errnum) 00090 return WvStream::errstr(); 00091 if (s()) 00092 return s()->errstr(); 00093 return "No child stream!"; 00094 } 00095 00096 00097 bool WvStreamClone::pre_select(SelectInfo &si) 00098 { 00099 SelectRequest oldwant; 00100 bool result; 00101 time_t alarmleft = alarm_remaining(); 00102 00103 if (alarmleft == 0) 00104 return true; // alarm has rung 00105 00106 if (si.wants.readable && inbuf.used() && inbuf.used() >= queue_min) 00107 return true; // sure_thing if anything in WvStream buffer 00108 00109 if (alarmleft >= 0 00110 && (alarmleft < si.msec_timeout || si.msec_timeout < 0)) 00111 si.msec_timeout = alarmleft; 00112 00113 if (s() && s()->isok()) 00114 { 00115 oldwant = si.wants; 00116 00117 if (!si.inherit_request) 00118 { 00119 si.wants |= force; 00120 si.wants |= s()->force; 00121 } 00122 00123 if (outbuf.used() || autoclose_time) 00124 si.wants.writable = true; 00125 00126 result = s()->pre_select(si); 00127 00128 si.wants = oldwant; 00129 return result; 00130 } 00131 00132 return false; 00133 } 00134 00135 00136 bool WvStreamClone::post_select(SelectInfo &si) 00137 { 00138 SelectRequest oldwant; 00139 bool val, want_write; 00140 00141 if (s() && (outbuf.used() || autoclose_time)) 00142 flush(0); 00143 00144 if (s() && s()->isok()) 00145 { 00146 oldwant = si.wants; 00147 if (!si.inherit_request) 00148 { 00149 si.wants |= force; 00150 si.wants |= s()->force; 00151 } 00152 00153 val = s()->post_select(si); 00154 want_write = si.wants.writable; 00155 si.wants = oldwant; 00156 00157 // don't return true if they're looking for writable and we still 00158 // have data in outbuf - we're not ready to flush yet. 00159 if (want_write && outbuf.used()) 00160 return false; 00161 else 00162 { 00163 if (val && si.wants.readable && read_requires_writable 00164 && !read_requires_writable->select(0, false, true)) 00165 return false; 00166 if (val && si.wants.writable && write_requires_readable 00167 && !write_requires_readable->select(0, true, false)) 00168 return false; 00169 00170 return val; 00171 } 00172 } 00173 return false; 00174 } 00175 00176 00177 const WvAddr *WvStreamClone::src() const 00178 { 00179 if (s()) 00180 return s()->src(); 00181 return NULL; 00182 } 00183 00184 00185 void WvStreamClone::execute() 00186 { 00187 WvStream::execute(); 00188 if (s()) s()->callback(); 00189 }