]> git.saurik.com Git - wxWidgets.git/commitdiff
Corrected statements about wxString correctly handling
authorMattia Barbon <mbarbon@cpan.org>
Mon, 1 Sep 2003 20:20:21 +0000 (20:20 +0000)
committerMattia Barbon <mbarbon@cpan.org>
Mon, 1 Sep 2003 20:20:21 +0000 (20:20 +0000)
embedded '\0' characters.
  Fixed various wxString::*find* methods (patch by Robert Vazan),
plus added missing overloaded variants of find_first/last_(not_)of.
Added more tests in console sample.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23357 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/latex/wx/tstring.tex
docs/latex/wx/wxstring.tex
include/wx/string.h
samples/console/console.cpp
src/common/string.cpp

index dce111c7cbbc3fea3cfca1036ca5bb740c786c35..7449e617e271bf8bd88f1423ef558cb5e2624853 100644 (file)
@@ -6,8 +6,9 @@ Classes: \helpref{wxString}{wxstring}, \helpref{wxArrayString}{wxarraystring}, \
 
 wxString is a class which represents a character string of arbitrary length (limited by 
 {\it MAX\_INT} which is usually 2147483647 on 32 bit machines) and containing
-arbitrary characters. The ASCII NUL character is allowed, although care should be
-taken when passing strings containing it to other functions.
+arbitrary characters. The ASCII NUL character is allowed, but be aware that
+in the current string implementation some methods might not work correctly
+in this case.
 
 wxString works with both ASCII (traditional, 7 or 8 bit, characters) as well as
 Unicode (wide characters) strings.
index b81b11641294ba39970f71d8d8c0d6cb8ea19c51..9f242d2240afdb8c62c570e8beef566b259a6e01 100644 (file)
@@ -6,7 +6,7 @@ there, wxString implements about 90\% of methods of the std::string class (itera
 are not supported, nor all methods which use them).
 These standard functions are not documented in this manual so please see the STL documentation.
 The behaviour of all these functions is identical to the behaviour described
-there.
+there (except that wxString is sensitive to null character).
 
 You may notice that wxString sometimes has many functions which do the same
 thing like, for example, \helpref{Length()}{wxstringlength}, 
index d402585c46ee63c096b980705d663b1f75ddac4b..ee362ff90c40c5d3ba438aada51c4d20385e5c6a 100644 (file)
@@ -523,6 +523,7 @@ public:
     { return find_first_of(str.c_str(), nStart); }
     // same as above
   size_t find_first_of(const wxChar* sz, size_t nStart = 0) const;
+  size_t find_first_of(const wxChar* sz, size_t nStart, size_t n) const;
     // same as find(char, size_t)
   size_t find_first_of(wxChar c, size_t nStart = 0) const
     { return find(c, nStart); }
@@ -531,6 +532,7 @@ public:
     { return find_last_of(str.c_str(), nStart); }
     // same as above
   size_t find_last_of (const wxChar* sz, size_t nStart = npos) const;
+  size_t find_last_of(const wxChar* sz, size_t nStart, size_t n) const;
     // same as above
   size_t find_last_of(wxChar c, size_t nStart = npos) const
     { return rfind(c, nStart); }
@@ -542,13 +544,15 @@ public:
     { return find_first_not_of(str.c_str(), nStart); }
     // same as above
   size_t find_first_not_of(const wxChar* sz, size_t nStart = 0) const;
+  size_t find_first_not_of(const wxChar* sz, size_t nStart, size_t n) const;
     // same as above
   size_t find_first_not_of(wxChar ch, size_t nStart = 0) const;
     //  as strcspn()
   size_t find_last_not_of(const wxStringBase& str, size_t nStart = npos) const
-    { return find_first_not_of(str.c_str(), nStart); }
+    { return find_last_not_of(str.c_str(), nStart); }
     // same as above
   size_t find_last_not_of(const wxChar* sz, size_t nStart = npos) const;
+  size_t find_last_not_of(const wxChar* sz, size_t nStart, size_t n) const;
     // same as above
   size_t find_last_not_of(wxChar ch, size_t nStart = npos) const;
 
index 417daefcd47fc94342cc3b6edaa9e40d00f1a079..4f7d0d45193c51b085267a119e725d14c03a1382 100644 (file)
@@ -97,7 +97,7 @@
     #undef TEST_ALL
     static const bool TEST_ALL = true;
 #else
-    #define TEST_HASHSET
+    #define TEST_STRINGS
 
     static const bool TEST_ALL = false;
 #endif
