- Added wxLog::Log().
- Added wxProtocolLog and use it in wxFTP.
- Added wxXmlResource::GetResourceNode().
+- Optimize wxString::Replace() to use an O(N) algorithm (Kuang-che Wu).
All (Unix):
#include <stdlib.h>
#include "wx/hashmap.h"
+#include "wx/vector.h"
// string handling functions used by wxString:
#if wxUSE_UNICODE_UTF8
break;
}
}
- else // general case
+ else if ( !bReplaceAll)
+ {
+ size_t pos = m_impl.find(strOld, 0);
+ if ( pos != npos )
+ {
+ m_impl.replace(pos, strOld.m_impl.length(), strNew.m_impl);
+ uiCount = 1;
+ }
+ }
+ else // replace all occurrences
{
const size_t uiOldLen = strOld.m_impl.length();
const size_t uiNewLen = strNew.m_impl.length();
- for ( size_t pos = 0; ; )
+ // first scan the string to find all positions at which the replacement
+ // should be made
+ wxVector<size_t> replacePositions;
+
+ size_t pos;
+ for ( pos = m_impl.find(strOld.m_impl, 0);
+ pos != npos;
+ pos = m_impl.find(strOld.m_impl, pos + uiOldLen))
{
- pos = m_impl.find(strOld.m_impl, pos);
- if ( pos == npos )
- break;
+ replacePositions.push_back(pos);
+ ++uiCount;
+ }
- // replace this occurrence of the old string with the new one
- m_impl.replace(pos, uiOldLen, strNew.m_impl);
+ if ( !uiCount )
+ return 0;
- // move up pos past the string that was replaced
- pos += uiNewLen;
+ // allocate enough memory for the whole new string
+ wxString tmp;
+ tmp.m_impl.reserve(m_impl.length() + uiCount*(uiNewLen - uiOldLen));
- // increase replace count
- uiCount++;
+ // copy this string to tmp doing replacements on the fly
+ size_t replNum = 0;
+ for ( pos = 0; replNum < uiCount; replNum++ )
+ {
+ const size_t nextReplPos = replacePositions[replNum];
- // stop after the first one?
- if ( !bReplaceAll )
- break;
+ if ( pos != nextReplPos )
+ {
+ tmp.m_impl.append(m_impl, pos, nextReplPos - pos);
+ }
+
+ tmp.m_impl.append(strNew.m_impl);
+ pos = nextReplPos + uiOldLen;
}
+
+ if ( pos != m_impl.length() )
+ {
+ // append the rest of the string unchanged
+ tmp.m_impl.append(m_impl, pos, m_impl.length() - pos);
+ }
+
+ swap(tmp);
}
return uiCount;
return str.Replace("x", "y") != 0;
}
+BENCHMARK_FUNC(ReplaceLonger)
+{
+ wxString str('x', ASCIISTR_LEN);
+ return str.Replace("x", "yy") != 0;
+}
+
+BENCHMARK_FUNC(ReplaceShorter)
+{
+ wxString str('x', ASCIISTR_LEN);
+ return str.Replace("xx", "y") != 0;
+}
+
// ----------------------------------------------------------------------------
// string buffers: wx[W]CharBuffer
{ \
wxString s(o,olen); \
s.replace( pos , len , replacement ); \
- CPPUNIT_ASSERT( s == wxString(r,rlen) ); \
+ CPPUNIT_ASSERT_EQUAL( wxString(r,rlen), s ); \
}
TEST_NULLCHARREPLACE( _T("null\0char"), 9, 5, 1, _T("d"),
{ \
wxString s(o,olen); \
s.Replace( olds, news, all ); \
- CPPUNIT_ASSERT( s == wxString(r,rlen) ); \
+ CPPUNIT_ASSERT_EQUAL( wxString(r,rlen), s ); \
}
TEST_WXREPLACE( _T("null\0char"), 9, _T("c"), _T("de"), true,
_T("null\0char"), 9 );
TEST_WXREPLACE( "life", 4, "f", "", false, "lie", 3 );
+ TEST_WXREPLACE( "life", 4, "f", "", true, "lie", 3 );
+ TEST_WXREPLACE( "life", 4, "fe", "ve", true, "live", 4 );
+ TEST_WXREPLACE( "xx", 2, "x", "yy", true, "yyyy", 4 );
+ TEST_WXREPLACE( "xxx", 3, "xx", "z", true, "zx", 2 );
#undef TEST_WXREPLACE
#undef TEST_NULLCHARREPLACE