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
19{
20}
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
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
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
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
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
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
214{
215}
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
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
void merge(Buffer &inbuf, size_t count)
Efficiently moves count bytes from the specified buffer into this one.
Definition: wvbufbase.h:558
void zap()
Clears the buffer.
Definition: wvbufbase.h:257
size_t used() const
Returns the number of elements in the buffer currently available for reading.
Definition: wvbufbase.h:92
Specialization of WvBufBase for unsigned char type buffers intended for use with raw memory buffers.
Definition: wvbuf.h:24
WvString getstr()
Returns the entire buffer as a null-terminated WvString.
The const in place raw memory buffer type.
Definition: wvbuf.h:188
A raw memory read-only buffer backed by a constant WvString.
Definition: wvbuf.h:242
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
The base encoder class.
Definition: wvencoder.h:68
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.
Definition: wvencoder.h:90
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().
Definition: wvencoder.h:375
virtual ~WvEncoder()
Destroys the encoder.
Definition: wvencoder.cc:18
virtual bool _finish(WvBuf &outbuf)
Template method implementation of finish().
Definition: wvencoder.h:483
bool flushbufmem(WvBuf &inbuf, void *outmem, size_t *outlen, bool finish=false)
Flushes data through the encoder from a buffer to memory.
Definition: wvencoder.h:337
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
bool finished
Definition: wvencoder.h:71
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.
Definition: wvencoder.h:163
bool okay
Definition: wvencoder.h:70
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().
Definition: wvencoder.h:433
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.
Definition: wvencoder.h:249
void setfinished()
Sets 'finished' to true explicitly.
Definition: wvencoder.h:383
virtual bool _reset()
Template method implementation of reset().
Definition: wvencoder.h:498
WvString errstr
Definition: wvencoder.h:72
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...
Definition: wvstring.h:94
The in place raw memory buffer type.
Definition: wvbuf.h:165
A buffer that is always empty.
Definition: wvbufbase.h:990
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.
Definition: wvstring.h:330