@@ -6551,6 +6551,20 @@ void is(int line, const wxString& got, const wxString& expected,
     }
 }
 
+#if 0
+void is(int line, const wxChar* got, const wxChar* expected,
+        const wxString& msg = wxEmptyString)
+{
+    bool isOk = wxStrcmp( got, expected ) == 0;
+    ok(line, isOk, msg);
+    if( !isOk )
+    {
+        wxPuts(_T("Got: ") + wxString(got));
+        wxPuts(_T("Expected: ") + wxString(expected));
+    }
+}
+#endif
+
 void is(int line, const wxChar& got, const wxChar& expected,
         const wxString& msg = wxEmptyString)
 {
@@ -6558,11 +6572,26 @@ void is(int line, const wxChar& got, const wxChar& expected,
     ok(line, isOk, msg);
     if( !isOk )
     {
-        wxPuts("Got: " + got);
-        wxPuts("Expected: " + expected);
+        wxPuts(_T("Got: ") + got);
+        wxPuts(_T("Expected: ") + expected);
+    }
+}
+
+void is(int line, size_t got, size_t expected,
+        const wxString& msg = wxEmptyString)
+{
+    bool isOk = got == expected;
+    ok(line, isOk, msg);
+    if( !isOk )
+    {
+        wxPuts(wxString::Format(_T("Got: %ld"), got));
+        wxPuts(wxString::Format(_T("Expected: %ld"), expected));
     }
 }
 
+#define is_m( got, expected, message ) is( __LINE__, (got), (expected), (message) )
+#define is_nom( got, expected ) is( __LINE__, (got), (expected), wxEmptyString )
+
 void TestStdString()
 {
     wxPuts(_T("*** Testing std::string operations ***\n"));
@@ -6652,6 +6681,77 @@ void TestStdString()
     is( __LINE__, *it2, _T('g') );
     ok( __LINE__, it3 == s7.end() );
 
+    // find
+    //       0         1         2
+    //       01234567890123456789012345
+    s1 = _T("abcdefgABCDEFGabcABCabcABC");
+    s2 = _T("gAB");
+
+    is_nom( s1.find(_T('A')), 7u );
+    is_nom( s1.find(_T('A'), 7), 7u );
+    is_nom( s1.find(_T('Z')), wxString::npos );
+    is_nom( s1.find(_T('C'), 22), 25u );
+
+    is_nom( s1.find(_T("gAB")), 6u );
+    is_nom( s1.find(_T("gAB"), 7), wxString::npos );
+    is_nom( s1.find(_T("gAB"), 6), 6u );
+
+    is_nom( s1.find(_T("gABZZZ"), 2, 3), 6u );
+    is_nom( s1.find(_T("gABZZZ"), 7, 3), wxString::npos );
+
+    is_nom( s1.find(s2), 6u );
+    is_nom( s1.find(s2, 7), wxString::npos );
+    is_nom( s1.find(s2, 6), 6u );
+
+    // find_first_not_of
+    //       0         1         2         3
+    //       01234567890123456789012345678901234
+    s1 = _T("aaaaaabcdefghlkjiaaaaaabcdbcdbcdbcd");
+    s2 = _T("aaaaaa");
+
+    is_nom( s1.find_first_not_of(_T('a')), 6u );
+    is_nom( s1.find_first_not_of(_T('a'), 7), 7u );
+    is_nom( s2.find_first_not_of(_T('a')), wxString::npos );
+
+    is_nom( s1.find_first_not_of(_T("abde"), 4), 7u );
+    is_nom( s1.find_first_not_of(_T("abde"), 7), 7u );
+    is_nom( s1.find_first_not_of(_T("abcdefghijkl")), wxString::npos );
+
+    is_nom( s1.find_first_not_of(_T("abcdefghi"), 0, 4), 9u );
+
+    // find_first_of
+    is_nom( s1.find_first_of(_T('c')), 7u );
+    is_nom( s1.find_first_of(_T('v')), wxString::npos );
+    is_nom( s1.find_first_of(_T('c'), 10), 24u );
+
+    is_nom( s1.find_first_of(_T("ijkl")), 13u );
+    is_nom( s1.find_first_of(_T("ddcfg"), 17), 24u );
+    is_nom( s1.find_first_of(_T("ddcfga"), 17, 5), 24u );
+
+    // find_last_not_of
+    //       0         1         2         3
+    //       01234567890123456789012345678901234
+    s1 = _T("aaaaaabcdefghlkjiaaaaaabcdbcdbcdbcd");
+    s2 = _T("aaaaaa");
+
+    is_nom( s2.find_last_not_of(_T('a')), wxString::npos );
+    is_nom( s1.find_last_not_of(_T('d')), 33u );
+    is_nom( s1.find_last_not_of(_T('d'), 25), 24u );
+
+    is_nom( s1.find_last_not_of(_T("bcd")), 22u );
+    is_nom( s1.find_last_not_of(_T("abc"), 24), 16u );
+
+    is_nom( s1.find_last_not_of(_T("abcdefghijklmnopqrstuv"), 24, 3), 16u );
+
+    // find_last_of
+    is_nom( s2.find_last_of(_T('c')), wxString::npos );
+    is_nom( s1.find_last_of(_T('a')), 22u );
+    is_nom( s1.find_last_of(_T('b'), 24), 23u );
+
+    is_nom( s1.find_last_of(_T("ijklm")), 16u );
+    is_nom( s1.find_last_of(_T("ijklma"), 33, 4), 16u );
+    is_nom( s1.find_last_of(_T("a"), 17), 17u );
+
     // test insert
     s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = _T("aaaa");
     s9 = s10 = _T("cdefg");
@@ -6702,6 +6802,49 @@ void TestStdString()
     is( __LINE__, s6, s9);
     is( __LINE__, s7, _T("QWwertyP") );
 
+    // rfind
+    //       0         1         2
+    //       01234567890123456789012345
+    s1 = _T("abcdefgABCDEFGabcABCabcABC");
+    s2 = _T("gAB");
+
+    is_nom( s1.rfind(_T('A')), 23u );
+    is_nom( s1.rfind(_T('A'), 7), 7u );
+    is_nom( s1.rfind(_T('Z')), wxString::npos );
+    is_nom( s1.rfind(_T('C'), 22), 19u );
+
+    is_nom( s1.rfind(_T("cAB")), 22u );
+    is_nom( s1.rfind(_T("cAB"), 15), wxString::npos );
+    is_nom( s1.rfind(_T("cAB"), 21), 16u );
+
+    is_nom( s1.rfind(_T("gABZZZ"), 7, 3), 6u );
+    is_nom( s1.rfind(_T("gABZZZ"), 5, 3), wxString::npos );
+
+    is_nom( s1.rfind(s2), 6u );
+    is_nom( s1.rfind(s2, 5), wxString::npos );
+    is_nom( s1.rfind(s2, 6), 6u );
+
+    // resize
+    s1 = s2 = s3 = s4 = _T("abcABCdefDEF");
+
+    s1.resize( 12 );
+    s2.resize( 10 );
+    s3.resize( 14, _T(' ') );
+    s4.resize( 14, _T('W') );
+
+    is_nom( s1, _T("abcABCdefDEF") );
+    is_nom( s2, _T("abcABCdefD") );
+    is_nom( s3, _T("abcABCdefDEF  ") );
+    is_nom( s4, _T("abcABCdefDEFWW") );
+
+    // substr
+    s1 = _T("abcdefgABCDEFG");
+
+    is_nom( s1.substr( 0, 14 ), s1 );
+    is_nom( s1.substr( 1, 13 ), _T("bcdefgABCDEFG") );
+    is_nom( s1.substr( 1, 20 ), _T("bcdefgABCDEFG") );
+    is_nom( s1.substr( 14, 30 ), _T("") );
+
     wxPuts(_T("*** Testing std::string operations finished ***\n"));
 }
 
index 4715f63154ab66df9062db9eb1c4bb892957d3db..76a89a88a32411a27e15adebda85d8da600d8360 100644 (file)
@@ -479,18 +479,36 @@ size_t wxStringBase::find(wxChar ch, size_t nStart) const
 
 size_t wxStringBase::rfind(const wxStringBase& str, size_t nStart) const
 {
-  wxASSERT( str.GetStringData()->IsValid() );
-  wxASSERT( nStart == npos || nStart <= length() );
-
-  // TODO could be made much quicker than that
-  const wxChar *p = c_str() + (nStart == npos ? length() : nStart);
-  while ( p >= c_str() + str.length() ) {
-    if ( wxStrncmp(p - str.length(), str.c_str(), str.length()) == 0 )
-      return p - str.length() - c_str();
-    p--;
-  }
+    wxASSERT( str.GetStringData()->IsValid() );
+    wxASSERT( nStart == npos || nStart <= length() );
+
+    if ( length() >= str.length() )
+    {
+        // avoids a corner case later
+        if ( length() == 0 && str.length() == 0 )
+            return 0;
+
+        // "top" is the point where search starts from
+        size_t top = length() - str.length();
 
-  return npos;
+        if ( nStart == npos )
+            nStart = length() - 1;
+        if ( nStart < top )
+            top = nStart;
+
+        const wxChar *cursor = c_str() + top;
+        do
+        {
+            if ( memcmp(cursor, str.c_str(),
+                        str.length() * sizeof(wxChar)) == 0 )
+            {
+                return cursor - c_str();
+            }
+            --cursor;
+        } while ( cursor > c_str() );
+    }
+    
+    return npos;
 }
 
 size_t wxStringBase::rfind(const wxChar* sz, size_t nStart, size_t n) const
@@ -530,11 +548,17 @@ size_t wxStringBase::find_first_of(const wxChar* sz, size_t nStart) const
         return npos;
 }
 
