This replaces the SBuf::trim() to use CharacterSet instead of an SBuf()
list of characters and memchr()

It seems to be faster for CharacterSet lookup than repeated memchr
calls, but Im not certain of that. It is certainly makes simpler parser
code with trim and a predefined CharacterSet than static SBuf set of chars.

Amos
=== modified file 'src/SBuf.cc'
--- src/SBuf.cc 2014-05-19 06:06:36 +0000
+++ src/SBuf.cc 2014-06-02 08:37:21 +0000
@@ -549,54 +549,54 @@
     ++stats.nulTerminate;
     return buf();
 }
 
 SBuf&
 SBuf::chop(size_type pos, size_type n)
 {
     if (pos == npos || pos > length() || n == 0) {
         clear();
         return *this;
     }
     if (n == npos || (pos+n) > length())
         n = length()-pos;
     ++stats.chop;
     off_ += pos;
     len_ = n;
     return *this;
 }
 
 SBuf&
-SBuf::trim(const SBuf &toRemove, bool atBeginning, bool atEnd)
+SBuf::trim(const CharacterSet &toRemove, bool atBeginning, bool atEnd)
 {
     ++stats.trim;
     if (atEnd) {
         const char *p = bufEnd()-1;
-        while (!isEmpty() && memchr(toRemove.buf(), *p, toRemove.length()) != 
NULL) {
+        while (!isEmpty() && toRemove[*p]) {
             //current end-of-buf is in the searched set
             --len_;
             --p;
         }
     }
     if (atBeginning) {
         const char *p = buf();
-        while (!isEmpty() && memchr(toRemove.buf(), *p, toRemove.length()) != 
NULL) {
+        while (!isEmpty() && toRemove[*p]) {
             --len_;
             ++off_;
             ++p;
         }
     }
     if (isEmpty())
         clear();
     return *this;
 }
 
 SBuf
 SBuf::substr(size_type pos, size_type n) const
 {
     SBuf rv(*this);
     rv.chop(pos, n); //stats handled by callee
     return rv;
 }
 
 SBuf::size_type
 SBuf::find(char c, size_type startPos) const

=== modified file 'src/SBuf.h'
--- src/SBuf.h  2014-04-21 17:14:44 +0000
+++ src/SBuf.h  2014-06-02 08:36:19 +0000
@@ -447,41 +447,41 @@
      * bytes starting from position 'pos', first byte is at pos 0.
      * It is an in-place-modifying version of substr.
      * \param pos start sub-stringing from this byte. If it is
      *      npos or it is greater than the SBuf length, the SBuf is cleared and
      *      an empty SBuf is returned.
      * \param n maximum number of bytes of the resulting SBuf.
      *     npos means "to end of SBuf".
      *     if it is 0, the SBuf is cleared and an empty SBuf is returned.
      *     if it overflows the end of the SBuf, it is capped to the end of SBuf
      * \see substr, trim
      */
     SBuf& chop(size_type pos, size_type n = npos);
 
     /** Remove characters in the toremove set at the beginning, end or both
      *
      * \param toremove characters to be removed. Stops chomping at the first
      *        found char not in the set
      * \param atBeginning if true (default), strips at the beginning of the 
SBuf
      * \param atEnd if true (default), strips at the end of the SBuf
      */
-    SBuf& trim(const SBuf &toRemove, bool atBeginning = true, bool atEnd = 
true);
+    SBuf& trim(const CharacterSet &toRemove, bool atBeginning = true, bool 
atEnd = true);
 
     /** Extract a part of the current SBuf.
      *
      * Return a fresh a fresh copy of a portion the current SBuf, which is
      * left untouched. The same parameter convetions apply as for chop.
      * \see trim, chop
      */
     SBuf substr(size_type pos, size_type n = npos) const;
 
     /** Find first occurrence of character in SBuf
      *
      * Returns the index in the SBuf of the first occurrence of char c.
      * \return npos if the char was not found
      * \param startPos if specified, ignore any occurrences before that 
position
      *     if startPos is npos or greater than length() npos is always returned
      *     if startPos is less than zero, it is ignored
      */
     size_type find(char c, size_type startPos = 0) const;
 
     /** Find first occurrence of SBuf in SBuf.

=== modified file 'src/tests/testSBuf.cc'
--- src/tests/testSBuf.cc       2014-04-21 17:14:44 +0000
+++ src/tests/testSBuf.cc       2014-06-03 06:43:58 +0000
@@ -462,48 +462,49 @@
     }
     { // null-chop
         SBuf b(a);
         b.chop(0,b.length());
         SBuf ref(a);
         CPPUNIT_ASSERT_EQUAL(ref,b);
     }
     { // overflow chopped area
         SBuf b(a);
         b.chop(b.length()-3,b.length());
         SBuf ref("xyz");
         CPPUNIT_ASSERT_EQUAL(ref,b);
     }
 }
 
 void
 testSBuf::testChomp()
 {
     SBuf s1("complete string");
     SBuf s2(s1);
-    s2.trim(SBuf(" ,"));
+    CharacterSet spc(NULL," ,");
+    s2.trim(spc);
     CPPUNIT_ASSERT_EQUAL(s1,s2);
     s2.assign(" complete string ,");
-    s2.trim(SBuf(" ,"));
+    s2.trim(spc);
     CPPUNIT_ASSERT_EQUAL(s1,s2);
     s1.assign(", complete string ,");
     s2=s1;
-    s2.trim(SBuf(" "));
+    s2.trim(CharacterSet::SP);
     CPPUNIT_ASSERT_EQUAL(s1,s2);
 }
 
 // inspired by SBufFindTest; to be expanded.
 class SBufSubstrAutoTest
 {
     SBuf fullString, sb;
     std::string fullReference, str;
 public:
     void performEqualityTest() {
         SBuf ref(str);
         CPPUNIT_ASSERT_EQUAL(ref,sb);
     }
     SBufSubstrAutoTest() : fullString(fox), fullReference(fox) {
         for (int offset=fullString.length()-1; offset >= 0; --offset ) {
             for (int length=fullString.length()-1-offset; length >= 0; 
--length) {
                 sb=fullString.substr(offset,length);
                 str=fullReference.substr(offset,length);
                 performEqualityTest();
             }

Reply via email to