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 
36 bool 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 
49 bool 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);
55  setfinished();
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 
77 bool 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 
86 bool WvEncoder::flushstrstr(WvStringParm instr, WvString &outstr,
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 
97 bool 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 
107 WvString WvEncoder::strflushstr(WvStringParm instr, bool finish)
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 
123 bool 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 
132 bool 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 
150 bool WvEncoder::flushstrmem(WvStringParm instr,
151  void *outmem, size_t *outlen, bool finish)
152 {
153  WvConstStringBuffer inbuf(instr);
154  return flushbufmem(inbuf, outmem, outlen, finish);
155 }
156 
157 
158 WvString 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 
167 bool 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 
183 WvPassthroughEncoder::WvPassthroughEncoder()
184 {
185  _reset();
186 }
187 
188 
189 bool 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.
254 bool 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 
277 bool 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 
312 void WvEncoderChain::append(WvEncoder *enc, bool autofree)
313 {
314  encoders.append(new ChainElem(enc, autofree), true);
315 }
316 
317 
318 void 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 
334 void WvEncoderChain::set_autofree(WvEncoder *enc, bool autofree)
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 
WvEncoder::okay
bool okay
Definition: wvencoder.h:70
WvPassthroughEncoder::_encode
virtual bool _encode(WvBuf &in, WvBuf &out, bool flush)
Template method implementation of encode().
Definition: wvencoder.cc:189
WvEncoder
The base encoder class.
Definition: wvencoder.h:67
WvEncoderChain::_isok
virtual bool _isok() const
Returns true if the encoder has not encountered an error.
Definition: wvencoder.cc:218
WvEncoderChain::_finish
virtual bool _finish(WvBuf &out)
Finishes the chain of encoders.
Definition: wvencoder.cc:283
WvEncoder::flushmemmem
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
WvEncoderChain::zap
void zap()
Clears the encoder chain.
Definition: wvencoder.cc:374
WvEncoder::_reset
virtual bool _reset()
Template method implementation of reset().
Definition: wvencoder.h:498
WvEncoderChain::append
void append(WvEncoder *enc, bool autofree)
Appends an encoder to the tail of the chain.
Definition: wvencoder.cc:312
WvBufBase< unsigned char >::getstr
WvString getstr()
Returns the entire buffer as a null-terminated WvString.
Definition: wvbuffer.cc:17
WvEncoderChain::WvEncoderChain
WvEncoderChain()
Creates an initially empty chain of encoders.
Definition: wvencoder.cc:207
WvEncoder::strflushstr
WvString strflushstr(WvStringParm instr, bool finish=false)
Flushes data through the encoder from a string to a string.
Definition: wvencoder.cc:107
WvEncoderChain::_isfinished
virtual bool _isfinished() const
Returns true if the encoder can no longer encode data.
Definition: wvencoder.cc:228
WvEncoder::strflushmem
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
WvConstStringBuffer
A raw memory read-only buffer backed by a constant WvString.
Definition: wvbuf.h:241
WvEncoder::encode
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
WvString
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:329
WvEncoder::flushstrbuf
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::encodebufstr
bool encodebufstr(WvBuf &inbuf, WvString &outstr, bool flush=false, bool finish=false)
Encodes data from a buffer to a string.
Definition: wvencoder.cc:97
WvEncoderChain::_reset
virtual bool _reset()
Resets the chain of encoders.
Definition: wvencoder.cc:298
WvEncoder::~WvEncoder
virtual ~WvEncoder()
Destroys the encoder.
Definition: wvencoder.cc:18
WvInPlaceBuf
The in place raw memory buffer type.
Definition: wvbuf.h:164
WvEncoder::WvEncoder
WvEncoder()
Creates a new WvEncoder.
Definition: wvencoder.cc:11
WvEncoderChain::buffered
size_t buffered()
Returns true if there is data in an internal buffer.
Definition: wvencoder.cc:380
WvEncoderChain::set_autofree
void set_autofree(WvEncoder *enc, bool autofree)
Sets the autofree state of a particular encoder in the chain.
Definition: wvencoder.cc:334
WvEncoder::_encode
virtual bool _encode(WvBuf &inbuf, WvBuf &outbuf, bool flush)=0
Template method implementation of encode().
WvEncoderChain::continue_encode
bool continue_encode(WvBuf &inbuf, WvBuf &outbuf)
"Continues" encoding a buffer.
Definition: wvencoder.cc:290
WvEncoder::flushbufmem
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
WvBufBase< unsigned char >
Specialization of WvBufBase for unsigned char type buffers intended for use with raw memory buffers.
Definition: wvbuf.h:22
WvBufBaseCommonImpl::zap
void zap()
Clears the buffer.
Definition: wvbufbase.h:257
WvEncoder::strflushbuf
WvString strflushbuf(WvBuf &inbuf, bool finish=false)
Flushes data through the encoder from a buffer to a string.
Definition: wvencoder.cc:115
WvEncoder::geterror
WvString geterror() const
Returns an error message if any is available.
Definition: wvencoder.cc:23
WvEncoder::isok
bool isok() const
Returns true if the encoder has not encountered an error.
Definition: wvencoder.h:90
WvConstInPlaceBuf
The const in place raw memory buffer type.
Definition: wvbuf.h:187
WvEncoder::finish
bool finish(WvBuf &outbuf)
Tells the encoder that NO MORE DATA will ever be encoded.
Definition: wvencoder.cc:49
WvEncoder::flushstrstr
bool flushstrstr(WvStringParm instr, WvString &outstr, bool finish=false)
Flushes data through the encoder from a string to a string.
Definition: wvencoder.cc:86
WvEncoderChain::unlink
void unlink(WvEncoder *enc)
Unlinks the encoder from the chain.
Definition: wvencoder.cc:365
WvEncoder::flushbufstr
bool flushbufstr(WvBuf &inbuf, WvString &outstr, bool finish=false)
Flushes data through the encoder from a buffer to a string.
Definition: wvencoder.h:249
WvEncoder::errstr
WvString errstr
Definition: wvencoder.h:72
WvNullBufBase
A buffer that is always empty.
Definition: wvbufbase.h:989
WvEncoder::flush
bool flush(WvBuf &inbuf, WvBuf &outbuf, bool finish=false)
Flushes the encoder and optionally finishes it.
Definition: wvencoder.h:163
WvDynBufBase< unsigned char >
WvEncoderChain::prepend
void prepend(WvEncoder *enc, bool autofree)
Prepends an encoder to the head of the chain.
Definition: wvencoder.cc:318
WvEncoder::setfinished
void setfinished()
Sets 'finished' to true explicitly.
Definition: wvencoder.h:383
WvEncoder::finished
bool finished
Definition: wvencoder.h:71
WvBufBaseCommonImpl::used
size_t used() const
Returns the number of elements in the buffer currently available for reading.
Definition: wvbufbase.h:92
WvNullEncoder::_encode
virtual bool _encode(WvBuf &in, WvBuf &out, bool flush)
Template method implementation of encode().
Definition: wvencoder.cc:167
WvEncoder::_geterror
virtual WvString _geterror() const
Template method implementation of geterror().
Definition: wvencoder.h:433
WvNullEncoder::_reset
virtual bool _reset()
Template method implementation of reset().
Definition: wvencoder.cc:174
WvEncoder::flushstrmem
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
WvEncoder::flushmembuf
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
WvEncoderChain::_encode
virtual bool _encode(WvBuf &in, WvBuf &out, bool flush)
Passes the data through the entire chain of encoders.
Definition: wvencoder.cc:277
WvBufBaseCommonImpl::merge
void merge(Buffer &inbuf, size_t count)
Efficiently moves count bytes from the specified buffer into this one.
Definition: wvbufbase.h:558
WvEncoder::encodebufmem
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
WvEncoder::seterror
void seterror(WvStringParm message)
Sets an error condition, then setnotok().
Definition: wvencoder.h:375
WvEncoder::_finish
virtual bool _finish(WvBuf &outbuf)
Template method implementation of finish().
Definition: wvencoder.h:483
WvEncoderChain::~WvEncoderChain
virtual ~WvEncoderChain()
Destroys the encoder chain.
Definition: wvencoder.cc:213
WvEncoderChain::get_autofree
bool get_autofree(WvEncoder *enc) const
Gets the autofree state of a particular encoder in the chain.
Definition: wvencoder.cc:324
WvPassthroughEncoder::_reset
virtual bool _reset()
Template method implementation of reset().
Definition: wvencoder.cc:197
WvEncoder::reset
bool reset()
Asks an encoder to reset itself to its initial state at creation time, if supported.
Definition: wvencoder.cc:60
WvEncoderChain::_geterror
virtual WvString _geterror() const
Returns the error message, if any.
Definition: wvencoder.cc:238