+size_t wxStringBase::find_first_of(const wxChar* sz, size_t nStart,
+                                   size_t n) const
+{
+    return find_first_of(wxStringBase(sz, n), nStart);
+}
+
 size_t wxStringBase::find_last_of(const wxChar* sz, size_t nStart) const
 {
     if ( nStart == npos )
     {
-        nStart = length();
+        nStart = length() - 1;
     }
     else
     {
@@ -542,7 +566,7 @@ size_t wxStringBase::find_last_of(const wxChar* sz, size_t nStart) const
                         _T("invalid index in find_last_of()") );
     }
 
-    for ( const wxChar *p = c_str() + nStart - 1; p >= c_str(); p-- )
+    for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p )
     {
         if ( wxStrchr(sz, *p) )
             return p - c_str();
@@ -551,6 +575,12 @@ size_t wxStringBase::find_last_of(const wxChar* sz, size_t nStart) const
     return npos;
 }
 
+size_t wxStringBase::find_last_of(const wxChar* sz, size_t nStart,
+                                   size_t n) const
+{
+    return find_last_of(wxStringBase(sz, n), nStart);
+}
+
 size_t wxStringBase::find_first_not_of(const wxChar* sz, size_t nStart) const
 {
     if ( nStart == npos )
@@ -566,7 +596,13 @@ size_t wxStringBase::find_first_not_of(const wxChar* sz, size_t nStart) const
     if ( nAccept >= length() - nStart )
         return npos;
     else
-        return nAccept;
+        return nStart + nAccept;
+}
+
+size_t wxStringBase::find_first_not_of(const wxChar* sz, size_t nStart,
+                                       size_t n) const
+{
+    return find_first_not_of(wxStringBase(sz, n), nStart);
 }
 
 size_t wxStringBase::find_first_not_of(wxChar ch, size_t nStart) const
