++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;
debugs(24, 8, "Found at " << (tmp-buf()));
return (tmp-buf());
}
- begin = tmp+1;
+ start = tmp+1;
}
debugs(24, 8, "not found");
return npos;
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;
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;
#include <climits>
#include <cstdarg>
#include <iosfwd>
+#include <iterator>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
};
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.
{
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.
/// 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:
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 */
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);
+ }
+}
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:
void testFindFirstNotOf();
void testAutoFind();
void testStdStringOps();
+ void testIterators();
};
#endif