00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
#include "wvstreamclone.h"
00014
#include "wvmoniker.h"
00015
00016
#ifdef _MSC_VER
00017
#pragma warning(disable : 4073)
00018
#pragma init_seg(lib)
00019
#endif
00020
00021 static IWvStream *
creator(
WvStringParm s,
IObject *obj,
void *)
00022 {
00023
if (!obj)
00024 obj = wvcreate<IWvStream>(s);
00025
return new WvStreamClone(mutate<IWvStream>(obj));
00026 }
00027
00028
static WvMoniker<IWvStream> reg(
"clone", creator);
00029
00030
00031 WvStreamClone::WvStreamClone(
IWvStream *_cloned)
00032 : cloned(0), disassociate_on_close(false)
00033 {
00034
setclone(_cloned);
00035
00036 force_select(
false,
false,
false);
00037 }
00038
00039
00040 WvStreamClone::~WvStreamClone()
00041 {
00042
00043
close();
00044
if (
cloned)
00045
delete cloned;
00046 }
00047
00048 void WvStreamClone::nowrite()
00049 {
00050
if (
cloned)
00051
cloned->
nowrite();
00052 }
00053
00054 void WvStreamClone::close()
00055 {
00056
00057
if (
cloned)
00058
cloned->
setclosecallback(0, 0);
00059
WvStream::close();
00060
if (
disassociate_on_close)
00061
cloned = NULL;
00062
if (
cloned)
00063
cloned->
close();
00064 }
00065
00066
00067 bool WvStreamClone::flush_internal(time_t msec_timeout)
00068 {
00069
if (
cloned)
00070
return cloned->
flush(msec_timeout);
00071
else
00072
return true;
00073 }
00074
00075
00076 size_t
WvStreamClone::uread(
void *buf, size_t size)
00077 {
00078
00079
00080
if (
cloned)
00081
return cloned->
read(buf, size);
00082
else
00083
return 0;
00084 }
00085
00086
00087 size_t
WvStreamClone::uwrite(
const void *buf, size_t size)
00088 {
00089
00090
00091
if (
cloned)
00092
return cloned->
write(buf, size);
00093
else
00094
return 0;
00095 }
00096
00097
00098 bool WvStreamClone::isok()
const
00099
{
00100
if (errnum)
00101
return false;
00102
if (
cloned)
00103
return cloned->
isok();
00104
return false;
00105 }
00106
00107
00108 int WvStreamClone::geterr()
const
00109
{
00110
if (errnum)
00111
return errnum;
00112
if (
cloned)
00113
return cloned->
geterr();
00114
return EIO;
00115 }
00116
00117
00118 WvString WvStreamClone::errstr()
const
00119
{
00120
if (errnum)
00121
return WvStream::errstr();
00122
if (
cloned)
00123
return cloned->
errstr();
00124
return "No child stream!";
00125 }
00126
00127
00128 static void close_callback(
WvStream &s,
void *userdata)
00129 {
00130
WvStreamClone *_this = (
WvStreamClone *)userdata;
00131
if (_this->
cloned == &s)
00132 _this->
close();
00133 }
00134
00135
00136 void WvStreamClone::setclone(
IWvStream *newclone)
00137 {
00138
if (
cloned)
00139
cloned->
setclosecallback(0, 0);
00140
cloned = newclone;
00141
if (
cloned)
00142
cloned->
setclosecallback(
close_callback,
this);
00143 }
00144
00145
00146 bool WvStreamClone::pre_select(SelectInfo &si)
00147 {
00148 SelectRequest oldwant;
00149
bool result = WvStream::pre_select(si);
00150
if (
cloned &&
cloned->
isok())
00151 {
00152 oldwant = si.wants;
00153
00154
if (!si.inherit_request)
00155 {
00156 si.wants |= force;
00157
00158 }
00159
00160
if (outbuf.
used() || autoclose_time)
00161 si.wants.writable =
true;
00162
00163 result = result ||
cloned->
pre_select(si);
00164
00165 si.wants = oldwant;
00166 }
00167
return result;
00168 }
00169
00170
00171 bool WvStreamClone::post_select(SelectInfo &si)
00172 {
00173 SelectRequest oldwant;
00174
00175
00176
bool result = WvStream::post_select(si);
00177
bool val, want_write;
00178
00179
if (
cloned &&
cloned->
should_flush())
00180 flush(0);
00181
00182
if (
cloned &&
cloned->
isok())
00183 {
00184 oldwant = si.wants;
00185
if (!si.inherit_request)
00186 {
00187 si.wants |= force;
00188
00189 }
00190
00191 val =
cloned->
post_select(si);
00192 want_write = si.wants.writable;
00193 si.wants = oldwant;
00194
00195
00196
00197
if (want_write && outbuf.
used())
00198
return result;
00199
else if (val && si.wants.readable && read_requires_writable
00200 && !read_requires_writable->
select(0,
false,
true))
00201
return result;
00202
else if (val && si.wants.writable && write_requires_readable
00203 && !write_requires_readable->
select(0,
true,
false))
00204
return result;
00205
else
00206
return val || result;
00207 }
00208
00209
return result;
00210 }
00211
00212
00213 const WvAddr *
WvStreamClone::src()
const
00214
{
00215
if (
cloned)
00216
return cloned->
src();
00217
return NULL;
00218 }
00219
00220
00221 void WvStreamClone::execute()
00222 {
00223
WvStream::execute();
00224
if (
cloned)
cloned->
callback();
00225 }