00001
00002
00003
00004
00005
00006
00007 #include "wvencoder.h"
00008
00009
00010
00011 WvEncoder::WvEncoder()
00012 {
00013 okay = true;
00014 finished = false;
00015 }
00016
00017
00018 WvEncoder::~WvEncoder()
00019 {
00020 }
00021
00022
00023 WvString WvEncoder::geterror() const
00024 {
00025 if (isok())
00026 return WvString::null;
00027 if (!!errstr)
00028 return errstr;
00029 WvString message = _geterror();
00030 if (!!message)
00031 return message;
00032 return "unknown encoder error";
00033 }
00034
00035
00036 bool WvEncoder::encode(WvBuf &inbuf, WvBuf &outbuf,
00037 bool flush, bool _finish)
00038 {
00039
00040 bool success = okay && !finished && (inbuf.used() != 0 || flush);
00041 if (success)
00042 success = _encode(inbuf, outbuf, flush);
00043 if (_finish)
00044 success = finish(outbuf) && success;
00045 return success;
00046 }
00047
00048
00049 bool WvEncoder::finish(WvBuf &outbuf)
00050 {
00051
00052 bool success = okay && !finished;
00053 if (success)
00054 success = _finish(outbuf);
00055 setfinished();
00056 return success;
00057 }
00058
00059
00060 bool WvEncoder::reset()
00061 {
00062
00063 okay = true;
00064 finished = false;
00065 errstr = WvString::null;
00066
00067 bool success = _reset();
00068 if (!success)
00069 {
00070 if (okay)
00071 seterror("reset not supported by encoder");
00072 }
00073 return success;
00074 }
00075
00076
00077 bool WvEncoder::flushstrbuf(WvStringParm instr, WvBuf &outbuf,
00078 bool finish)
00079 {
00080 WvConstStringBuffer inbuf(instr);
00081 bool success = encode(inbuf, outbuf, true, finish);
00082 return success;
00083 }
00084
00085
00086 bool WvEncoder::flushstrstr(WvStringParm instr, WvString &outstr,
00087 bool finish)
00088 {
00089 WvConstStringBuffer inbuf(instr);
00090 WvDynBuf outbuf;
00091 bool success = encode(inbuf, outbuf, true, finish);
00092 outstr.append(outbuf.getstr());
00093 return success;
00094 }
00095
00096
00097 bool WvEncoder::encodebufstr(WvBuf &inbuf, WvString &outstr,
00098 bool flush, bool finish)
00099 {
00100 WvDynBuf outbuf;
00101 bool success = encode(inbuf, outbuf, flush, finish);
00102 outstr.append(outbuf.getstr());
00103 return success;
00104 }
00105
00106
00107 WvString WvEncoder::strflushstr(WvStringParm instr, bool finish)
00108 {
00109 WvString outstr;
00110 flushstrstr(instr, outstr, finish);
00111 return outstr;
00112 }
00113
00114
00115 WvString WvEncoder::strflushbuf(WvBuf &inbuf, bool finish)
00116 {
00117 WvString outstr;
00118 flushbufstr(inbuf, outstr, finish);
00119 return outstr;
00120 }
00121
00122
00123 bool WvEncoder::flushmembuf(const void *inmem, size_t inlen,
00124 WvBuf &outbuf, bool finish)
00125 {
00126 WvConstInPlaceBuf inbuf(inmem, inlen);
00127 bool success = encode(inbuf, outbuf, true, finish);
00128 return success;
00129 }
00130
00131
00132 bool WvEncoder::flushmemmem(const void *inmem, size_t inlen,
00133 void *outmem, size_t *outlen, bool finish)
00134 {
00135 WvConstInPlaceBuf inbuf(inmem, inlen);
00136 return encodebufmem(inbuf, outmem, outlen, true, finish);
00137 }
00138
00139
00140 bool WvEncoder::encodebufmem(WvBuf &inbuf,
00141 void *outmem, size_t *outlen, bool flush, bool finish)
00142 {
00143 WvInPlaceBuf outbuf(outmem, 0, *outlen);
00144 bool success = encode(inbuf, outbuf, true, finish);
00145 *outlen = outbuf.used();
00146 return success;
00147 }
00148
00149
00150 bool WvEncoder::flushstrmem(WvStringParm instr,
00151 void *outmem, size_t *outlen, bool finish)
00152 {
00153 WvConstStringBuffer inbuf(instr);
00154 return flushbufmem(inbuf, outmem, outlen, finish);
00155 }
00156
00157
00158 WvString WvEncoder::strflushmem(const void *inmem, size_t inlen, bool finish)
00159 {
00160 WvConstInPlaceBuf inbuf(inmem, inlen);
00161 return strflushbuf(inbuf, finish);
00162 }
00163
00164
00165
00166
00167 bool WvNullEncoder::_encode(WvBuf &in, WvBuf &out, bool flush)
00168 {
00169 in.zap();
00170 return true;
00171 }
00172
00173
00174 bool WvNullEncoder::_reset()
00175 {
00176 return true;
00177 }
00178
00179
00180
00181
00182
00183 WvPassthroughEncoder::WvPassthroughEncoder()
00184 {
00185 _reset();
00186 }
00187
00188
00189 bool WvPassthroughEncoder::_encode(WvBuf &in, WvBuf &out, bool flush)
00190 {
00191 total += in.used();
00192 out.merge(in);
00193 return true;
00194 }
00195
00196
00197 bool WvPassthroughEncoder::_reset()
00198 {
00199 total = 0;
00200 return true;
00201 }
00202
00203
00204
00205
00206
00207 WvEncoderChain::WvEncoderChain()
00208 {
00209 last_run = NULL;
00210 }
00211
00212
00213 WvEncoderChain::~WvEncoderChain()
00214 {
00215 }
00216
00217
00218 bool WvEncoderChain::_isok() const
00219 {
00220 ChainElemList::Iter it(const_cast<ChainElemList&>(encoders));
00221 for (it.rewind(); it.next(); )
00222 if (!it->enc->isok())
00223 return false;
00224 return true;
00225 }
00226
00227
00228 bool WvEncoderChain::_isfinished() const
00229 {
00230 ChainElemList::Iter it(const_cast<ChainElemList&>(encoders));
00231 for (it.rewind(); it.next(); )
00232 if (it->enc->isfinished())
00233 return true;
00234 return false;
00235 }
00236
00237
00238 WvString WvEncoderChain::_geterror() const
00239 {
00240 ChainElemList::Iter it(const_cast<ChainElemList&>(encoders));
00241 for (it.rewind(); it.next(); )
00242 {
00243 WvString message = it->enc->geterror();
00244 if (!!message) return message;
00245 }
00246 return WvString::null;
00247 }
00248
00249
00250
00251
00252
00253
00254 bool WvEncoderChain::do_encode(WvBuf &in, WvBuf &out, ChainElem *start_after,
00255 bool flush, bool finish)
00256 {
00257 bool success = true;
00258 WvBuf *tmpin = ∈
00259 ChainElemList::Iter it(encoders);
00260 it.rewind();
00261 if (start_after) it.find(start_after);
00262 last_run = start_after;
00263 for (; it.cur() && it.next(); )
00264 {
00265 if (!it->enc->encode(*tmpin, it->out, flush))
00266 success = false;
00267 if (finish && !it->enc->finish(it->out))
00268 success = false;
00269 last_run = it.ptr();
00270 tmpin = &it->out;
00271 }
00272 out.merge(*tmpin);
00273 return success;
00274 }
00275
00276
00277 bool WvEncoderChain::_encode(WvBuf &in, WvBuf &out, bool flush)
00278 {
00279 return do_encode(in, out, NULL, flush, false);
00280 }
00281
00282
00283 bool WvEncoderChain::_finish(WvBuf &out)
00284 {
00285 WvNullBuf empty;
00286 return do_encode(empty, out, NULL, true, true);
00287 }
00288
00289
00290 bool WvEncoderChain::continue_encode(WvBuf &in, WvBuf &out)
00291 {
00292
00293
00294 return do_encode(in, out, last_run, false, false);
00295 }
00296
00297
00298 bool WvEncoderChain::_reset()
00299 {
00300 bool success = true;
00301 ChainElemList::Iter it(encoders);
00302 for (it.rewind(); it.next(); )
00303 {
00304 it->out.zap();
00305 if (!it->enc->reset())
00306 success = false;
00307 }
00308 return success;
00309 }
00310
00311
00312 void WvEncoderChain::append(WvEncoder *enc, bool autofree)
00313 {
00314 encoders.append(new ChainElem(enc, autofree), true);
00315 }
00316
00317
00318 void WvEncoderChain::prepend(WvEncoder *enc, bool autofree)
00319 {
00320 encoders.prepend(new ChainElem(enc, autofree), true);
00321 }
00322
00323
00324 bool WvEncoderChain::get_autofree(WvEncoder *enc) const
00325 {
00326 ChainElemList::Iter i(encoders);
00327 for (i.rewind(); i.next(); )
00328 if (i->enc == enc && i.get_autofree())
00329 return true;
00330 return false;
00331 }
00332
00333
00334 void WvEncoderChain::set_autofree(WvEncoder *enc, bool autofree)
00335 {
00336 ChainElemList::Iter i(encoders);
00337 if (autofree)
00338 {
00339
00340 bool first = true;
00341 for (i.rewind(); i.next(); )
00342 {
00343 if (i->enc == enc)
00344 {
00345 if (first)
00346 {
00347 i.set_autofree(true);
00348 first = false;
00349 }
00350 else
00351 i.set_autofree(false);
00352 }
00353 }
00354 }
00355 else
00356 {
00357
00358 for (i.rewind(); i.next(); )
00359 if (i->enc == enc)
00360 i.set_autofree(false);
00361 }
00362 }
00363
00364
00365 void WvEncoderChain::unlink(WvEncoder *enc)
00366 {
00367 ChainElemList::Iter it(encoders);
00368 for (it.rewind(); it.next(); )
00369 if (it->enc == enc)
00370 it.xunlink();
00371 }
00372
00373
00374 void WvEncoderChain::zap()
00375 {
00376 encoders.zap();
00377 }
00378
00379
00380 size_t WvEncoderChain::buffered()
00381 {
00382 size_t used = 0;
00383 ChainElemList::Iter it(encoders);
00384 for (it.rewind(); it.next(); )
00385 used += it().out.used();
00386 return used;
00387 }
00388