CUtlString CUtlString::Replace( const char *pszFrom, const char *pszTo ) const { Assert( pszTo ); // Can be 0 length, but not null Assert( pszFrom && *pszFrom ); // Must be valid and have one character. const char *pos = V_strstr( String(), pszFrom ); if ( !pos ) { return *this; } const char *pFirstFound = pos; // count number of search string int nSearchCount = 0; int nSearchLength = V_strlen( pszFrom ); while ( pos ) { nSearchCount++; int nSrcOffset = ( pos - String() ) + nSearchLength; pos = V_strstr( String() + nSrcOffset, pszFrom ); } // allocate the new string int nReplaceLength = V_strlen( pszTo ); int nAllocOffset = nSearchCount * ( nReplaceLength - nSearchLength ); size_t srcLength = Length(); CUtlString strDest; size_t destLength = srcLength + nAllocOffset; strDest.SetLength( destLength ); // find and replace the search string pos = pFirstFound; int nDestOffset = 0; int nSrcOffset = 0; while ( pos ) { // Found an instance int nCurrentSearchOffset = pos - String(); int nCopyLength = nCurrentSearchOffset - nSrcOffset; V_strncpy( strDest.GetForModify() + nDestOffset, String() + nSrcOffset, nCopyLength + 1 ); nDestOffset += nCopyLength; V_strncpy( strDest.GetForModify() + nDestOffset, pszTo, nReplaceLength + 1 ); nDestOffset += nReplaceLength; nSrcOffset = nCurrentSearchOffset + nSearchLength; pos = V_strstr( String() + nSrcOffset, pszFrom ); } // making sure that the left over string from the source is the same size as the left over dest buffer Assert( destLength - nDestOffset == srcLength - nSrcOffset ); if ( destLength - nDestOffset > 0 ) { V_strncpy( strDest.GetForModify() + nDestOffset, String() + nSrcOffset, destLength - nDestOffset + 1 ); } return strDest; }