DnsLookupDetails.cc
SBUF_SOURCE= \
+ base/CharacterSet.h \
base/InstanceId.h \
MemBlob.h \
MemBlob.cc \
}
SBuf::size_type
-SBuf::find_first_of(const SBuf &set, size_type startPos) const
+SBuf::find_first_of(const CharacterSet &set, size_type startPos) const
{
- // if set is 1 char big, use the char search. Stats updated there
- if (set.length() == 1)
- return find(set[0], startPos);
-
++stats.find;
if (startPos == npos)
if (startPos >= length())
return npos;
- if (set.length() == 0)
+ debugs(24, 7, "first of characterset " << set.name << " in id " << id);
+ char *cur = buf()+startPos;
+ const char *end = bufEnd();
+ while (cur < end) {
+ if (set[*cur])
+ return cur-buf();
+ ++cur;
+ }
+ debugs(24, 7, "not found");
+ return npos;
+}
+
+SBuf::size_type
+SBuf::find_first_not_of(const CharacterSet &set, size_type startPos) const
+{
+ ++stats.find;
+
+ if (startPos == npos)
return npos;
- debugs(24, 7, "any of '" << set << "' " << " in id " << id);
- char *cur = buf()+startPos, *end = bufEnd();
+ if (startPos >= length())
+ return npos;
+
+ debugs(24, 7, "first not of characterset " << set.name << " in id " << id);
+ char *cur = buf()+startPos;
+ const char *end = bufEnd();
while (cur < end) {
- if (memchr(set.buf(), *cur, set.length()))
- return (cur-buf());
+ if (!set[*cur])
+ return cur-buf();
++cur;
}
debugs(24, 7, "not found");
- return npos;
+ return length();
}
/*
#ifndef SQUID_SBUF_H
#define SQUID_SBUF_H
+#include "base/CharacterSet.h"
#include "base/InstanceId.h"
#include "MemBlob.h"
#include "SBufExceptions.h"
* \param startPos if specified, ignore any occurrences before that position
* if npos, then npos is always returned
*/
- size_type find_first_of(const SBuf &set, size_type startPos = 0) const;
+ size_type find_first_of(const CharacterSet &set, size_type startPos = 0) const;
+
+ /** Find first occurrence character NOT in character set
+ *
+ * \return length() if all characters in the SBuf are from set
+ * \param startPos if specified, ignore any occurrences before that position
+ * if npos, then npos is always returned
+ */
+ size_type find_first_not_of(const CharacterSet &set, size_type startPos = 0) const;
/** sscanf-alike
*
--- /dev/null
+#ifndef _SQUID_SRC_PARSER_CHARACTERSET_H
+#define _SQUID_SRC_PARSER_CHARACTERSET_H
+
+#include <vector>
+
+class CharacterSet
+{
+public:
+ CharacterSet(const char *label, const char * const c) : name(label), chars_(std::vector<bool>(256,false)) {
+ size_t clen = strlen(c);
+ for (size_t i = 0; i < clen; ++i)
+ chars_[static_cast<uint8_t>(c[i])] = true;
+ }
+
+ /// whether a given character exists in the set
+ bool operator[](unsigned char c) const {return chars_[static_cast<uint8_t>(c)];}
+
+ /// add a given char to the character set. c must be >= 0.
+ CharacterSet & add(const unsigned char c) {chars_[static_cast<uint8_t>(c)] = true; return *this; }
+
+ /// add all characters from the given CharacterSet to this one
+ const CharacterSet &operator +=(const CharacterSet &src) {
+ //precondition: src.chars_.size() == chars_.size()
+ std::vector<bool>::const_iterator s = src.chars_.begin();
+ const std::vector<bool>::const_iterator e = src.chars_.end();
+ std::vector<bool>::iterator d = chars_.begin();
+ while (s != e) {
+ if (*s)
+ *d = true;
+ ++s;
+ ++d;
+ }
+ return *this;
+ }
+
+ /// name of this character set
+ const char * name;
+
+private:
+ /// characters defined in this set
+ std::vector<bool> chars_; //std::vector<bool> is optimized
+};
+
+#endif /* _SQUID_SRC_PARSER_CHARACTERSET_H */
AsyncJobCalls.h \
AsyncCallQueue.cc \
AsyncCallQueue.h \
+ CharacterSet.h \
TidyPointer.h \
CbcPointer.h \
InstanceId.h \
noinst_LTLIBRARIES = libicmp-core.la libicmp.la
SBUF_SOURCE= \
+ $(top_srcdir)/src/base/CharacterSet.h \
$(top_srcdir)/src/SBuf.h \
$(top_srcdir)/src/SBuf.cc \
$(top_srcdir)/src/MemBlob.h \
{
theFindString = theStringHay.find_first_of(theStringNeedle, thePos);
theBareNeedlePos = theStringHay.find_first_of(theStringNeedle);
- theFindSBuf = theSBufHay.find_first_of(theSBufNeedle, thePos);
+ theFindSBuf = theSBufHay.find_first_of(CharacterSet("cs",theSBufNeedle.c_str()), thePos);
checkResults("find_first_of");
}
SBuf::size_type idx;
// not found
- idx=haystack.find_first_of(SBuf("ADHRWYP"));
+ idx=haystack.find_first_of(CharacterSet("t1","ADHRWYP"));
CPPUNIT_ASSERT_EQUAL(SBuf::npos,idx);
// found at beginning
- idx=haystack.find_first_of(SBuf("THANDF"));
+ idx=haystack.find_first_of(CharacterSet("t2","THANDF"));
CPPUNIT_ASSERT_EQUAL(0U,idx);
//found at end of haystack
- idx=haystack.find_first_of(SBuf("QWERYVg"));
+ idx=haystack.find_first_of(CharacterSet("t3","QWERYVg"));
CPPUNIT_ASSERT_EQUAL(haystack.length()-1,idx);
//found in the middle of haystack
- idx=haystack.find_first_of(SBuf("QWERqYV"));
+ idx=haystack.find_first_of(CharacterSet("t4","QWERqYV"));
CPPUNIT_ASSERT_EQUAL(4U,idx);
}
+void
+testSBuf::testFindFirstNotOf()
+{
+ SBuf haystack(literal);
+ SBuf::size_type idx;
+
+ // all chars from the set
+ idx=haystack.find_first_not_of(CharacterSet("t1",literal.c_str()));
+ CPPUNIT_ASSERT_EQUAL(haystack.length(),idx);
+
+ // found at beginning
+ idx=haystack.find_first_not_of(CharacterSet("t2","a"));
+ CPPUNIT_ASSERT_EQUAL(0U,idx);
+
+ //found at end of haystack
+ idx=haystack.find_first_not_of(CharacterSet("t3",literal.substr(0,literal.length()-1).c_str()));
+ CPPUNIT_ASSERT_EQUAL(haystack.length()-1,idx);
+
+ //found in the middle of haystack
+ idx=haystack.find_first_not_of(CharacterSet("t4","The"));
+ CPPUNIT_ASSERT_EQUAL(3U,idx);
+}
+
+
void
testSBuf::testAutoFind()
{
CPPUNIT_TEST( testRFindChar );
CPPUNIT_TEST( testRFindSBuf );
CPPUNIT_TEST( testFindFirstOf );
+ CPPUNIT_TEST( testFindFirstNotOf );
CPPUNIT_TEST( testPrintf );
CPPUNIT_TEST( testScanf );
CPPUNIT_TEST( testCopy );
void testStartsWith();
void testSBufStream();
void testFindFirstOf();
+ void testFindFirstNotOf();
void testAutoFind();
void testStdStringOps();
};