--------------------- PatchSet 1524 Date: 2005/08/18 05:14:33 Author: rousskov Branch: squid3-icap Tag: (none) Log: - Added consume() and append*() methods to allow the buffer to be used in a consumer/producer pipe-like environment. - Added content() and space() methods as the first step to hide buf and size members that require consume() method to always shift content to keep a copyf of buf member valid (in case somebody made a copy of it). - Noted that spaceSize() logic assumes the buffer does not expand and is 0-terminated. This means that the following does not hold: max_capacity == contentSize() + spaceSize() Fortunately, max_capacity is a private member that nobody should be using outside of MemBuf.cc - Localized 0-termination code. Does anybody actually use this [implicit] 0-termination of a MemBuf? Can we make it explicit like string::c_str()? Members: src/MemBuf.cc:1.6->1.6.8.1 src/MemBuf.h:1.3->1.3.16.1 Index: squid3/src/MemBuf.cc =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/MemBuf.cc,v retrieving revision 1.6 retrieving revision 1.6.8.1 diff -u -r1.6 -r1.6.8.1 --- squid3/src/MemBuf.cc 22 Dec 2004 03:13:57 -0000 1.6 +++ squid3/src/MemBuf.cc 18 Aug 2005 05:14:33 -0000 1.6.8.1 @@ -1,6 +1,6 @@ /* - * $Id: MemBuf.cc,v 1.6 2004/12/22 03:13:57 squidadm Exp $ + * $Id: MemBuf.cc,v 1.6.8.1 2005/08/18 05:14:33 rousskov Exp $ * * DEBUG: section 59 auto-growing Memory Buffer with printf * AUTHOR: Alex Rousskov @@ -195,27 +195,63 @@ return 0; } - -/* calls memcpy, appends exactly size bytes, extends buffer if needed */ -void -memBufAppend(MemBuf * mb, const char *buf, mb_size_t sz) -{ - assert(mb && buf && sz >= 0); - assert(mb->buf); - assert(!mb->stolen); /* not frozen */ +mb_size_t MemBuf::spaceSize() const { + const mb_size_t terminatedSize = size + 1; + return (terminatedSize < capacity) ? capacity - terminatedSize : 0; +} + +// removes sz bytes and "packs" by moving content left +void MemBuf::consume(mb_size_t shiftSize) { + const mb_size_t cSize = contentSize(); + assert(0 <= shiftSize && shiftSize <= cSize); + assert(!stolen); /* not frozen */ + if (shiftSize > 0) { + if (shiftSize < cSize) + xmemmove(buf, buf + shiftSize, cSize - shiftSize); + size -= shiftSize; + terminate(); + } +} + +// calls memcpy, appends exactly size bytes, extends buffer if needed +void MemBuf::append(const char *newContent, mb_size_t sz) { + assert(sz >= 0); + assert(buf); + assert(!stolen); /* not frozen */ if (sz > 0) { - if (mb->size + sz + 1 > mb->capacity) - memBufGrow(mb, mb->size + sz + 1); - - assert(mb->size + sz <= mb->capacity); /* paranoid */ + if (size + sz + 1 > capacity) + memBufGrow(this, size + sz + 1); - xmemcpy(mb->buf + mb->size, buf, sz); + assert(size + sz <= capacity); /* paranoid */ - mb->size += sz; + xmemcpy(space(), newContent, sz); + appended(sz); + } +} + +// updates content size after external append +void MemBuf::appended(mb_size_t sz) { + assert(size + sz <= capacity); + size += sz; + terminate(); +} + +// 0-terminate in case we are used as a string. +// Extra octet is not counted in the content size (or space size) +// XXX: but the extra octet is counted when growth decisions are made! +// This will cause the buffer to grow when spaceSize() == 1 on append, +// which will assert() if the buffer cannot grow any more. +void MemBuf::terminate() { + assert(size < capacity); + *space() = '\0'; +} - mb->buf[mb->size] = '\0'; /* \0 terminate in case we are used as a string. Not counted in the size */ - } +void +memBufAppend(MemBuf * mb, const char *buf, mb_size_t sz) +{ + assert(mb); + mb->append(buf, sz); } /* calls memBufVPrintf */ Index: squid3/src/MemBuf.h =================================================================== RCS file: /cvsroot/squid-sf//squid3/src/MemBuf.h,v retrieving revision 1.3 retrieving revision 1.3.16.1 diff -u -r1.3 -r1.3.16.1 --- squid3/src/MemBuf.h 22 Feb 2003 03:14:30 -0000 1.3 +++ squid3/src/MemBuf.h 18 Aug 2005 05:14:33 -0000 1.3.16.1 @@ -1,6 +1,6 @@ /* - * $Id: MemBuf.h,v 1.3 2003/02/22 03:14:30 squidadm Exp $ + * $Id: MemBuf.h,v 1.3.16.1 2005/08/18 05:14:33 rousskov Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -42,11 +42,35 @@ public: _SQUID_INLINE_ MemBuf(); - /* public, read-only */ - char *buf; - mb_size_t size; /* used space, does not count 0-terminator */ + + /* use methods instead of deprecated buf and size members */ + + char *content() { return buf; } // start of the added data + mb_size_t contentSize() const { return size; } // available data size + + // space-related methods assume no growth and accounts for 0-termination + char *space() { return buf + size; } // space to add data + mb_size_t spaceSize() const; + bool packed() const { return spaceSize() <= 0; } + + void consume(mb_size_t sz); // removes sz bytes, moving content left + void append(const char *c, mb_size_t sz); // grows if needed and possible + void appended(mb_size_t sz); // updates content size after external append + + // XXX: convert global memBuf*() functions into methods + +private: + void terminate(); + +public: + /* public, read-only, depricated in favor of space*() and content*() */ + // XXX: hide these members completely and remove 0-termination + // so that consume() does not need to memmove all the time + char *buf; // available content + mb_size_t size; // used space, does not count 0-terminator /* private, stay away; use interface function instead */ + // XXX: make these private after converting memBuf*() functions to methods mb_size_t max_capacity; /* when grows: assert(new_capacity <= max_capacity) */ mb_size_t capacity; /* allocated space */