2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
5 * A top-level data encoder class. See wvencoder.h.
9 /***** WvEncoder *****/
11 WvEncoder::WvEncoder()
18 WvEncoder::~WvEncoder()
23 WvString
WvEncoder::geterror() const
26 return WvString::null
;
29 WvString message
= _geterror();
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
);
42 success
= _encode(inbuf
, outbuf
, flush
);
44 success
= finish(outbuf
) && success
;
49 bool WvEncoder::finish(WvBuf
&outbuf
)
51 // deliberately not using isok() and isfinished() here
52 bool success
= okay
&& !finished
;
54 success
= _finish(outbuf
);
60 bool WvEncoder::reset()
65 errstr
= WvString::null
;
66 // attempt to reset the encoder
67 bool success
= _reset();
71 seterror("reset not supported by encoder");
77 bool WvEncoder::flushstrbuf(WvStringParm instr
, WvBuf
&outbuf
,
80 WvConstStringBuffer
inbuf(instr
);
81 bool success
= encode(inbuf
, outbuf
, true, finish
);
86 bool WvEncoder::flushstrstr(WvStringParm instr
, WvString
&outstr
,
89 WvConstStringBuffer
inbuf(instr
);
91 bool success
= encode(inbuf
, outbuf
, true, finish
);
92 outstr
.append(outbuf
.getstr());
97 bool WvEncoder::encodebufstr(WvBuf
&inbuf
, WvString
&outstr
,
98 bool flush
, bool finish
)
101 bool success
= encode(inbuf
, outbuf
, flush
, finish
);
102 outstr
.append(outbuf
.getstr());
107 WvString
WvEncoder::strflushstr(WvStringParm instr
, bool finish
)
110 flushstrstr(instr
, outstr
, finish
);
115 WvString
WvEncoder::strflushbuf(WvBuf
&inbuf
, bool finish
)
118 flushbufstr(inbuf
, outstr
, finish
);
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
);
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();
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
)
174 bool WvNullEncoder::_reset()
181 /***** WvPassthroughEncoder *****/
183 WvPassthroughEncoder::WvPassthroughEncoder()
189 bool WvPassthroughEncoder::_encode(WvBuf
&in
, WvBuf
&out
, bool flush
)
197 bool WvPassthroughEncoder::_reset()
205 /***** WvEncoderChain *****/
207 WvEncoderChain::WvEncoderChain()
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())
228 bool WvEncoderChain::_isfinished() const
230 ChainElemList::Iter
it(const_cast<ChainElemList
&>(encoders
));
231 for (it
.rewind(); it
.next(); )
232 if (it
->enc
->isfinished())
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
)
259 ChainElemList::Iter
it(encoders
);
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
))
267 if (finish
&& !it
->enc
->finish(it
->out
))
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
)
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()
301 ChainElemList::Iter
it(encoders
);
302 for (it
.rewind(); it
.next(); )
305 if (!it
->enc
->reset())
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())
334 void WvEncoderChain::set_autofree(WvEncoder
*enc
, bool autofree
)
336 ChainElemList::Iter
i(encoders
);
339 // Ensure only the first matching encoder has autofree set
341 for (i
.rewind(); i
.next(); )
347 i
.set_autofree(true);
351 i
.set_autofree(false);
357 // Clear autofree for all matching encoders
358 for (i
.rewind(); i
.next(); )
360 i
.set_autofree(false);
365 void WvEncoderChain::unlink(WvEncoder
*enc
)
367 ChainElemList::Iter
it(encoders
);
368 for (it
.rewind(); it
.next(); )
374 void WvEncoderChain::zap()
380 size_t WvEncoderChain::buffered()
383 ChainElemList::Iter
it(encoders
);
384 for (it
.rewind(); it
.next(); )
385 used
+= it().out
.used();