The LIBS line was apparently accidentally deleted from configure-mingw32.
[wvstreams.git] / utils / wvencoder.cc
blobcd81cc34953448098eb8c2c6a3c7b02c885a0888
1 /*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4 *
5 * A top-level data encoder class. See wvencoder.h.
6 */
7 #include "wvencoder.h"
9 /***** WvEncoder *****/
11 WvEncoder::WvEncoder()
13 okay = true;
14 finished = false;
18 WvEncoder::~WvEncoder()
23 WvString WvEncoder::geterror() const
25 if (isok())
26 return WvString::null;
27 if (!!errstr)
28 return errstr;
29 WvString message = _geterror();
30 if (!!message)
31 return message;
32 return "unknown encoder error";
36 bool WvEncoder::encode(WvBuf &inbuf, WvBuf &outbuf,
37 bool flush, bool _finish)
39 // deliberately not using isok() and isfinished() here
40 bool success = okay && !finished && (inbuf.used() != 0 || flush);
41 if (success)
42 success = _encode(inbuf, outbuf, flush);
43 if (_finish)
44 success = finish(outbuf) && success;
45 return success;
49 bool WvEncoder::finish(WvBuf &outbuf)
51 // deliberately not using isok() and isfinished() here
52 bool success = okay && !finished;
53 if (success)
54 success = _finish(outbuf);
55 setfinished();
56 return success;
60 bool WvEncoder::reset()
62 // reset local state
63 okay = true;
64 finished = false;
65 errstr = WvString::null;
66 // attempt to reset the encoder
67 bool success = _reset();
68 if (!success)
70 if (okay)
71 seterror("reset not supported by encoder");
73 return success;
77 bool WvEncoder::flushstrbuf(WvStringParm instr, WvBuf &outbuf,
78 bool finish)
80 WvConstStringBuffer inbuf(instr);
81 bool success = encode(inbuf, outbuf, true, finish);
82 return success;
86 bool WvEncoder::flushstrstr(WvStringParm instr, WvString &outstr,
87 bool finish)
89 WvConstStringBuffer inbuf(instr);
90 WvDynBuf outbuf;
91 bool success = encode(inbuf, outbuf, true, finish);
92 outstr.append(outbuf.getstr());
93 return success;
97 bool WvEncoder::encodebufstr(WvBuf &inbuf, WvString &outstr,
98 bool flush, bool finish)
100 WvDynBuf outbuf;
101 bool success = encode(inbuf, outbuf, flush, finish);
102 outstr.append(outbuf.getstr());
103 return success;
107 WvString WvEncoder::strflushstr(WvStringParm instr, bool finish)
109 WvString outstr;
110 flushstrstr(instr, outstr, finish);
111 return outstr;
115 WvString WvEncoder::strflushbuf(WvBuf &inbuf, bool finish)
117 WvString outstr;
118 flushbufstr(inbuf, outstr, finish);
119 return outstr;
123 bool WvEncoder::flushmembuf(const void *inmem, size_t inlen,
124 WvBuf &outbuf, bool finish)
126 WvConstInPlaceBuf inbuf(inmem, inlen);
127 bool success = encode(inbuf, outbuf, true, finish);
128 return success;
132 bool WvEncoder::flushmemmem(const void *inmem, size_t inlen,
133 void *outmem, size_t *outlen, bool finish)
135 WvConstInPlaceBuf inbuf(inmem, inlen);
136 return encodebufmem(inbuf, outmem, outlen, true, finish);
140 bool WvEncoder::encodebufmem(WvBuf &inbuf,
141 void *outmem, size_t *outlen, bool flush, bool finish)
143 WvInPlaceBuf outbuf(outmem, 0, *outlen);
144 bool success = encode(inbuf, outbuf, true, finish);
145 *outlen = outbuf.used();
146 return success;
150 bool WvEncoder::flushstrmem(WvStringParm instr,
151 void *outmem, size_t *outlen, bool finish)
153 WvConstStringBuffer inbuf(instr);
154 return flushbufmem(inbuf, outmem, outlen, finish);
158 WvString WvEncoder::strflushmem(const void *inmem, size_t inlen, bool finish)
160 WvConstInPlaceBuf inbuf(inmem, inlen);
161 return strflushbuf(inbuf, finish);
165 /***** WvNullEncoder *****/
167 bool WvNullEncoder::_encode(WvBuf &in, WvBuf &out, bool flush)
169 in.zap();
170 return true;
174 bool WvNullEncoder::_reset()
176 return true;
181 /***** WvPassthroughEncoder *****/
183 WvPassthroughEncoder::WvPassthroughEncoder()
185 _reset();
189 bool WvPassthroughEncoder::_encode(WvBuf &in, WvBuf &out, bool flush)
191 total += in.used();
192 out.merge(in);
193 return true;
197 bool WvPassthroughEncoder::_reset()
199 total = 0;
200 return true;
205 /***** WvEncoderChain *****/
207 WvEncoderChain::WvEncoderChain()
209 last_run = NULL;
213 WvEncoderChain::~WvEncoderChain()
218 bool WvEncoderChain::_isok() const
220 ChainElemList::Iter it(const_cast<ChainElemList&>(encoders));
221 for (it.rewind(); it.next(); )
222 if (!it->enc->isok())
223 return false;
224 return true;
228 bool WvEncoderChain::_isfinished() const
230 ChainElemList::Iter it(const_cast<ChainElemList&>(encoders));
231 for (it.rewind(); it.next(); )
232 if (it->enc->isfinished())
233 return true;
234 return false;
238 WvString WvEncoderChain::_geterror() const
240 ChainElemList::Iter it(const_cast<ChainElemList&>(encoders));
241 for (it.rewind(); it.next(); )
243 WvString message = it->enc->geterror();
244 if (!!message) return message;
246 return WvString::null;
250 // NOTE: In this function we deliberately ignore deep isok() and
251 // isfinished() results to allow addition/removal of
252 // individual broken encoders while still processing data
253 // through as much of the chain as possible.
254 bool WvEncoderChain::do_encode(WvBuf &in, WvBuf &out, ChainElem *start_after,
255 bool flush, bool finish)
257 bool success = true;
258 WvBuf *tmpin = &in;
259 ChainElemList::Iter it(encoders);
260 it.rewind();
261 if (start_after) it.find(start_after);
262 last_run = start_after;
263 for (; it.cur() && it.next(); )
265 if (!it->enc->encode(*tmpin, it->out, flush))
266 success = false;
267 if (finish && !it->enc->finish(it->out))
268 success = false;
269 last_run = it.ptr();
270 tmpin = &it->out;
272 out.merge(*tmpin);
273 return success;
277 bool WvEncoderChain::_encode(WvBuf &in, WvBuf &out, bool flush)
279 return do_encode(in, out, NULL, flush, false);
283 bool WvEncoderChain::_finish(WvBuf &out)
285 WvNullBuf empty;
286 return do_encode(empty, out, NULL, true, true);
290 bool WvEncoderChain::continue_encode(WvBuf &in, WvBuf &out)
292 //fprintf(stderr, "continue_encode(%d,%d,%p)\n",
293 // in.used(), out.used(), last_run);
294 return do_encode(in, out, last_run, false, false);
298 bool WvEncoderChain::_reset()
300 bool success = true;
301 ChainElemList::Iter it(encoders);
302 for (it.rewind(); it.next(); )
304 it->out.zap();
305 if (!it->enc->reset())
306 success = false;
308 return success;
312 void WvEncoderChain::append(WvEncoder *enc, bool autofree)
314 encoders.append(new ChainElem(enc, autofree), true);
318 void WvEncoderChain::prepend(WvEncoder *enc, bool autofree)
320 encoders.prepend(new ChainElem(enc, autofree), true);
324 bool WvEncoderChain::get_autofree(WvEncoder *enc) const
326 ChainElemList::Iter i(encoders);
327 for (i.rewind(); i.next(); )
328 if (i->enc == enc && i.get_autofree())
329 return true;
330 return false;
334 void WvEncoderChain::set_autofree(WvEncoder *enc, bool autofree)
336 ChainElemList::Iter i(encoders);
337 if (autofree)
339 // Ensure only the first matching encoder has autofree set
340 bool first = true;
341 for (i.rewind(); i.next(); )
343 if (i->enc == enc)
345 if (first)
347 i.set_autofree(true);
348 first = false;
350 else
351 i.set_autofree(false);
355 else
357 // Clear autofree for all matching encoders
358 for (i.rewind(); i.next(); )
359 if (i->enc == enc)
360 i.set_autofree(false);
365 void WvEncoderChain::unlink(WvEncoder *enc)
367 ChainElemList::Iter it(encoders);
368 for (it.rewind(); it.next(); )
369 if (it->enc == enc)
370 it.xunlink();
374 void WvEncoderChain::zap()
376 encoders.zap();
380 size_t WvEncoderChain::buffered()
382 size_t used = 0;
383 ChainElemList::Iter it(encoders);
384 for (it.rewind(); it.next(); )
385 used += it().out.used();
386 return used;