WvStreams
wvencoder.cc
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"
8
9/***** WvEncoder *****/
10
12{
13 okay = true;
14 finished = false;
15}
16
17
21
22
24{
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";
33}
34
35
36bool WvEncoder::encode(WvBuf &inbuf, WvBuf &outbuf,
37 bool flush, bool _finish)
38{
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;
46}
47
48
49bool WvEncoder::finish(WvBuf &outbuf)
50{
51 // deliberately not using isok() and isfinished() here
52 bool success = okay && !finished;
53 if (success)
54 success = _finish(outbuf);
56 return success;
57}
58
59
61{
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)
69 {
70 if (okay)
71 seterror("reset not supported by encoder");
72 }
73 return success;
74}
75
76
77bool WvEncoder::flushstrbuf(WvStringParm instr, WvBuf &outbuf,
78 bool finish)
79{
80 WvConstStringBuffer inbuf(instr);
81 bool success = encode(inbuf, outbuf, true, finish);
82 return success;
83}
84
85
87 bool finish)
88{
89 WvConstStringBuffer inbuf(instr);
90 WvDynBuf outbuf;
91 bool success = encode(inbuf, outbuf, true, finish);
92 outstr.append(outbuf.getstr());
93 return success;
94}
95
96
97bool WvEncoder::encodebufstr(WvBuf &inbuf, WvString &outstr,
98 bool flush, bool finish)
99{
100 WvDynBuf outbuf;
101 bool success = encode(inbuf, outbuf, flush, finish);
102 outstr.append(outbuf.getstr());
103 return success;
104}
105
106
108{
109 WvString outstr;
110 flushstrstr(instr, outstr, finish);
111 return outstr;
112}
113
114
115WvString WvEncoder::strflushbuf(WvBuf &inbuf, bool finish)
116{
117 WvString outstr;
118 flushbufstr(inbuf, outstr, finish);
119 return outstr;
120}
121
122
123bool WvEncoder::flushmembuf(const void *inmem, size_t inlen,
124 WvBuf &outbuf, bool finish)
125{
126 WvConstInPlaceBuf inbuf(inmem, inlen);
127 bool success = encode(inbuf, outbuf, true, finish);
128 return success;
129}
130
131
132bool WvEncoder::flushmemmem(const void *inmem, size_t inlen,
133 void *outmem, size_t *outlen, bool finish)
134{
135 WvConstInPlaceBuf inbuf(inmem, inlen);
136 return encodebufmem(inbuf, outmem, outlen, true, finish);
137}
138
139
140bool WvEncoder::encodebufmem(WvBuf &inbuf,
141 void *outmem, size_t *outlen, bool flush, bool finish)
142{
143 WvInPlaceBuf outbuf(outmem, 0, *outlen);
144 bool success = encode(inbuf, outbuf, true, finish);
145 *outlen = outbuf.used();
146 return success;
147}
148
149
151 void *outmem, size_t *outlen, bool finish)
152{
153 WvConstStringBuffer inbuf(instr);
154 return flushbufmem(inbuf, outmem, outlen, finish);
155}
156
157
158WvString WvEncoder::strflushmem(const void *inmem, size_t inlen, bool finish)
159{
160 WvConstInPlaceBuf inbuf(inmem, inlen);
161 return strflushbuf(inbuf, finish);
162}
163
164
165/***** WvNullEncoder *****/
166
167bool WvNullEncoder::_encode(WvBuf &in, WvBuf &out, bool flush)
168{
169 in.zap();
170 return true;
171}
172
173
175{
176 return true;
177}
178
179
180
181/***** WvPassthroughEncoder *****/
182
183WvPassthroughEncoder::WvPassthroughEncoder()
184{
185 _reset();
186}
187
188
189bool WvPassthroughEncoder::_encode(WvBuf &in, WvBuf &out, bool flush)
190{
191 total += in.used();
192 out.merge(in);
193 return true;
194}
195
196
198{
199 total = 0;
200 return true;
201}
202
203
204
205/***** WvEncoderChain *****/
206
208{
209 last_run = NULL;
210}
211
212
216
217
219{
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;
225}
226
227
229{
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;
235}
236
237
239{
240 ChainElemList::Iter it(const_cast<ChainElemList&>(encoders));
241 for (it.rewind(); it.next(); )
242 {
243 WvString message = it->enc->geterror();
244 if (!!message) return message;
245 }
246 return WvString::null;
247}
248
249
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.
254bool WvEncoderChain::do_encode(WvBuf &in, WvBuf &out, ChainElem *start_after,
255 bool flush, bool finish)
256{
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(); )
264 {
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;
271 }
272 out.merge(*tmpin);
273 return success;
274}
275
276
277bool WvEncoderChain::_encode(WvBuf &in, WvBuf &out, bool flush)
278{
279 return do_encode(in, out, NULL, flush, false);
280}
281
282
284{
285 WvNullBuf empty;
286 return do_encode(empty, out, NULL, true, true);
287}
288
289
290bool WvEncoderChain::continue_encode(WvBuf &in, WvBuf &out)
291{
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);
295}
296
297
299{
300 bool success = true;
301 ChainElemList::Iter it(encoders);
302 for (it.rewind(); it.next(); )
303 {
304 it->out.zap();
305 if (!it->enc->reset())
306 success = false;
307 }
308 return success;
309}
310
311
312void WvEncoderChain::append(WvEncoder *enc, bool autofree)
313{
314 encoders.append(new ChainElem(enc, autofree), true);
315}
316
317
318void WvEncoderChain::prepend(WvEncoder *enc, bool autofree)
319{
320 encoders.prepend(new ChainElem(enc, autofree), true);
321}
322
323
325{
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;
331}
332
333
335{
336 ChainElemList::Iter i(encoders);
337 if (autofree)
338 {
339 // Ensure only the first matching encoder has autofree set
340 bool first = true;
341 for (i.rewind(); i.next(); )
342 {
343 if (i->enc == enc)
344 {
345 if (first)
346 {
347 i.set_autofree(true);
348 first = false;
349 }
350 else
351 i.set_autofree(false);
352 }
353 }
354 }
355 else
356 {
357 // Clear autofree for all matching encoders
358 for (i.rewind(); i.next(); )
359 if (i->enc == enc)
360 i.set_autofree(false);
361 }
362}
363
364
366{
367 ChainElemList::Iter it(encoders);
368 for (it.rewind(); it.next(); )
369 if (it->enc == enc)
370 it.xunlink();
371}
372
373
375{
376 encoders.zap();
377}
378
379
381{
382 size_t used = 0;
383 ChainElemList::Iter it(encoders);
384 for (it.rewind(); it.next(); )
385 used += it().out.used();
386 return used;
387}
388
size_t used() const
Returns the number of elements in the buffer currently available for reading.
The const in place raw memory buffer type.
A raw memory read-only buffer backed by a constant WvString.
virtual WvString _geterror() const
Returns the error message, if any.
Definition wvencoder.cc:238
size_t buffered()
Returns true if there is data in an internal buffer.
Definition wvencoder.cc:380
bool get_autofree(WvEncoder *enc) const
Gets the autofree state of a particular encoder in the chain.
Definition wvencoder.cc:324
bool continue_encode(WvBuf &inbuf, WvBuf &outbuf)
"Continues" encoding a buffer.
Definition wvencoder.cc:290
void unlink(WvEncoder *enc)
Unlinks the encoder from the chain.
Definition wvencoder.cc:365
WvEncoderChain()
Creates an initially empty chain of encoders.
Definition wvencoder.cc:207
void zap()
Clears the encoder chain.
Definition wvencoder.cc:374
void set_autofree(WvEncoder *enc, bool autofree)
Sets the autofree state of a particular encoder in the chain.
Definition wvencoder.cc:334
virtual ~WvEncoderChain()
Destroys the encoder chain.
Definition wvencoder.cc:213
virtual bool _reset()
Resets the chain of encoders.
Definition wvencoder.cc:298
virtual bool _encode(WvBuf &in, WvBuf &out, bool flush)
Passes the data through the entire chain of encoders.
Definition wvencoder.cc:277
void prepend(WvEncoder *enc, bool autofree)
Prepends an encoder to the head of the chain.
Definition wvencoder.cc:318
void append(WvEncoder *enc, bool autofree)
Appends an encoder to the tail of the chain.
Definition wvencoder.cc:312
virtual bool _isfinished() const
Returns true if the encoder can no longer encode data.
Definition wvencoder.cc:228
virtual bool _isok() const
Returns true if the encoder has not encountered an error.
Definition wvencoder.cc:218
virtual bool _finish(WvBuf &out)
Finishes the chain of encoders.
Definition wvencoder.cc:283
bool finish(WvBuf &outbuf)
Tells the encoder that NO MORE DATA will ever be encoded.
Definition wvencoder.cc:49
bool isok() const
Returns true if the encoder has not encountered an error.
bool reset()
Asks an encoder to reset itself to its initial state at creation time, if supported.
Definition wvencoder.cc:60
WvString strflushstr(WvStringParm instr, bool finish=false)
Flushes data through the encoder from a string to a string.
Definition wvencoder.cc:107
bool encode(WvBuf &inbuf, WvBuf &outbuf, bool flush=false, bool finish=false)
Reads data from the input buffer, encodes it, and writes the result to the output buffer.
Definition wvencoder.cc:36
void seterror(WvStringParm message)
Sets an error condition, then setnotok().
virtual ~WvEncoder()
Destroys the encoder.
Definition wvencoder.cc:18
virtual bool _finish(WvBuf &outbuf)
Template method implementation of finish().
bool flushbufmem(WvBuf &inbuf, void *outmem, size_t *outlen, bool finish=false)
Flushes data through the encoder from a buffer to memory.
bool encodebufmem(WvBuf &inbuf, void *outmem, size_t *outlen, bool flush=false, bool finish=false)
Encodes data from a buffer to memory.
Definition wvencoder.cc:140
bool flushmembuf(const void *inmem, size_t inlen, WvBuf &outbuf, bool finish=false)
Flushes data through the encoder from memory to a buffer.
Definition wvencoder.cc:123
bool flushmemmem(const void *inmem, size_t inlen, void *outmem, size_t *outlen, bool finish=false)
Flushes data through the encoder from memory to memory.
Definition wvencoder.cc:132
bool flushstrbuf(WvStringParm instr, WvBuf &outbuf, bool finish=false)
Flushes data through the encoder from a string to a buffer.
Definition wvencoder.cc:77
WvEncoder()
Creates a new WvEncoder.
Definition wvencoder.cc:11
bool encodebufstr(WvBuf &inbuf, WvString &outstr, bool flush=false, bool finish=false)
Encodes data from a buffer to a string.
Definition wvencoder.cc:97
bool flush(WvBuf &inbuf, WvBuf &outbuf, bool finish=false)
Flushes the encoder and optionally finishes it.
bool flushstrmem(WvStringParm instr, void *outmem, size_t *outlen, bool finish=false)
Flushes data through the encoder from a string to memory.
Definition wvencoder.cc:150
bool flushstrstr(WvStringParm instr, WvString &outstr, bool finish=false)
Flushes data through the encoder from a string to a string.
Definition wvencoder.cc:86
virtual WvString _geterror() const
Template method implementation of geterror().
WvString strflushmem(const void *inmem, size_t inlen, bool finish=false)
Flushes data through the encoder from memory to a string.
Definition wvencoder.cc:158
bool flushbufstr(WvBuf &inbuf, WvString &outstr, bool finish=false)
Flushes data through the encoder from a buffer to a string.
void setfinished()
Sets 'finished' to true explicitly.
virtual bool _reset()
Template method implementation of reset().
WvString geterror() const
Returns an error message if any is available.
Definition wvencoder.cc:23
WvString strflushbuf(WvBuf &inbuf, bool finish=false)
Flushes data through the encoder from a buffer to a string.
Definition wvencoder.cc:115
virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush)=0
Template method implementation of encode().
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
The in place raw memory buffer type.
virtual bool _encode(WvBuf &in, WvBuf &out, bool flush)
Template method implementation of encode().
Definition wvencoder.cc:167
virtual bool _reset()
Template method implementation of reset().
Definition wvencoder.cc:174
virtual bool _encode(WvBuf &in, WvBuf &out, bool flush)
Template method implementation of encode().
Definition wvencoder.cc:189
virtual bool _reset()
Template method implementation of reset().
Definition wvencoder.cc:197
WvString is an implementation of a simple and efficient printable-string class.