/* "Spam Filter"-Plugin for Miranda IM Copyright 2003-2006 Heiko Herkenrath This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program ("SpamFilter-License.txt"); if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // -- Includes #include "common.h" // ----------------------------------------- /* int SubStringExistsInStringCount(const TCHAR* pszStr, const TCHAR* pszSubString, BOOL bCaseSensitive) { int iSubStrLen; char* pszOcc; int iReturn; if (!pszSubString) return 0; pszOcc = pszStr; iCount = 0; iSubStrLen = lstrlen(pszSubString); while ((pszOcc = bCaseSensitive?StrStr(pszOcc, pszOldSubStr):StrStrI(pszOcc, pszOldSubStr)) != NULL) { iCount++; pszOcc = pszOcc+iSubStrLen; } return iCount; } */ WCHAR* RemoveSubStr(WCHAR* pszStr, int iPos, int iSubStrLen) { if (!pszStr) return NULL; if ((iPos > 0) && (iSubStrLen > 0) && (iPos < lstrlen(pszStr))) MoveMemory(&pszStr[iPos], &pszStr[iPos+iSubStrLen], (lstrlen(&pszStr[iPos])+1)*sizeof(WCHAR)); return pszStr; } /* BOOL HasSubStr(const TCHAR* pszStr, int iPos, const TCHAR* pszSubStr); { TCHAR* pszPos; if (!pszSubStr || !pszStr || (iPos >= lstrlen(pszStr))) return FALSE; // Test for suffix if (iPos < 0) return ((lstrlen(pszStr) <= lstrlen(pszSubStr)) || (StrCmp(pszStr+lstrlen(pszStr)-lstrlen(pszSubStr), pszSubStr) != 0)); else return (StrCmpN(&pszStr[iPos], pszSubStr, lstrlen(pszSubStr)) != 0)) } */ WCHAR* InsertSubStr(WCHAR* pszStr, int cchMaxSize, int iPos, const WCHAR* pszSubStr) { int iSubStrLen; if (!pszStr) return NULL; if (!pszSubStr || (iPos < 0) || (iPos >= lstrlen(pszStr))) return pszStr; iSubStrLen = lstrlen(pszSubStr); if ((cchMaxSize > 0) && ((iSubStrLen+lstrlen(pszStr)+1) > cchMaxSize)) return pszStr; MoveMemory(&pszStr[iPos+iSubStrLen], &pszStr[iPos], (lstrlen(&pszStr[iPos])+1)*sizeof(WCHAR)); CopyMemory(&pszStr[iPos], pszSubStr, iSubStrLen*sizeof(WCHAR)); // no terminating zero return pszStr; } WCHAR* ReplaceSubStringWithString(const WCHAR* pszStr, const WCHAR* pszOldSubStr, const WCHAR* pszNewSubStr, BOOL bCaseSensitive, BOOL bAlsoSearchNewString, BOOL* pbSthReplaced) { // returned TCHAR* needs to be mir_free()'d // returns NULL on error int iOldSubStrLen, iNewSubStrLen; int iPos; WCHAR* pszOcc; WCHAR* pszReturn; WCHAR* pszReturnBuf; if (pbSthReplaced) *pbSthReplaced = FALSE; if (!pszStr) return NULL; if (!pszOldSubStr) { *pbSthReplaced = TRUE; return mir_wstrdup(pszStr); } iOldSubStrLen = (int)lstrlen(pszOldSubStr); iNewSubStrLen = pszNewSubStr?(int)lstrlen(pszNewSubStr):0; // Make sure that no infinite loop occurs (on str in new one) if (bAlsoSearchNewString && pszNewSubStr) if (bCaseSensitive?StrStr(pszNewSubStr, pszOldSubStr):StrStrI(pszNewSubStr, pszOldSubStr)) bAlsoSearchNewString = FALSE; pszReturn = mir_wstrdup(pszStr); if (!pszReturn) return NULL; pszOcc = pszReturn; while ((pszOcc = bCaseSensitive?StrStr(pszOcc, pszOldSubStr):StrStrI(pszOcc, pszOldSubStr)) != NULL) { // Reallocate more memory (memory block might get moved) if (iNewSubStrLen > iOldSubStrLen) { pszReturnBuf = pszReturn; pszReturn = (WCHAR*)mir_realloc(pszReturnBuf, (lstrlen(pszReturn)+iNewSubStrLen-iOldSubStrLen+1)*sizeof(WCHAR)); if (!pszReturn) { mir_free(pszReturnBuf); return NULL; } } iPos = pszOcc-pszReturn; RemoveSubStr(pszReturn, iPos, iOldSubStrLen); if (pszNewSubStr) InsertSubStr(pszReturn, 0, iPos, pszNewSubStr); // Get new start position for search if (!bAlsoSearchNewString) pszOcc = &pszReturn[iPos+iNewSubStrLen]; if (pbSthReplaced) *pbSthReplaced = TRUE; } // Correct memory allocation (if less needed) if (iNewSubStrLen < iOldSubStrLen) { pszReturnBuf = pszReturn; pszReturn = (WCHAR*)mir_realloc(pszReturnBuf, (lstrlen(pszReturn)+1)*sizeof(WCHAR)); if (!pszReturn) pszReturn = pszReturnBuf; } return pszReturn; } BOOL ReplaceSubStringWithStringBuf(WCHAR* pszStr, int cchMaxSize, const WCHAR* pszOldSubStr, const WCHAR* pszNewSubStr, BOOL bCaseSensitive, BOOL bAlsoSearchNewString) { int iOldSubStrLen, iNewSubStrLen; int iPos; WCHAR* pszOcc; BOOL bSthReplaced; if (!pszStr) return FALSE; if (!pszOldSubStr || (cchMaxSize <= 0)) return TRUE; iOldSubStrLen = (int)lstrlen(pszOldSubStr); iNewSubStrLen = pszNewSubStr?(int)lstrlen(pszNewSubStr):0; // Make sure that no infinite loop occurs (on str in new one) if (bAlsoSearchNewString && pszNewSubStr) if (bCaseSensitive?StrStr(pszNewSubStr, pszOldSubStr):StrStrI(pszNewSubStr, pszOldSubStr)) bAlsoSearchNewString = FALSE; pszOcc = pszStr; bSthReplaced = FALSE; while ((pszOcc = bCaseSensitive?StrStr(pszOcc, pszOldSubStr):StrStrI(pszOcc, pszOldSubStr)) != NULL) { if (cchMaxSize < lstrlen(pszStr)+iNewSubStrLen-iOldSubStrLen+1); break; iPos = pszOcc-pszStr; RemoveSubStr(pszStr, iPos, iOldSubStrLen); if (pszNewSubStr) InsertSubStr(pszStr, 0, iPos, pszNewSubStr); // Get new start position for search if (!bAlsoSearchNewString) pszOcc = &pszStr[iPos+iNewSubStrLen]; bSthReplaced = TRUE; } return bSthReplaced; } WCHAR* ReplaceSubStringWithStringMultiple(const WCHAR* pszStr, STRINGLIST* pslFromTo, BOOL bCaseSensitive, BOOL bAlsoSearchNewString, BOOL* pbSthReplaced) { WCHAR* pszReplaced; WCHAR* pszStrBuf; int i; BOOL bSthReplacedBuf; if (pbSthReplaced) *pbSthReplaced = FALSE; if (!pszStr) return NULL; pszStrBuf = mir_wstrdup(pszStr); if (pszStrBuf && pslFromTo) for (i=SL_MIN_POS; i 0) for (i=0; i