From: Francesco Chemolli Date: Sat, 31 Jan 2015 19:41:00 +0000 (+0100) Subject: Implemented SBuf forward and reverse input iterators X-Git-Tag: merge-candidate-3-v1~302^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8a3e1749876f955a03f4c5281e3a5dcd22d8b9ad;p=thirdparty%2Fsquid.git Implemented SBuf forward and reverse input iterators --- diff --git a/src/SBuf.cc b/src/SBuf.cc index 53221d6049..1468192835 100644 --- a/src/SBuf.cc +++ b/src/SBuf.cc @@ -630,17 +630,17 @@ SBuf::find(const SBuf &needle, size_type startPos) const ++stats.find; - char *begin = buf()+startPos; + char *start = buf()+startPos; char *lastPossible = buf()+length()-needle.length()+1; char needleBegin = needle[0]; debugs(24, 7, "looking for " << needle << "starting at " << startPos << " in id " << id); - while (begin < lastPossible) { + while (start < lastPossible) { char *tmp; - debugs(24, 8, " begin=" << (void *) begin << + debugs(24, 8, " begin=" << (void *) start << ", lastPossible=" << (void*) lastPossible ); - tmp = static_cast(memchr(begin, needleBegin, lastPossible-begin)); + tmp = static_cast(memchr(start, needleBegin, lastPossible-start)); if (tmp == NULL) { debugs(24, 8 , "First byte not found"); return npos; @@ -650,7 +650,7 @@ SBuf::find(const SBuf &needle, size_type startPos) const debugs(24, 8, "Found at " << (tmp-buf())); return (tmp-buf()); } - begin = tmp+1; + start = tmp+1; } debugs(24, 8, "not found"); return npos; @@ -736,8 +736,8 @@ SBuf::findFirstOf(const CharacterSet &set, size_type startPos) const debugs(24, 7, "first of characterset " << set.name << " in id " << id); char *cur = buf()+startPos; - const char *end = bufEnd(); - while (cur < end) { + const char *bufend = bufEnd(); + while (cur < bufend) { if (set[*cur]) return cur-buf(); ++cur; @@ -759,8 +759,8 @@ SBuf::findFirstNotOf(const CharacterSet &set, size_type startPos) const debugs(24, 7, "first not of characterset " << set.name << " in id " << id); char *cur = buf()+startPos; - const char *end = bufEnd(); - while (cur < end) { + const char *bufend = bufEnd(); + while (cur < bufend) { if (!set[*cur]) return cur-buf(); ++cur; diff --git a/src/SBuf.h b/src/SBuf.h index ef77733dc1..4d3b8f8f2e 100644 --- a/src/SBuf.h +++ b/src/SBuf.h @@ -17,6 +17,7 @@ #include #include #include +#include #if HAVE_UNISTD_H #include #endif @@ -75,6 +76,35 @@ public: }; class CharacterSet; +class SBuf; + +class SBufIterator : public std::iterator +{ +public: + friend class SBuf; + typedef MemBlob::size_type size_type; + bool operator==(const SBufIterator &s) const; + bool operator!=(const SBufIterator &s) const; + + char operator*() const { return *iter; } + SBufIterator& operator++() { ++iter; return *this; } + +protected: + SBufIterator(const SBuf &, size_type); + + const SBuf &sbuf; + const char *iter; +}; + +class SBufReverseIterator : public SBufIterator +{ + friend class SBuf; +public: + SBufReverseIterator& operator++() { --iter; return *this;} + char operator*() const { return *(iter-1); } +protected: + SBufReverseIterator(const SBuf &s, size_type sz) : SBufIterator(s,sz) {} +}; /** * A String or Buffer. @@ -86,6 +116,8 @@ class SBuf { public: typedef MemBlob::size_type size_type; + typedef SBufIterator iterator; + typedef SBufReverseIterator reverse_iterator; static const size_type npos = 0xffffffff; // max(uint32_t) /// Maximum size of a SBuf. By design it MUST be < MAX(size_type)/2. Currently 256Mb. @@ -541,6 +573,22 @@ public: /// std::string export function std::string toStdString() const { return std::string(buf(),length()); } + iterator begin() { + return iterator(*this, 0); + } + + iterator end() { + return iterator(*this, length()); + } + + reverse_iterator rbegin() { + return reverse_iterator(*this, length()); + } + + reverse_iterator rend() { + return reverse_iterator(*this, 0); + } + // TODO: possibly implement erase() similar to std::string's erase // TODO: possibly implement a replace() call private: @@ -619,5 +667,24 @@ ToLower(SBuf buf) return buf; } +inline +SBufIterator::SBufIterator(const SBuf &s, size_type pos) + : sbuf(s), iter(s.rawContent()+pos) +{} + +inline bool +SBufIterator::operator==(const SBufIterator &s) const +{ + // note: maybe the sbuf comparison is unnecessary? + return iter == s.iter && sbuf == s.sbuf; +} + +inline bool +SBufIterator::operator!=(const SBufIterator &s) const +{ + // note: maybe the sbuf comparison is unnecessary? + return iter != s.iter || sbuf != s.sbuf; +} + #endif /* SQUID_SBUF_H */ diff --git a/src/tests/testSBuf.cc b/src/tests/testSBuf.cc index b3059bb67d..44e1c285d1 100644 --- a/src/tests/testSBuf.cc +++ b/src/tests/testSBuf.cc @@ -915,3 +915,39 @@ testSBuf::testStdStringOps() CPPUNIT_ASSERT_EQUAL(astr,sb.toStdString()); } +void +testSBuf::testIterators() +{ + SBuf text("foo"), text2("foo"); + CPPUNIT_ASSERT(text.begin() == text.begin()); + CPPUNIT_ASSERT(text.begin() != text.end()); + CPPUNIT_ASSERT(text.begin() != text2.begin()); + { + auto i = text.begin(); + auto e = text.end() + CPPUNIT_ASSERT_EQUAL('f', *i); + CPPUNIT_ASSERT(i != e); + ++i; + CPPUNIT_ASSERT_EQUAL('o', *i); + CPPUNIT_ASSERT(i != e); + ++i; + CPPUNIT_ASSERT_EQUAL('o', *i); + CPPUNIT_ASSERT(i != e); + ++i; + CPPUNIT_ASSERT(i == e); + } + { + auto i = text.rbegin(); + auto e = text.rend(); + CPPUNIT_ASSERT_EQUAL('o', *i); + CPPUNIT_ASSERT(i != e); + ++i; + CPPUNIT_ASSERT_EQUAL('o', *i); + CPPUNIT_ASSERT(i != e); + ++i; + CPPUNIT_ASSERT_EQUAL('f', *i); + CPPUNIT_ASSERT(i != e); + ++i; + CPPUNIT_ASSERT(i == e); + } +} diff --git a/src/tests/testSBuf.h b/src/tests/testSBuf.h index 83318b2918..838356c727 100644 --- a/src/tests/testSBuf.h +++ b/src/tests/testSBuf.h @@ -52,6 +52,7 @@ class testSBuf : public CPPUNIT_NS::TestFixture CPPUNIT_TEST( testSBufStream ); CPPUNIT_TEST( testAutoFind ); CPPUNIT_TEST( testStdStringOps ); + CPPUNIT_TEST( testIterators ); // CPPUNIT_TEST( testDumpStats ); //fake test, to print alloc stats CPPUNIT_TEST_SUITE_END(); protected: @@ -91,6 +92,7 @@ protected: void testFindFirstNotOf(); void testAutoFind(); void testStdStringOps(); + void testIterators(); }; #endif