X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c801d85f158c4cba50b588807daabdcbd0ed3853..b4c05cda99b0fcde1a00e48e35699d381c32c424:/src/common/string.cpp diff --git a/src/common/string.cpp b/src/common/string.cpp index 611b5969de..3031ae6daf 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -61,8 +61,6 @@ static int g_strEmpty[] = { -1, // ref count (locked) 0, // current length 0, // allocated memory 0 }; // string data -// empty string shares memory with g_strEmpty -static wxStringData *g_strNul = (wxStringData*)&g_strEmpty; // empty C style string: points to 'string data' byte of g_strEmpty extern const char *g_szNul = (const char *)(&g_strEmpty[3]); @@ -153,7 +151,7 @@ wxString::wxString(char ch, size_t nLength) if ( nLength > 0 ) { AllocBuffer(nLength); - + wxASSERT( sizeof(char) == 1 ); // can't use memset if not memset(m_pchData, ch, nLength); @@ -193,9 +191,11 @@ wxString::wxString(const unsigned char* psz, size_t nLength) #ifdef STD_STRING_COMPATIBILITY // ctor from a substring -wxString::wxString(const wxString& s, size_t nPos, size_t nLen) +wxString::wxString(const wxString& str, size_t nPos, size_t nLen) { - InitWith(s.c_str(), nPos, nLen == npos ? 0 : nLen); + wxASSERT( str.GetStringData()->IsValid() ); + + InitWith(str.c_str(), nPos, nLen == npos ? 0 : nLen); } // poor man's iterators are "void *" pointers @@ -282,23 +282,34 @@ void wxString::AllocBeforeWrite(size_t nLen) wxASSERT( nLen != 0 ); // doesn't make any sense // must not share string and must have enough space - register wxStringData* pData = GetStringData(); + register wxStringData* pData = GetStringData(); if ( pData->IsShared() || (nLen > pData->nAllocLength) ) { // can't work with old buffer, get new one pData->Unlock(); AllocBuffer(nLen); } - wxASSERT( !pData->IsShared() ); // we must be the only owner + wxASSERT( !GetStringData()->IsShared() ); // we must be the only owner } // get the pointer to writable buffer of (at least) nLen bytes -char *wxString::GetWriteBuf(size_t nLen) +char *wxString::GetWriteBuf(int nLen) { AllocBeforeWrite(nLen); + + wxASSERT( GetStringData()->nRefs == 1 ); + GetStringData()->Validate(FALSE); + return m_pchData; } +// put string back in a reasonable state after GetWriteBuf +void wxString::UngetWriteBuf() +{ + GetStringData()->nDataLength = strlen(m_pchData); + GetStringData()->Validate(TRUE); +} + // dtor frees memory if no other strings use it wxString::~wxString() { @@ -332,6 +343,8 @@ void wxString::AssignCopy(size_t nSrcLen, const char *pszSrcData) // assigns one string to another wxString& wxString::operator=(const wxString& stringSrc) { + wxASSERT( stringSrc.GetStringData()->IsValid() ); + // don't copy string over itself if ( m_pchData != stringSrc.m_pchData ) { if ( stringSrc.GetStringData()->IsEmpty() ) { @@ -429,6 +442,8 @@ void wxString::ConcatSelf(int nSrcLen, const char *pszSrcData) void wxString::operator+=(const wxString& string) { + wxASSERT( string.GetStringData()->IsValid() ); + ConcatSelf(string.Len(), string); } @@ -448,6 +463,8 @@ void wxString::operator+=(char ch) wxString& wxString::operator<<(const wxString& string) { + wxASSERT( string.GetStringData()->IsValid() ); + ConcatSelf(string.Len(), string); return *this; } @@ -473,6 +490,9 @@ wxString& wxString::operator<<(char ch) wxString operator+(const wxString& string1, const wxString& string2) { + wxASSERT( string1.GetStringData()->IsValid() ); + wxASSERT( string2.GetStringData()->IsValid() ); + wxString s; s.ConcatCopy(string1.GetStringData()->nDataLength, string1.m_pchData, string2.GetStringData()->nDataLength, string2.m_pchData); @@ -481,6 +501,8 @@ wxString operator+(const wxString& string1, const wxString& string2) wxString operator+(const wxString& string1, char ch) { + wxASSERT( string1.GetStringData()->IsValid() ); + wxString s; s.ConcatCopy(string1.GetStringData()->nDataLength, string1.m_pchData, 1, &ch); return s; @@ -488,6 +510,8 @@ wxString operator+(const wxString& string1, char ch) wxString operator+(char ch, const wxString& string) { + wxASSERT( string.GetStringData()->IsValid() ); + wxString s; s.ConcatCopy(1, &ch, string.GetStringData()->nDataLength, string.m_pchData); return s; @@ -495,6 +519,8 @@ wxString operator+(char ch, const wxString& string) wxString operator+(const wxString& string, const char *psz) { + wxASSERT( string.GetStringData()->IsValid() ); + wxString s; s.ConcatCopy(string.GetStringData()->nDataLength, string.m_pchData, Strlen(psz), psz); @@ -503,6 +529,8 @@ wxString operator+(const wxString& string, const char *psz) wxString operator+(const char *psz, const wxString& string) { + wxASSERT( string.GetStringData()->IsValid() ); + wxString s; s.ConcatCopy(Strlen(psz), psz, string.GetStringData()->nDataLength, string.m_pchData); @@ -569,7 +597,7 @@ wxString wxString::Right(char ch) const if ( iPos == NOT_FOUND ) str = *this; else - str = c_str() + iPos; + str = c_str() + iPos + 1; return str; } @@ -603,7 +631,7 @@ wxString wxString::Before(char ch) const wxString str; int iPos = Find(ch, TRUE); if ( iPos != NOT_FOUND && iPos != 0 ) - str = wxString(c_str(), iPos - 1); + str = wxString(c_str(), iPos); return str; } @@ -862,6 +890,92 @@ int wxString::PrintfV(const char* pszFormat, va_list argptr) return iLen; } +#if 0 +int wxString::Scanf(const char *pszFormat, ...) const +{ + va_list argptr; + va_start(argptr, pszFormat); + + int iLen = ScanfV(pszFormat, argptr); + + va_end(argptr); + + return iLen; +} + +int wxString::ScanfV(const char *pszFormat, va_list argptr) const +{ +#ifdef __WXMSW__ + wxMessageBox("ScanfV not implemented"); + return 0; +#else + return vsscanf(c_str(), pszFormat, argptr); +#endif +} +#endif + +// ---------------------------------------------------------------------------- +// misc other operations +// ---------------------------------------------------------------------------- +bool wxString::Matches(const char *pszMask) const +{ + // check char by char + const char *pszTxt; + for ( pszTxt = c_str(); *pszMask != '\0'; pszMask++, pszTxt++ ) { + switch ( *pszMask ) { + case '?': + if ( *pszTxt == '\0' ) + return FALSE; + + pszTxt++; + pszMask++; + break; + + case '*': + { + // ignore special chars immediately following this one + while ( *pszMask == '*' || *pszMask == '?' ) + pszMask++; + + // if there is nothing more, match + if ( *pszMask == '\0' ) + return TRUE; + + // are there any other metacharacters in the mask? + uint uiLenMask; + const char *pEndMask = strpbrk(pszMask, "*?"); + + if ( pEndMask != NULL ) { + // we have to match the string between two metachars + uiLenMask = pEndMask - pszMask; + } + else { + // we have to match the remainder of the string + uiLenMask = strlen(pszMask); + } + + wxString strToMatch(pszMask, uiLenMask); + const char* pMatch = strstr(pszTxt, strToMatch); + if ( pMatch == NULL ) + return FALSE; + + // -1 to compensate "++" in the loop + pszTxt = pMatch + uiLenMask - 1; + pszMask += uiLenMask - 1; + } + break; + + default: + if ( *pszMask != *pszTxt ) + return FALSE; + break; + } + } + + // match only if nothing left + return *pszTxt == '\0'; +} + // --------------------------------------------------------------------------- // standard C++ library string functions // --------------------------------------------------------------------------- @@ -869,13 +983,15 @@ int wxString::PrintfV(const char* pszFormat, va_list argptr) wxString& wxString::insert(size_t nPos, const wxString& str) { + wxASSERT( str.GetStringData()->IsValid() ); wxASSERT( nPos <= Len() ); wxString strTmp; - char *pc = strTmp.GetWriteBuf(Len() + str.Len() + 1); + char *pc = strTmp.GetWriteBuf(Len() + str.Len()); strncpy(pc, c_str(), nPos); strcpy(pc + nPos, str); strcpy(pc + nPos + str.Len(), c_str() + nPos); + strTmp.UngetWriteBuf(); *this = strTmp; return *this; @@ -883,6 +999,7 @@ wxString& wxString::insert(size_t nPos, const wxString& str) size_t wxString::find(const wxString& str, size_t nStart) const { + wxASSERT( str.GetStringData()->IsValid() ); wxASSERT( nStart <= Len() ); const char *p = strstr(c_str() + nStart, str); @@ -890,10 +1007,13 @@ size_t wxString::find(const wxString& str, size_t nStart) const return p == NULL ? npos : p - c_str(); } +// VC++ 1.5 can't cope with the default argument in the header. +#if ! (defined(_MSC_VER) && !defined(__WIN32__)) size_t wxString::find(const char* sz, size_t nStart, size_t n) const { return find(wxString(sz, n == npos ? 0 : n), nStart); } +#endif size_t wxString::find(char ch, size_t nStart) const { @@ -906,6 +1026,7 @@ size_t wxString::find(char ch, size_t nStart) const size_t wxString::rfind(const wxString& str, size_t nStart) const { + wxASSERT( str.GetStringData()->IsValid() ); wxASSERT( nStart <= Len() ); // # could be quicker than that @@ -919,6 +1040,8 @@ size_t wxString::rfind(const wxString& str, size_t nStart) const return npos; } +// VC++ 1.5 can't cope with the default argument in the header. +#if ! (defined(_MSC_VER) && !defined(__WIN32__)) size_t wxString::rfind(const char* sz, size_t nStart, size_t n) const { return rfind(wxString(sz, n == npos ? 0 : n), nStart); @@ -932,6 +1055,7 @@ size_t wxString::rfind(char ch, size_t nStart) const return p == NULL ? npos : p - c_str(); } +#endif wxString wxString::substr(size_t nStart, size_t nLen) const { @@ -977,7 +1101,7 @@ wxString& wxString::replace(size_t nStart, size_t nLen, size_t nCount, char ch) } wxString& wxString::replace(size_t nStart, size_t nLen, - const wxString& str, size_t nStart2, size_t nLen2) + const wxString& str, size_t nStart2, size_t nLen2) { return replace(nStart, nLen, str.substr(nStart2, nLen2)); } @@ -1126,7 +1250,7 @@ void wxArrayString::Alloc(size_t nSize) // searches the array for an item (forward or backwards) -// Robert Roebling (changed to bool from Bool) +// Robert Roebling (changed to bool from bool) int wxArrayString::Index(const char *sz, bool bCase, bool bFromEnd) const { @@ -1151,27 +1275,31 @@ int wxArrayString::Index(const char *sz, bool bCase, bool bFromEnd) const } // add item at the end -void wxArrayString::Add(const wxString& src) +void wxArrayString::Add(const wxString& str) { + wxASSERT( str.GetStringData()->IsValid() ); + Grow(); // the string data must not be deleted! - src.GetStringData()->Lock(); - m_pItems[m_nCount++] = (char *)src.c_str(); + str.GetStringData()->Lock(); + m_pItems[m_nCount++] = (char *)str.c_str(); } // add item at the given position -void wxArrayString::Insert(const wxString& src, size_t nIndex) +void wxArrayString::Insert(const wxString& str, size_t nIndex) { - wxCHECK( nIndex <= m_nCount ); + wxASSERT( str.GetStringData()->IsValid() ); + + wxCHECK_RET( nIndex <= m_nCount, "bad index in wxArrayString::Insert" ); Grow(); memmove(&m_pItems[nIndex + 1], &m_pItems[nIndex], (m_nCount - nIndex)*sizeof(char *)); - src.GetStringData()->Lock(); - m_pItems[nIndex] = (char *)src.c_str(); + str.GetStringData()->Lock(); + m_pItems[nIndex] = (char *)str.c_str(); m_nCount++; } @@ -1179,7 +1307,7 @@ void wxArrayString::Insert(const wxString& src, size_t nIndex) // removes item from array (by index) void wxArrayString::Remove(size_t nIndex) { - wxCHECK( nIndex <= m_nCount ); + wxCHECK_RET( nIndex <= m_nCount, "bad index in wxArrayString::Remove" ); // release our lock Item(nIndex).GetStringData()->Unlock(); @@ -1194,15 +1322,14 @@ void wxArrayString::Remove(const char *sz) { int iIndex = Index(sz); - wxCHECK( iIndex != NOT_FOUND ); + wxCHECK_RET( iIndex != NOT_FOUND, + "removing inexistent element in wxArrayString::Remove" ); Remove((size_t)iIndex); } // sort array elements using passed comparaison function -// Robert Roebling (changed to bool from Bool) - void wxArrayString::Sort(bool bCase, bool bReverse) { //@@@@ TO DO