]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Implemented SBuf forward and reverse input iterators
authorFrancesco Chemolli <kinkie@squid-cache.org>
Sat, 31 Jan 2015 19:41:00 +0000 (20:41 +0100)
committerFrancesco Chemolli <kinkie@squid-cache.org>
Sat, 31 Jan 2015 19:41:00 +0000 (20:41 +0100)
src/SBuf.cc
src/SBuf.h
src/tests/testSBuf.cc
src/tests/testSBuf.h

index 53221d60493a5be2407783f4af5215b16a93f783..146819283543f41bc8b57c8c1a3424360952db3f 100644 (file)
@@ -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<char *>(memchr(begin, needleBegin, lastPossible-begin));
+        tmp = static_cast<char *>(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;
index ef77733dc1fae7e1baacbc2ed554077d1423458b..4d3b8f8f2ec1eae9ab67828d764a4b9f1e32ed9e 100644 (file)
@@ -17,6 +17,7 @@
 #include <climits>
 #include <cstdarg>
 #include <iosfwd>
+#include <iterator>
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -75,6 +76,35 @@ public:
 };
 
 class CharacterSet;
+class SBuf;
+
+class SBufIterator : public std::iterator<std::input_iterator_tag, char>
+{
+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 */
 
index b3059bb67dc9932d4ada2fbf1b0a498b8e36c40a..44e1c285d147760f78ff7a7f8aecc5f2e9cab4e1 100644 (file)
@@ -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);
+    }
+}
index 83318b2918cac865843b81c05e23d4c59ef00b20..838356c7276dadc234fd68a73f1484770c867635 100644 (file)
@@ -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