@@ -586,14 +622,14 @@ size_t wxStringBase::find_last_not_of(const wxChar* sz, size_t nStart) const
 {
     if ( nStart == npos )
     {
-        nStart = length();
+        nStart = length() - 1;
     }
     else
     {
         wxASSERT( nStart <= length() );
     }
 
-    for ( const wxChar *p = c_str() + nStart - 1; p >= c_str(); p-- )
+    for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p )
     {
         if ( !wxStrchr(sz, *p) )
             return p - c_str();
@@ -602,18 +638,24 @@ size_t wxStringBase::find_last_not_of(const wxChar* sz, size_t nStart) const
     return npos;
 }
 
+size_t wxStringBase::find_last_not_of(const wxChar* sz, size_t nStart,
+                                      size_t n) const
+{
+    return find_last_not_of(wxStringBase(sz, n), nStart);
+}
+
 size_t wxStringBase::find_last_not_of(wxChar ch, size_t nStart) const
 {
     if ( nStart == npos )
     {
-        nStart = length();
+        nStart = length() - 1;
     }
     else
     {
         wxASSERT( nStart <= length() );
     }
 
-    for ( const wxChar *p = c_str() + nStart - 1; p >= c_str(); p-- )
+    for ( const wxChar *p = c_str() + nStart; p >= c_str(); --p )
     {
         if ( *p != ch )
             return p - c_str();
@@ -2172,6 +2214,13 @@ void wxArrayString::Remove(const wxChar *sz)
   RemoveAt(iIndex);
 }
 
+void wxArrayString::assign(const_iterator first, const_iterator last)
+{
+    reserve(last - first);
+    for(; first != last; ++first)
+        push_back(*first);
+}
+
 // ----------------------------------------------------------------------------
 // sorting
 // ----------------------------------------------------------------------------