21
20
* it under the terms of the GNU General Public License as published by
22
21
* the Free Software Foundation; either version 2 of the License, or
23
22
* (at your option) any later version.
25
24
* This program is distributed in the hope that it will be useful,
26
25
* but WITHOUT ANY WARRANTY; without even the implied warranty of
27
26
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28
27
* GNU General Public License for more details.
30
29
* You should have received a copy of the GNU General Public License
31
30
* along with this program; if not, write to the Free Software
32
31
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
37
* To-Do: use memory pools for .buf recycling @?@ @?@
36
\todo use memory pools for .buf recycling @?@ @?@
44
44
* Here is how one would comm_write an object without MemBuffer:
48
48
* buf = malloc(big_enough);
51
51
* snprintf object(s) piece-by-piece constantly checking for overflows
52
52
* and maintaining (buf+offset);
56
56
* comm_write(buf, free, ...);
59
59
* The whole "packing" idea is quite messy: We are given a buffer of fixed
60
60
* size and we have to check all the time that we still fit. Sounds logical.
62
62
* However, what happens if we have more data? If we are lucky to stop before
63
63
* we overrun any buffers, we still may have garbage (e.g. half of ETag) in
69
69
* MemBuffer is a memory-resident buffer with printf()-like interface. It
70
70
* hides all offest handling and overflow checking. Moreover, it has a
71
71
* build-in control that no partial data has been written.
73
73
* MemBuffer is designed to handle relatively small data. It starts with a
74
74
* small buffer of configurable size to avoid allocating huge buffers all the
75
75
* time. MemBuffer doubles the buffer when needed. It assert()s that it will
76
76
* not grow larger than a configurable limit. MemBuffer has virtually no
77
77
* overhead (and can even reduce memory consumption) compared to old
78
78
* "packing" approach.
80
80
* MemBuffer eliminates both "packing" mess and truncated data:
86
86
* -- required init with optional size tuning (see #defines for defaults)
87
87
* buf.init(initial-size, absolute-maximum);
89
89
* -- "pack" (no need to handle offsets or check for overflows)
94
94
* comm_write_mbuf(fd, buf, handler, data);
96
96
* -- *iff* you did not give the buffer away, free it yourself
100
102
/* if you have configure you can use this */
101
103
#if defined(HAVE_CONFIG_H)
102
104
#include "config.h"
220
226
PROF_stop(MemBuf_consume);
223
// calls memcpy, appends exactly size bytes, extends buffer if needed
229
// removes last tailSize bytes
230
void MemBuf::truncate(mb_size_t tailSize)
232
const mb_size_t cSize = contentSize();
233
assert(0 <= tailSize && tailSize <= cSize);
234
assert(!stolen); /* not frozen */
239
* calls memcpy, appends exactly size bytes,
240
* extends buffer or creates buffer if needed.
224
242
void MemBuf::append(const char *newContent, mb_size_t sz)
245
assert(buf || (0==capacity && 0==size));
228
246
assert(!stolen); /* not frozen */
230
248
PROF_start(MemBuf_append);
252
// 0-terminate in case we are used as a string.
253
// Extra octet is not counted in the content size (or space size)
254
// XXX: but the extra octet is counted when growth decisions are made!
255
// This will cause the buffer to grow when spaceSize() == 1 on append,
256
// which will assert() if the buffer cannot grow any more.
271
* Null-terminate in case we are used as a string.
272
* Extra octet is not counted in the content size (or space size)
274
\note XXX: but the extra octet is counted when growth decisions are made!
275
* This will cause the buffer to grow when spaceSize() == 1 on append,
276
* which will assert() if the buffer cannot grow any more.
257
278
void MemBuf::terminate()
259
280
assert(size < capacity);
263
284
/* calls memBufVPrintf */
266
286
MemBuf::Printf(const char *fmt,...)
269
289
va_start(args, fmt);
272
MemBuf::Printf(va_alist)
278
const char *fmt = va_arg(args, char *);
281
290
vPrintf(fmt, args);
286
/* vPrintf for other printf()'s to use; calls vsnprintf, extends buf if needed */
296
* vPrintf for other printf()'s to use; calls vsnprintf, extends buf if needed
288
MemBuf::vPrintf(const char *fmt, va_list vargs) {
299
MemBuf::vPrintf(const char *fmt, va_list vargs)
338
* returns free() function to be used.
340
351
* calling this function "freezes" mb,
341
352
* do not _update_ mb after that in any way
342
353
* (you still can read-access .buf and .size)
355
\retval free() function to be used.
348
362
assert(!stolen); /* not frozen */