00001
00002
00003
00004
00005
00006
00007
00008
00009
#include "wvencoderstream.h"
00010
00011 WvEncoderStream::WvEncoderStream(
WvStream *_cloned) :
WvStreamClone(_cloned)
00012 {
00013 is_closing =
false;
00014 is_eof =
false;
00015
min_readsize = 0;
00016 }
00017
00018
00019 WvEncoderStream::~WvEncoderStream()
00020 {
00021
close();
00022 }
00023
00024
00025 void WvEncoderStream::close()
00026 {
00027
00028
00029
00030
00031
if (is_closing)
return;
00032 is_closing =
true;
00033
00034
00035
finish_read();
00036
finish_write();
00037
00038
WvStreamClone::close();
00039 }
00040
00041
00042 bool WvEncoderStream::isok()
const
00043
{
00044
00045
if (!
WvStream::isok())
00046
return false;
00047
00048
00049
00050
00051
if (! cloned || cloned->
geterr() != 0)
00052
return false;
00053
00054
00055
return ! is_eof;
00056 }
00057
00058
00059 bool WvEncoderStream::flush_internal(time_t msec_timeout)
00060 {
00061
flush_write();
00062
00063
00064
while (
isok() && writeoutbuf.
used())
00065 {
00066 WvEncoderStream::flush(msec_timeout);
00067
if (!msec_timeout || !select(msec_timeout,
false,
true))
00068 {
00069
if (msec_timeout >= 0)
00070
break;
00071 }
00072 }
00073
00074
return !writeoutbuf.
used();
00075 }
00076
00077
00078 bool WvEncoderStream::flush_read()
00079 {
00080
bool success =
readchain.
flush(readinbuf, readoutbuf);
00081 checkreadisok();
00082 inbuf.
merge(readoutbuf);
00083
return success;
00084 }
00085
00086
00087 bool WvEncoderStream::flush_write()
00088 {
00089
bool success = push(
true ,
false );
00090
return success;
00091 }
00092
00093
00094 bool WvEncoderStream::finish_read()
00095 {
00096
bool success =
readchain.
flush(readinbuf, readoutbuf);
00097
if (!
readchain.
finish(readoutbuf))
00098 success =
false;
00099 checkreadisok();
00100 inbuf.
merge(readoutbuf);
00101 is_eof =
true;
00102
return success;
00103 }
00104
00105
00106 bool WvEncoderStream::finish_write()
00107 {
00108
return push(
true ,
true );
00109 }
00110
00111
00112
void WvEncoderStream::pull(size_t size)
00113 {
00114
if (is_eof)
00115
return;
00116
00117
00118
bool finish =
false;
00119
if (! readchain.
isfinished() && cloned)
00120 {
00121
if (size != 0)
00122 cloned->
read(readinbuf, size);
00123
if (! cloned->
isok())
00124 finish =
true;
00125 }
00126
00127
00128
readchain.
encode(readinbuf, readoutbuf, finish );
00129
if (finish)
00130 {
00131
readchain.
finish(readoutbuf);
00132
if (readoutbuf.
used() == 0 &&
inbuf.
used() == 0)
00133 is_eof =
true;
00134
00135 }
00136
else if (readoutbuf.
used() == 0 &&
inbuf.
used() == 0 &&
readchain.
isfinished())
00137 {
00138
00139
00140 is_eof =
true;
00141 }
00142 checkreadisok();
00143 }
00144
00145
00146
bool WvEncoderStream::push(
bool flush,
bool finish)
00147 {
00148
00149
if (flush)
00150 writeinbuf.
merge(outbuf);
00151
bool success =
writechain.
encode(writeinbuf, writeoutbuf, flush);
00152
if (finish)
00153
if (!
writechain.
finish(writeoutbuf))
00154 success =
false;
00155 checkwriteisok();
00156
00157
00158 size_t size = writeoutbuf.
used();
00159
if (size != 0)
00160 {
00161
const unsigned char *writeout = writeoutbuf.
get(size);
00162 size_t len =
WvStreamClone::uwrite(writeout, size);
00163 writeoutbuf.
unget(size - len);
00164 }
00165
return success;
00166 }
00167
00168
00169 size_t
WvEncoderStream::uread(
void *buf, size_t size)
00170 {
00171
if (size && readoutbuf.
used() == 0)
00172 {
00173 pull(
min_readsize > size ?
min_readsize : size);
00174 }
00175 size_t avail = readoutbuf.
used();
00176
if (size > avail)
00177 size = avail;
00178 readoutbuf.
move(buf, size);
00179
return size;
00180 }
00181
00182
00183 size_t
WvEncoderStream::uwrite(
const void *buf, size_t size)
00184 {
00185 writeinbuf.
put(buf, size);
00186 push(
false ,
false );
00187
return size;
00188 }
00189
00190
00191 bool WvEncoderStream::pre_select(SelectInfo &si)
00192 {
00193
bool surething =
false;
00194
00195
00196
00197
00198
if (si.wants.readable)
00199 {
00200 pull(0);
00201
if (readoutbuf.
used() != 0)
00202 surething =
true;
00203 }
00204
00205
00206
00207 push(
false ,
false );
00208
00209
00210
if (WvStreamClone::pre_select(si))
00211 surething =
true;
00212
return surething;
00213 }
00214
00215
00216
void WvEncoderStream::checkreadisok()
00217 {
00218
if (! readchain.
isok())
00219 {
00220 seterr(
WvString(
"read chain: %s", readchain.
geterror()));
00221 is_eof =
true;
00222 }
00223 }
00224
00225
00226
void WvEncoderStream::checkwriteisok()
00227 {
00228
if (!
writechain.
isok())
00229
seterr(
WvString(
"write chain: %s",
writechain.
geterror()));
00230 }