From: Francesco Chemolli Date: Fri, 11 Nov 2016 22:43:43 +0000 (+0000) Subject: Ready for testing X-Git-Tag: M-staged-PR71~378^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f9879a34027ae86e1b85ae5acfcdbf335e6a6ed3;p=thirdparty%2Fsquid.git Ready for testing --- diff --git a/src/acl/UserData.cc b/src/acl/UserData.cc index a139d3cde0..7704724908 100644 --- a/src/acl/UserData.cc +++ b/src/acl/UserData.cc @@ -50,7 +50,9 @@ ACLUserData::dump() const sl.insert(sl.end(), userDataNames.begin(), userDataNames.end()); - debugs(28,5, "ACLUserData dump output: " << SBufContainerJoin(userDataNames,SBuf(" "))); + debugs(28,5, "ACLUserData dump output: " << + JoinContainerToSBuf(userDataNames.begin(), userDataNames.end(), + SBuf(" "))); return sl; } diff --git a/src/sbuf/Algorithms.h b/src/sbuf/Algorithms.h index e65284851a..b24de5ea8c 100644 --- a/src/sbuf/Algorithms.h +++ b/src/sbuf/Algorithms.h @@ -54,31 +54,53 @@ private: SBuf::size_type separatorLen_; }; -/// join all the SBuf in a container of SBuf into a single SBuf, separating with separator -template -SBuf -SBufContainerJoin(const Container &items, const SBuf& separator) +/** Join container of SBufs and append to supplied target + * + * append to the target SBuf all elements in the [begin,end) range from + * an iterable container, prefixed by prefix, separated by separator and + * followed by suffix. Prefix and suffix are added also in case of empty + * iterable + * + * \return the modified dest + */ +template +SBuf& +JoinContainerIntoSBuf(SBuf &dest, const ContainerIterator &begin, + const ContainerIterator &end, const SBuf& separator, + const SBuf& prefix = SBuf(), const SBuf& suffix = SBuf()) { - // optimization: pre-calculate needed storage - const SBuf::size_type sz = std::accumulate(items.begin(), items.end(), 0, SBufAddLength(separator)); - - // sz can be zero in two cases: either items is empty, or all items - // are zero-length. In the former case, we must protect against - // dereferencing the iterator later on, and checking sz is more efficient - // than checking items.size(). This check also provides an optimization - // for the latter case without adding complexity. - if (sz == 0) - return SBuf(); + if (begin == end) { + dest.append(prefix).append(suffix); + return dest; + } - SBuf rv; - rv.reserveSpace(sz); + // optimization: pre-calculate needed storage + const SBuf::size_type totalContainerSize = + std::accumulate(begin, end, 0, SBufAddLength(separator)) + + dest.length() + prefix.length() + suffix.length(); + SBufReservationRequirements req; + req.minSpace = totalContainerSize; + dest.reserve(req); - typename Container::const_iterator i(items.begin()); - rv.append(*i); + auto i = begin; + dest.append(prefix); + dest.append(*i); ++i; - for (; i != items.end(); ++i) - rv.append(separator).append(*i); - return rv; + for (; i != end; ++i) + dest.append(separator).append(*i); + dest.append(suffix); + return dest; +} + +/// convenience wrapper of JoinContainerIntoSBuf with no caller-supplied SBuf +template +SBuf +JoinContainerToSBuf(const ContainerIterator &begin, + const ContainerIterator &end, const SBuf& separator, + const SBuf& prefix = SBuf(), const SBuf& suffix = SBuf()) +{ + SBuf rv; + return JoinContainerIntoSBuf(rv, begin, end, separator, prefix, suffix); } namespace std { diff --git a/src/tests/testSBufList.cc b/src/tests/testSBufList.cc index cc4ca0e16b..01fdf828c7 100644 --- a/src/tests/testSBufList.cc +++ b/src/tests/testSBufList.cc @@ -37,11 +37,17 @@ void testSBufList::testSBufListJoin() { SBufList foo; - CPPUNIT_ASSERT_EQUAL(SBuf(""),SBufContainerJoin(foo,SBuf())); - CPPUNIT_ASSERT_EQUAL(SBuf(""),SBufContainerJoin(foo,SBuf())); + CPPUNIT_ASSERT_EQUAL(SBuf(""),JoinContainerToSBuf(foo.begin(), foo.end(),SBuf())); for (int j = 0; j < sbuf_tokens_number; ++j) foo.push_back(tokens[j]); - SBuf joined=SBufContainerJoin(foo,SBuf(" ")); + SBuf joined=JoinContainerToSBuf(foo.begin(), foo.end(),SBuf(" ")); CPPUNIT_ASSERT_EQUAL(literal,joined); + SBuf s1("1"), s2("2"), s3("3"), full("(1,2,3)"); + SBufList sl{s1,s2,s3}; + CPPUNIT_ASSERT_EQUAL(full, JoinContainerToSBuf(sl.begin(), + sl.end(), SBuf(","), SBuf("("), SBuf(")"))); + + CPPUNIT_ASSERT_EQUAL(SBuf(""),JoinContainerToSBuf(foo.begin(), foo.begin(),SBuf())); + }