MemBuf.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
72#include "squid.h"
73#include "mem/forward.h"
74#include "MemBuf.h"
75
76/* local constants */
77
78/* default values for buffer sizes, used by memBufDefInit */
79#define MEM_BUF_INIT_SIZE (2*1024)
80#define MEM_BUF_MAX_SIZE (2*1000*1024*1024)
81
83
85void
87{
89}
90
92void
94{
95 assert(szInit > 0 && szMax > 0);
96 buf = nullptr;
97 size = 0;
98 max_capacity = szMax;
99 capacity = 0;
100 stolen = 0;
101 grow(szInit);
102 terminate();
103}
104
109void
111{
112 if (isNull()) {
113 // nothing to do
114 } else {
115 assert(buf);
116 assert(!stolen); /* not frozen */
117
119 buf = nullptr;
120 size = capacity = max_capacity = 0;
121 }
122}
123
128void
130{
131 if (isNull()) {
132 init();
133 } else {
134 assert(!stolen); /* not frozen */
135 /* reset */
136 memset(buf, 0, capacity);
137 size = 0;
138 }
139}
140
144int
146{
147 if (!buf && !max_capacity && !capacity && !size)
148 return 1; /* is null (not initialized) */
149
150 assert(buf && max_capacity && capacity); /* paranoid */
151
152 return 0;
153}
154
156{
157 const mb_size_t terminatedSize = size + 1;
158 return (terminatedSize < capacity) ? capacity - terminatedSize : 0;
159}
160
162{
163 const mb_size_t terminatedSize = size + 1;
164 return (terminatedSize < max_capacity) ? max_capacity - terminatedSize : 0;
165}
166
169{
170 const mb_size_t cSize = contentSize();
171 assert(0 <= shiftSize && shiftSize <= cSize);
172 assert(!stolen); /* not frozen */
173
174 if (shiftSize > 0) {
175 if (shiftSize < cSize)
176 memmove(buf, buf + shiftSize, cSize - shiftSize);
177
178 size -= shiftSize;
179
180 terminate();
181 }
182}
183
186{
187 if (contentSize() > 0) {
188 const char *end = buf + contentSize();
189 const char *p = buf;
190 for (; p<end && xisspace(*p); ++p);
191 if (p-buf > 0)
192 consume(p-buf);
193 }
194}
195
196// removes last tailSize bytes
198{
199 const mb_size_t cSize = contentSize();
200 assert(0 <= tailSize && tailSize <= cSize);
201 assert(!stolen); /* not frozen */
202 size -= tailSize;
203}
204
209void MemBuf::append(const char *newContent, int sz)
210{
211 assert(sz >= 0);
212 assert(buf || (0==capacity && 0==size));
213 assert(!stolen); /* not frozen */
214
215 if (sz > 0) {
216 if (size + sz + 1 > capacity)
217 grow(size + sz + 1);
218
219 assert(size + sz <= capacity); /* paranoid */
220 memcpy(space(), newContent, sz);
221 appended(sz);
222 }
223}
224
227{
228 assert(size + sz <= capacity);
229 size += sz;
230 terminate();
231}
232
242{
244 *space() = '\0';
245}
246
250void
251MemBuf::vappendf(const char *fmt, va_list vargs)
252{
253 int sz = 0;
254 assert(fmt);
255 assert(buf);
256 assert(!stolen); /* not frozen */
257 /* assert in Grow should quit first, but we do not want to have a scary infinite loop */
258
259 while (capacity <= max_capacity) {
260 mb_size_t free_space = capacity - size;
261 /* put as much as we can */
262
263 /* Fix of bug 753r. The value of vargs is undefined
264 * after vsnprintf() returns. Make a copy of vargs
265 * in case we loop around and call vsnprintf() again.
266 */
267 va_list ap;
268 va_copy(ap,vargs);
269 sz = vsnprintf(buf + size, free_space, fmt, ap);
270 va_end(ap);
271
272 /* check for possible overflow */
273 /* snprintf on Linuz returns -1 on overflows */
274 /* snprintf on FreeBSD returns at least free_space on overflows */
275
276 if (sz < 0 || sz >= free_space)
277 grow(capacity + 1);
278 else
279 break;
280 }
281
282 size += sz;
283 /* on Linux and FreeBSD, '\0' is not counted in return value */
284 /* on XXX it might be counted */
285 /* check that '\0' is appended and not counted */
286
287 if (!size || buf[size - 1]) {
288 assert(!buf[size]);
289 } else {
290 --size;
291 }
292}
293
302FREE *
304{
305 FREE *ff;
306 assert(buf);
307 assert(!stolen); /* not frozen */
308
309 ff = memFreeBufFunc((size_t) capacity);
310 stolen = 1; /* freeze */
311 return ff;
312}
313
317void
319{
320 size_t new_cap;
321 size_t buf_cap;
322
323 assert(!stolen);
324 assert(capacity < min_cap);
325
326 /* determine next capacity */
327
328 if (min_cap > 64 * 1024) {
329 new_cap = 64 * 1024;
330
331 while (new_cap < (size_t) min_cap)
332 new_cap += 64 * 1024; /* increase in reasonable steps */
333 } else {
334 new_cap = (size_t) min_cap;
335 }
336
337 /* last chance to fit before we assert(!overflow) */
338 if (new_cap > (size_t) max_capacity)
339 new_cap = (size_t) max_capacity;
340
341 assert(new_cap <= (size_t) max_capacity); /* no overflow */
342
343 assert(new_cap > (size_t) capacity); /* progress */
344
345 buf_cap = (size_t) capacity;
346
347 buf = (char *)memReallocBuf(buf, new_cap, &buf_cap);
348
349 /* done */
350 capacity = (mb_size_t) buf_cap;
351}
352
353/* Reports */
354
358void
360{
361 assert(mb);
362 mb->appendf("memBufReport is not yet implemented @?@\n");
363}
364
#define MEM_BUF_MAX_SIZE
Definition: MemBuf.cc:80
#define MEM_BUF_INIT_SIZE
Definition: MemBuf.cc:79
void memBufReport(MemBuf *mb)
Definition: MemBuf.cc:359
ssize_t mb_size_t
Definition: MemBuf.h:17
#define assert(EX)
Definition: assert.h:17
#define CBDATA_CLASS_INIT(type)
Definition: cbdata.h:320
Definition: MemBuf.h:24
mb_size_t spaceSize() const
Definition: MemBuf.cc:155
void init()
Definition: MemBuf.cc:86
void clean()
Definition: MemBuf.cc:110
void truncate(mb_size_t sz)
Definition: MemBuf.cc:197
void append(const char *c, int sz) override
Definition: MemBuf.cc:209
char * space()
returns buffer after data; does not check space existence
Definition: MemBuf.h:57
FREE * freeFunc()
Definition: MemBuf.cc:303
mb_size_t size
Definition: MemBuf.h:135
char * buf
Definition: MemBuf.h:134
void grow(mb_size_t min_cap)
Definition: MemBuf.cc:318
mb_size_t max_capacity
Definition: MemBuf.h:142
mb_size_t contentSize() const
available data size
Definition: MemBuf.h:47
mb_size_t potentialSpaceSize() const
Definition: MemBuf.cc:161
void consume(mb_size_t sz)
removes sz bytes and "packs" by moving content left
Definition: MemBuf.cc:168
int isNull() const
Definition: MemBuf.cc:145
void reset()
Definition: MemBuf.cc:129
mb_size_t capacity
Definition: MemBuf.h:149
void appended(mb_size_t sz)
updates content size after external append
Definition: MemBuf.cc:226
void terminate()
Definition: MemBuf.cc:241
unsigned stolen
Definition: MemBuf.h:151
void vappendf(const char *fmt, va_list ap) override
Definition: MemBuf.cc:251
void consumeWhitespacePrefix()
removes all prefix whitespace, moving content left
Definition: MemBuf.cc:185
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
Definition: Packable.h:61
void FREE(void *)
Definition: forward.h:37
void memFreeBuf(size_t size, void *)
Definition: minimal.cc:90
void * memReallocBuf(void *buf, size_t net_size, size_t *gross_size)
Definition: minimal.cc:53
FREE * memFreeBufFunc(size_t size)
Definition: minimal.cc:102
int const char size_t
Definition: stub_liblog.cc:83
#define xisspace(x)
Definition: xis.h:15

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors