diff options
author | Gluzskiy Alexandr <sss123next@list.ru> | 2010-04-05 19:30:17 +0300 |
---|---|---|
committer | Gluzskiy Alexandr <sss123next@list.ru> | 2010-04-05 19:30:17 +0300 |
commit | d7730685516d6ed6fc278a6ea74f7a5cf12e0042 (patch) | |
tree | 41a381fbe4051ed4b9041f5596913b6c174cf9be /stringlist.c | |
parent | 7fd9fe181150f166a098eaf4e006f878c28cb770 (diff) |
dos2unixspamfilter
Diffstat (limited to 'stringlist.c')
-rw-r--r-- | stringlist.c | 2012 |
1 files changed, 1006 insertions, 1006 deletions
diff --git a/stringlist.c b/stringlist.c index e1d6de5..c7012e4 100644 --- a/stringlist.c +++ b/stringlist.c @@ -1,1007 +1,1007 @@ -/*
-
-"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"
-
-// -- Macros
-#define SLAlloc(s) mir_alloc(s)
-#define SLReAlloc(p, s) mir_realloc((p), (s))
-#define SLFree(p) mir_free(p)
-//#define SLAlloc(s) HeapAlloc(GetProcessHeap(), 0, (s))
-//#define SLReAlloc(p, s) HeapReAlloc(GetProcessHeap(), 0, (p), (s))
-//#define SLFree(p) HeapFree(GetProcessHeap(), 0, (p))
-
-
-// -----------------------------------------
-
-
-BOOL SLAssignToListBoxCtrl(LPSTRINGLIST psl, HWND hwndListBox)
-{
- BOOL bReturn = FALSE;
- int i;
-
- if (!psl || !hwndListBox) return FALSE;
- SendMessage(hwndListBox, LB_RESETCONTENT, 0, 0);
- SendMessage(hwndListBox, LB_INITSTORAGE, (WPARAM)psl->uCount, (LPARAM)(SLGetSize(psl, TRUE)*sizeof(WCHAR)));
- EnterCriticalSection(&psl->csListAccess);
- for (i=SL_MIN_POS; i<(int)psl->uCount; i++)
- if (SendMessage(hwndListBox, LB_ADDSTRING, 0, (LPARAM)psl->papszList[i]) >= 0)
- bReturn = TRUE;
- LeaveCriticalSection(&psl->csListAccess);
- return bReturn;
-}
-
-BOOL SLRetrieveFromListBoxCtrl(LPSTRINGLIST psl, HWND hwndListBox)
-{
- int iCount, i, iPos;
- BOOL bReturn;
-
- if (!psl || !hwndListBox) return FALSE;
- bReturn = FALSE;
- EnterCriticalSection(&psl->csListAccess);
- iCount = SendMessage(hwndListBox, LB_GETCOUNT, 0, 0);
- for (i=0; i<iCount; i++)
- {
- iPos = SLPrepareItem(psl, SendMessage(hwndListBox, LB_GETTEXTLEN, (WPARAM)i, 0));
- if (iPos != SL_INVALID_POS)
- {
- if (SendMessage(hwndListBox, LB_GETTEXT, (WPARAM)i, (LPARAM)psl->papszList[iPos]) != LB_ERR)
- bReturn = TRUE;
- else
- SLDeleteItem(psl, iPos);
- }
- }
- LeaveCriticalSection(&psl->csListAccess);
- return bReturn;
-}
-
-/*
-BOOL SLLoadFromIniFile(LPSTRINGLIST psl, const TCHAR* pszSearchPath, const TCHAR* pszSection, const TCHAR* pszSettingPrefix)
-{
- TCHAR szFile[MAX_PATH];
- BOOL bFileFound;
- BOOL bReturn = FALSE;
- int i, iLen, iSize;
- TCHAR* pszItem;
- TCHAR* pszBuf;
- WIN32_FIND_DATA wfd;
- HANDLE hFind;
-
- if (!psl || !pszSection || !pszSearchPath)
- return FALSE;
-
- ZeroMemory(&wfd, sizeof(wfd));
-
- EnterCriticalSection(&psl->csListAccess);
-
- // Enum all files in the directory
- hFind = FindFirstFile(pszSearchPath, &wfd);
- for (bFileFound=(hFind!=INVALID_HANDLE_VALUE); bFileFound; bFileFound=FindNextFile(hFind, &wfd))
- {
- if (wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
- continue;
-
- // Construct the file name
- mir_sntprintf(szFile, ARRAYSIZE(szFile), _T("%s"), pszSearchPath);
- PathRemoveFileSpec(szFile);
- PathAppend(szFile, wfd.cFileName);
-
- // Load the data from ini file
- iSize = (pszSettingPrefix?(lstrlen(pszSettingPrefix)+1):0)+MAX_INT_LENGTH+1);
- pszItem = (TCHAR*)mir_alloc(iSize*sizeof(TCHAR));
- if (!pszItem) continue;
-
- for (i=SL_MIN_POS;;i++) // no break condition
- {
- mir_sntprintf(pszItem, _T("%s%s%i"), iSize, pszSettingPrefix?pszSettingPrefix:_T(""), pszSettingPrefix?_T("|"):_T(""), i);
-
- iLen = GetPrivateProfileString(pszSection, pszItem, NULL, NULL, 0, szFile);
- if (iLen < 0) break;
-
- pszBuf = (TCHAR*)mir_alloc((iLen+1)*sizeof(TCHAR));
- if (!pszBuf) continue;
-
- GetPrivateProfileString(pszSection, pszItem, NULL, pszBuf, iLen, szFile);
- if (lstrlen(pszBuf) <= 0) break;
-
- if (SLAddItem(psl, pszBuf) != SL_INVALID_POS)
- if (!bReturn) bReturn = TRUE;
-
- mir_free(pszBuf);
- }
-
- mir_free(pszItem);
- }
-
- LeaveCriticalSection(&psl->csListAccess);
-
- if (hFind) FindClose(hFind);
-
- return bReturn;
-}
-
-
-
-BOOL SLSaveToIniFile(LPSTRINGLIST psl, const TCHAR* pszFileName, const TCHAR* pszSection, const TCHAR* pszSettingPrefix)
-{
- int i;
- char* pszItem;
- int iSize;
- BOOL bReturn = FALSE;
-
- if (!psl || !pszSection || !pszFileName)
- return FALSE;
-
- iSize = (pszSettingPrefix?(lstrlen(pszSettingPrefix)+1):0)+MAX_INT_LENGTH+1;
- pszItem = (TCHAR*)mir_alloc(iSize*sizeof(TCHAR));
-
- if (pszItem)
- {
- EnterCriticalSection(&psl->csListAccess);
-
- // Delete old items (empty section)
- WritePrivateProfileString(pszSection, NULL, NULL, pszFileName);
-
- for (i=SL_MIN_POS; i<(int)psl->uCount; i++)
- {
- mir_sntprintf(pszItem, iSize, _T("%s%s%i"), pszSettingPrefix?pszSettingPrefix:_T(""), pszSettingPrefix?_T("|"):_T(""), i);
-
- if (WritePrivateProfileString(pszSection, pszItem, psl->papszList[i], pszFileName))
- bReturn = TRUE;
- }
-
- LeaveCriticalSection(&psl->csListAccess);
-
- mir_free(pszItem);
- }
-
- return bReturn;
-}
-*/
-
-
-BOOL SLLoadFromFile(LPSTRINGLIST psl, const WCHAR* pszSearchPath)
-{
- BOOL bReturn;
- WIN32_FIND_DATA wfd;
- HANDLE hFind;
- BOOL bFileFound;
- WCHAR szFile[MAX_PATH];
- HANDLE hFile;
- DWORD dwRead;
- int iAllocBufSize;
- int iAllocBufStep;
- char* pszAllocBuf;
- char* pszAllocBufTmp;
- const char szBOM[3] = {0xEF, 0xBB, 0xBF};
- BOOL bWatchBOM;
- BOOL bEndOfFile;
- WCHAR* pszContentConv;
- WCHAR* pszBuf;
-
- if (!psl || !pszSearchPath) return FALSE;
- EnterCriticalSection(&psl->csListAccess);
-
- // Initial buffer size (gets auto-enlarged if needed)
- iAllocBufSize = 128; // read-in chars buffer
- pszAllocBuf = NULL;
-
- // Enum all files in the directory
- bReturn = FALSE;
- hFind = FindFirstFile(pszSearchPath, &wfd);
- for (bFileFound=(hFind!=INVALID_HANDLE_VALUE); bFileFound; bFileFound=FindNextFile(hFind, &wfd))
- {
- if (wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
- continue;
- mir_sntprintf(szFile, ARRAYSIZE(szFile), _T("%s"), pszSearchPath);
- PathRemoveFileSpec(szFile);
- PathAppend(szFile, wfd.cFileName);
-
- hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
- if (hFile == INVALID_HANDLE_VALUE) continue;
- bWatchBOM = TRUE;
- bEndOfFile = FALSE;
- iAllocBufStep = 0;
- while (!bEndOfFile)
- {
- // Enlarge buffer if needed
- if (!pszAllocBuf || (iAllocBufStep >= iAllocBufSize))
- {
- pszAllocBufTmp = (char*)mir_realloc(pszAllocBuf, (iAllocBufSize*2)*sizeof(char));
- if (pszAllocBufTmp) {
- if (pszAllocBuf) iAllocBufSize *= 2;
- pszAllocBuf = pszAllocBufTmp;
- } else {
- bEndOfFile = TRUE; // out of memory
- }
- }
- if (!bEndOfFile) {
- if (!ReadFile(hFile, &pszAllocBuf[iAllocBufStep], sizeof(char), &dwRead, NULL))
- bEndOfFile = TRUE;
- if (dwRead < sizeof(char))
- bEndOfFile = TRUE;
- }
- if ((pszAllocBuf[iAllocBufStep] == '\n') || bEndOfFile)
- {
- if (!bEndOfFile && (iAllocBufStep>0) && (pszAllocBuf[iAllocBufStep-1] == '\r'))
- pszAllocBuf[iAllocBufStep-1] = '\0';
- else
- pszAllocBuf[iAllocBufStep] = '\0';
-
- if (lstrlenA(pszAllocBuf) > 0)
- {
- // Test UTF-8 BOM
- // EF BB BF = UTF-8
- // -> indicating UTF-8 Unicode text file (check only once)
- if (bWatchBOM)
- {
- if (StrCmpNA(pszAllocBuf, szBOM, ARRAYSIZE(szBOM)) == 0)
- MoveMemory(pszAllocBuf, (PBYTE)pszAllocBuf+sizeof(szBOM), ((lstrlenA(pszAllocBuf)+1)*sizeof(char))-sizeof(szBOM));
- bWatchBOM = FALSE;
- }
-
- // Decode Utf8
- mir_utf8decode(pszAllocBuf,&pszContentConv);
- if (pszContentConv)
- {
- pszBuf = pszContentConv;
- while (pszBuf)
- {
- // Find comment indicator
- pszBuf = StrChr(pszBuf, _T(';')); // find ";" comment indicator
- if (pszBuf && (*CharPrev(pszContentConv, pszBuf) != _T('\\'))) // ignore "\;" chars
- {
- *pszBuf = _T('\0');
- break;
- }
- }
-
- // Replace no-comment indicators
- pszBuf = ReplaceSubStringWithString(pszContentConv, _T("\\;"), _T(";"), TRUE, FALSE, NULL);
-
- // Add item to list (disallow empty items)
- if (lstrlen(pszContentConv) > 0)
- if (SLAddItem(psl, pszBuf?pszBuf:pszContentConv) >= 0)
- bReturn = TRUE;
-
- mir_free(pszContentConv);
- if (pszBuf) mir_free(pszBuf);
- }
- }
-
- // Reset step count
- iAllocBufStep = 0;
-
- } else {
- // Step up in string
- iAllocBufStep++;
- }
-
- } // while (!bEndOfFile)
-
- CloseHandle(hFile);
- }
-
- if (hFind) FindClose(hFind);
- if (pszAllocBuf) mir_free(pszAllocBuf);
- LeaveCriticalSection(&psl->csListAccess);
- return bReturn;
-}
-
-
-BOOL SLSaveToFile(LPSTRINGLIST psl, const WCHAR* pszFileName)
-{
- BOOL bReturn;
- int i;
- const char szBOM[3] = {0xEF, 0xBB, 0xBF};
- HANDLE hFile;
- DWORD dwWritten; // Win98 compatibility
- WCHAR* pszBuf;
- char* pszContentUtf8;
-
- if (!psl || !pszFileName) return FALSE;
- hFile = CreateFile(pszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);
- if (hFile == INVALID_HANDLE_VALUE) return FALSE;
- bReturn = FALSE;
- EnterCriticalSection(&psl->csListAccess);
-
- // Write UTF-8 BOM
- // EF BB BF = UTF-8
- // -> indicating UTF-8 Unicode text file
- if (WriteFile(hFile, &szBOM, sizeof(szBOM), &dwWritten, NULL))
- for (i=SL_MIN_POS; i<(int)psl->uCount; i++)
- {
- // Replace comment indicators
- pszBuf = ReplaceSubStringWithString(psl->papszList[i], _T(";"), _T("\\;"), TRUE, FALSE, NULL);
- if (!pszBuf) continue;
- pszContentUtf8 = mir_utf8encodeW(pszBuf);
- if (pszContentUtf8) {
- if (WriteFile(hFile, pszContentUtf8, lstrlenA(pszContentUtf8)*sizeof(char), &dwWritten, NULL))
- if (WriteFile(hFile, "\r\n", 2*sizeof(char), &dwWritten, NULL))
- bReturn = TRUE;
- mir_free(pszContentUtf8);
- }
- mir_free(pszBuf);
- }
-
- LeaveCriticalSection(&psl->csListAccess);
- SetEndOfFile(hFile); // if it was longer before
- FlushFileBuffers(hFile); // just to be sure
- CloseHandle(hFile);
- return bReturn;
-}
-
-
-/*
-BOOL SLConvertFromString(LPSTRINGLIST psl, const TCHAR* pszString, int cchSize, const TCHAR* pszSeparator, BOOL bIgnoreEmptyItems)
-{
- // If pszSeparator is NULL a _T('\0') is taken as separator
- BOOL bReturn;
- int cchSepLen;
-
- BOOL bReachedEnd;
- TCHAR* pszAfterPrev;
- TCHAR* pszNext;
- int iPos;
-
- if (!pszString || !psl) return 0;
-
- if (cchSize < 0) cchSize = lstrlen(pszString)+1;
- cchSepLen = pszSeparator?lstrlen(pszSeparator):1;
-
- EnterCriticalSection(&psl->csListAccess);
-
- // Loop through string
- bReturn = 0;
- pszAfterPrev = (TCHAR*)pszString;
- bReachedEnd = FALSE;
- while (!bReachedEnd)
- {
- // Find first/next occurence
- if (pszSeparator)
- {
- pszNext = StrStr(pszAfterPrev, pszSeparator);
- if (!pszNext)
- {
- bReachedEnd = TRUE;
- pszNext = (TCHAR*)pszString+(cchSize*sizeof(TCHAR));
- }
-
- } else {
-
- // Find NULL separator
- pszNext = pszAfterPrev;
- while (*pszNext != _T('\0'));
- {
- pszNext = CharNext(pszNext);
- if ( pszNext >= (szString+((cchSize-1)*sizeof(TCHAR)) )
- {
- bReachedEnd = TRUE;
- break;
- }
- }
- }
-
- // Add item
- if (!bIgnoreEmptyItems || (pszNext != pszAfterPrev))
- {
- i2
- if (iPos < 0) continue;
- CopyMemory((PBYTE)psl->papszList[iPos], pszAfterPrev, ((PBYTE)pszNext-(PBYTE)pszAfterPrev));
-
- bReturn = TRUE;
- }
-
- // Step up one separated item
- pszAfterPrev = pszNext+(cchSepLen*sizeof(TCHAR));
- if ( pszAfterPrev >= pszString+((cchSize-1)*sizeof(TCHAR)) )
- bReachedEnd = TRUE;
- }
-
- LeaveCriticalSection(&psl->csListAccess);
-
- return bReturn;
-}
-*/
-
-
-WCHAR* SLConvertToString(LPSTRINGLIST psl, const WCHAR* pszSeparator, BOOL bAlsoDoFirst, BOOL bAlsoDoLast, int* piSize)
-{
- // Returned string needs to be freed with SLFreeReturn()
- // If pszSeparator is NULL a _T('\0') is taken as separator
-
- int i;
- int iSepLen;
- int iSize;
- WCHAR* pszReturn;
- WCHAR* pszStep;
-
- if (piSize) *piSize = 0;
- if (!psl) return NULL;
-
- EnterCriticalSection(&psl->csListAccess);
-
- // Get needed size
- iSepLen = pszSeparator?lstrlen(pszSeparator):1;
- iSize = SLGetSize(psl, FALSE)+1; // character count in string list
- if (psl->uCount > 0) iSize += (psl->uCount-1)*iSepLen;
- if ((psl->uCount > 0) && bAlsoDoFirst) iSize += iSepLen;
- if (bAlsoDoLast) iSize += iSepLen;
-
- pszReturn = (WCHAR*)SLAlloc(iSize*sizeof(WCHAR));
- if (!pszReturn) {
- LeaveCriticalSection(&psl->csListAccess);
- return NULL;
- }
- if (piSize) *piSize = iSize;
-
- // Add items to memory
- pszStep = pszReturn;
- for (i=SL_MIN_POS; i<(int)psl->uCount; i++)
- {
- if ((i>SL_MIN_POS) || bAlsoDoFirst)
- {
- if (pszSeparator)
- CopyMemory(pszStep, pszSeparator, iSepLen*sizeof(WCHAR)); // no terminating zero
- else
- ZeroMemory(pszStep, sizeof(WCHAR));
- pszStep = &pszStep[iSepLen];
- }
-
- // Add item
- CopyMemory(pszStep, psl->papszList[i], lstrlen(psl->papszList[i])*sizeof(WCHAR)); // no terminating zero
- pszStep = &pszStep[lstrlen(psl->papszList[i])];
- }
- LeaveCriticalSection(&psl->csListAccess);
-
- if (bAlsoDoLast)
- {
- if (pszSeparator)
- CopyMemory(pszStep, pszSeparator, iSepLen*sizeof(WCHAR)); // no terminating zero
- else
- ZeroMemory(pszStep, sizeof(WCHAR));
- pszStep = &pszStep[iSepLen];
- }
-
- ZeroMemory(pszStep, sizeof(WCHAR));
- return pszReturn;
-}
-
-void SLFreeReturn(void* pPntr)
-{
- if (pPntr) SLFree(pPntr);
-}
-
-BOOL SLConvertToStringBuf(LPSTRINGLIST psl, WCHAR* pszOutput, int cchMaxSize, const WCHAR* pszSeparator, BOOL bAlsoDoFirst, BOOL bAlsoDoLast)
-{
- BOOL bReturn;
- int iSize;
- WCHAR* pszBuf;
-
- if (!psl || !pszOutput || (cchMaxSize <= 0)) return FALSE;
- pszBuf = SLConvertToString(psl, pszSeparator, bAlsoDoFirst, bAlsoDoLast, &iSize);
- if (pszBuf) {
- if (cchMaxSize < iSize) iSize = cchMaxSize;
- CopyMemory(pszOutput, pszBuf, iSize*sizeof(WCHAR));
- SLFreeReturn(pszBuf);
- bReturn = TRUE;
- } else {
- iSize = 1;
- bReturn = FALSE;
- }
- if (cchMaxSize > 1)
- ZeroMemory(&pszOutput[iSize-1], sizeof(WCHAR));
- if (!pszSeparator && bAlsoDoLast && (cchMaxSize > 2))
- ZeroMemory(&pszOutput[iSize], sizeof(WCHAR));
- return bReturn;
-}
-
-
-BOOL SLMergeList(LPSTRINGLIST pslDest, LPSTRINGLIST pslFrom)
-{
- BOOL bReturn;
- int i;
-
- if (!pslDest || !pslFrom || (pslDest == pslFrom)) return FALSE;
- EnterCriticalSection(&pslFrom->csListAccess); // first list
- if (pslFrom->uCount == 0) {
- LeaveCriticalSection(&pslFrom->csListAccess);
- return TRUE;
- }
- EnterCriticalSection(&pslDest->csListAccess); // second list
- bReturn = FALSE;
- for (i=SL_MIN_POS; i<(int)(pslFrom->uCount); i++)
- if (SLAddItem(pslDest, pslFrom->papszList[i]) != SL_INVALID_POS)
- bReturn = TRUE;
- LeaveCriticalSection(&pslFrom->csListAccess); // first list
- LeaveCriticalSection(&pslDest->csListAccess); // second list
- return bReturn;
-}
-
-
-int SLFindItem(LPSTRINGLIST psl, const WCHAR* pszItem, BOOL bCaseSensitive, int iStartPos)
-{
- int i, iReturn;
-
- if (!psl || !pszItem) return SL_INVALID_POS;
- EnterCriticalSection(&psl->csListAccess);
- if (!SLIsValid(psl, iStartPos)) {
- LeaveCriticalSection(&psl->csListAccess);
- return SL_INVALID_POS;
- }
- iReturn = SL_INVALID_POS;
- for (i=iStartPos; i<(int)psl->uCount; i++)
- if ((bCaseSensitive?StrCmp(psl->papszList[i], pszItem):StrCmpI(psl->papszList[i], pszItem)) == 0) {
- iReturn = i;
- break;
- }
- LeaveCriticalSection(&psl->csListAccess);
- return iReturn;
-}
-
-BOOL SLIsItem(LPSTRINGLIST psl, const WCHAR* pszItem, BOOL bCaseSensitive)
-{
- return (SLFindItem(psl, pszItem, bCaseSensitive, SL_MIN_POS) != SL_INVALID_POS);
-}
-
-int SLAddItem(LPSTRINGLIST psl, const WCHAR* pszNewItem)
-{
- WCHAR** apszBuf;
- WCHAR* pszBuf;
- int i;
-
- if (!psl) return SL_INVALID_POS;
- EnterCriticalSection(&psl->csListAccess);
- if (((int)(psl->uCount+1) <= 0) || ((int)(psl->uCount+1) == psl->uCount)) {
- #if defined(_DEBUG)
- OutputDebugString(_T("Spam Filter: Stringlist overflow.\r\n"));
- DebugBreak();
- #endif
- LeaveCriticalSection(&psl->csListAccess);
- return SL_INVALID_POS;
- }
-
- // Create/Resize the array
- if (!psl->papszList) {
- apszBuf = (WCHAR**)SLAlloc(sizeof(WCHAR*));
- psl->uCount = 0;
- } else {
- apszBuf = (WCHAR**)SLReAlloc(psl->papszList, (psl->uCount+1)*sizeof(WCHAR*));
- }
- if (apszBuf) {
- psl->papszList = apszBuf;
- } else {
- LeaveCriticalSection(&psl->csListAccess);
- return SL_INVALID_POS;
- }
-
- // Prepare new string memory
- pszBuf = (WCHAR*)SLAlloc(((pszNewItem?lstrlen(pszNewItem):0)+1)*sizeof(WCHAR));
- if (!pszBuf) {
- LeaveCriticalSection(&psl->csListAccess);
- return SL_INVALID_POS;
- }
- // Prepare new string
- if (pszNewItem)
- CopyMemory(pszBuf, pszNewItem, (lstrlen(pszNewItem)+1)*sizeof(WCHAR));
- else
- ZeroMemory(pszBuf, sizeof(WCHAR));
-
- // Insert the new string
- i = psl->uCount;
- psl->papszList[i] = pszBuf;
- psl->uCount++;
-
- LeaveCriticalSection(&psl->csListAccess);
- return i;
-}
-
-int SLAddItemPair(LPSTRINGLIST psl, const WCHAR* pszNewItem1, const WCHAR* pszNewItem2)
-{
- int iPos;
-
- if (!psl) return SL_INVALID_POS;
- EnterCriticalSection(&psl->csListAccess);
- iPos = SLAddItem(psl, pszNewItem1);
- if (iPos != SL_INVALID_POS)
- if (SLAddItem(psl, pszNewItem2) == SL_INVALID_POS)
- SLDeleteItem(psl, iPos);
- LeaveCriticalSection(&psl->csListAccess);
- return iPos;
-}
-
-int SLPrepareItem(LPSTRINGLIST psl, int cchLength)
-{
- int iPos;
-
- if (!psl) return SL_INVALID_POS;
- EnterCriticalSection(&psl->csListAccess);
- iPos = SLAddItem(psl, NULL); // empty item
- if (iPos != SL_INVALID_POS)
- if (!SLSetItemLength(psl, iPos, cchLength)) {
- SLDeleteItem(psl, iPos);
- iPos = SL_INVALID_POS;
- }
- LeaveCriticalSection(&psl->csListAccess);
- return iPos;
-}
-
-/*
-BOOL SLAddItems(LPSTRINGLIST psl, const TCHAR* apszNewItems[], UINT uNewItemsCount)
-{
- int i;
- TCHAR** apszBuf;
-
- if (!psl || !apszNewItems || (uNewItemsCount <= 0))
- return FALSE;
-
- EnterCriticalSection(&psl->csListAccess);
-
- // Create/Resize the array
- if (!psl->papszList) {
- apszBuf = (TCHAR**)SLAlloc(uNewItemCount*sizeof(TCHAR*));
- psl->uCount = 0; // just to be sure
- } else {
- apszBuf = (TCHAR**)SLReAlloc(psl->papszList, (psl->uCount+uNewItemCount)*sizeof(TCHAR*));
- }
-
- if (apszBuf) {
- psl->papszList = apszBuf;
- } else {
- LeaveCriticalSection(&psl->csListAccess);
- return FALSE;
- }
-
- // Insert the new string
- for (i=SL_MIN_POS; i<=iNewItemCount; i++)
- {
- psl->papszList[psl->uCount+i] = (TCHAR*)SLAlloc((lstrlen(apszNewItems[i])+1)*sizeof(TCHAR));
-
- if (psl->papszList[psl->uCount+i])
- {
- CopyMemory((PBYTE)psl->papszList[psl->uCount+i], apszNewItems[i], (lstrlen(apszNewItems[i])+1)*sizeof(TCHAR));
- // Increase list count
- psl->uCount++;
-
- } else {
- LeaveCriticalSection(&psl->csListAccess);
- return FALSE;
- }
- }
-
- LeaveCriticalSection(&psl->csListAccess);
- return TRUE;
-}
-*/
-
-BOOL SLDeleteItems(LPSTRINGLIST psl, int iPosFirst, int iPosLast)
-{
- int i;
- WCHAR** apszBuf;
-
- if (!psl) return FALSE;
- if (iPosLast < iPosFirst) {
- i = iPosLast;
- iPosLast = iPosFirst;
- iPosFirst = i;
- }
- EnterCriticalSection(&psl->csListAccess);
- if (!SLIsValid(psl, iPosFirst) || !SLIsValid(psl, iPosLast)) {
- LeaveCriticalSection(&psl->csListAccess);
- return FALSE;
- }
-
- for (i=iPosFirst; i<=iPosLast; i++)
- SLFree(psl->papszList[i]);
- if ((iPosLast+1) < (int)uMsgTypesCount)
- MoveMemory(&pamtdMsgTypes[iPosFirst], &pamtdMsgTypes[iPosLast+1], (iPosLast-iPosFirst+1)*sizeof(WCHAR));
-
- psl->uCount -= (iPosLast-iPosFirst+1);
-
- if (psl->papszList && (psl->uCount > 0)) {
- apszBuf = (WCHAR**)SLReAlloc(psl->papszList, psl->uCount*sizeof(WCHAR*));
- if (apszBuf) psl->papszList = apszBuf;
- } else {
- if (psl->papszList) SLFree(psl->papszList);
- psl->papszList = NULL;
- psl->uCount = 0;
- }
-
- LeaveCriticalSection(&psl->csListAccess);
- return TRUE;
-}
-
-BOOL SLDeleteItem(LPSTRINGLIST psl, int iPos)
-{
- return SLDeleteItems(psl, iPos, iPos);
-}
-
-BOOL SLSetItemLength(LPSTRINGLIST psl, int iPos, int cchLength)
-{
- WCHAR* pszBuf;
- int iOldLen;
- BOOL bReturn;
-
- if (!psl) return FALSE;
- if (cchLength < 0) cchLength = 0;
- EnterCriticalSection(&psl->csListAccess);
- if (!SLIsValid(psl, iPos)) {
- LeaveCriticalSection(&psl->csListAccess);
- return FALSE;
- }
-
- iOldLen = lstrlen(psl->papszList[iPos]);
- pszBuf = (WCHAR*)SLReAlloc(psl->papszList[iPos], (cchLength+1)*sizeof(WCHAR));
- if (pszBuf) {
- psl->papszList[iPos] = pszBuf;
- if (cchLength <= iOldLen)
- ZeroMemory(&pszBuf[cchLength], sizeof(WCHAR));
- else
- ZeroMemory(&pszBuf[iOldLen], (cchLength-iOldLen+1)*sizeof(WCHAR));
- bReturn = TRUE;
- } else {
- bReturn = FALSE;
- }
-
- LeaveCriticalSection(&psl->csListAccess);
- return bReturn;
-}
-
-
-BOOL SLChangeItem(LPSTRINGLIST psl, int iPos, WCHAR* pszNewStr, BOOL bDoAppend)
-{
- BOOL bReturn;
- WCHAR* pszBuf;
-
- if (!psl) return FALSE;
- EnterCriticalSection(&psl->csListAccess);
- if (!SLIsValid(psl, iPos)) {
- LeaveCriticalSection(&psl->csListAccess);
- return FALSE;
- }
-
- pszBuf = (WCHAR*)SLReAlloc(psl->papszList[iPos], ((pszNewStr?lstrlen(pszNewStr):0) + (bDoAppend?lstrlen(psl->papszList[iPos]):0) + 1)*sizeof(WCHAR));
- if (pszBuf)
- {
- psl->papszList[iPos] = pszBuf;
-
- if (bDoAppend && pszNewStr)
- CopyMemory(&pszBuf[lstrlen(pszBuf)], pszNewStr, (lstrlen(pszNewStr)+1)*sizeof(WCHAR));
- else if (pszNewStr)
- CopyMemory(pszBuf, pszNewStr, (lstrlen(pszNewStr)+1)*sizeof(WCHAR));
- else if (!bDoAppend)
- ZeroMemory(psl->papszList[iPos], sizeof(WCHAR));
-
- bReturn = TRUE;
- } else {
- if (!bDoAppend) ZeroMemory(psl->papszList[iPos], sizeof(WCHAR));
- bReturn = FALSE;
- }
-
- LeaveCriticalSection(&psl->csListAccess);
- return bReturn;
-}
-
-
-
-BOOL SLItemPrintf(LPSTRINGLIST psl, int iPos, int cchArgMaxLen, ...)
-{
- BOOL bReturn = FALSE;
- WCHAR* pszBuf;
- WCHAR* pszFmt;
- va_list arglist;
-
- if (!psl) return FALSE;
- if (cchArgMaxLen < 0) cchArgMaxLen = 0;
- EnterCriticalSection(&psl->csListAccess);
- if (SLIsValid(psl, iPos))
- {
- pszFmt = (WCHAR*)SLAlloc((lstrlen(psl->papszList[iPos])+1)*sizeof(WCHAR));
- if (pszFmt)
- {
- CopyMemory(pszFmt, psl->papszList[iPos], (lstrlen(psl->papszList[iPos])+1)*sizeof(WCHAR));
- pszBuf = (WCHAR*)SLReAlloc(psl->papszList[iPos], (lstrlen(psl->papszList[iPos])+cchArgMaxLen+1)*sizeof(WCHAR));
- if (pszBuf)
- {
- psl->papszList[iPos] = pszBuf;
-
- va_start(arglist, cchArgMaxLen);
- mir_vsntprintf(pszBuf, lstrlen(pszBuf)+cchArgMaxLen+1, pszFmt, arglist);
- va_end(arglist);
-
- bReturn = TRUE;
- mir_free(pszFmt);
- }
- }
- }
-
- LeaveCriticalSection(&psl->csListAccess);
- return bReturn;
-}
-
-
-/*
-BOOL SLMoveItem(LPSTRINGLIST psl, int iOldPos, int iNewPos, BOOL bOnlySwitch)
-{
- TCHAR* pszBuf;
-
- if (!psl) return FALSE;
-
- EnterCriticalSection(&psl->csListAccess);
-
- if (!SLIsValid(psl, iOldPos) || !SLIsValid(psl, iNewPos)) {
- LeaveCriticalSection(&psl->csListAccess);
- return FALSE;
- }
-
- if (iNewPos == iOldPos) {
- LeaveCriticalSection(&psl->csListAccess);
- return TRUE;
- }
-
- if (bOnlySwitch)
- {
- // Switch the items
- pszBuf = psl->papszList[iOldPos];
- psl->papszList[iOldPos] = psl->papszList[iNewPos];
- psl->papszList[iOldPos] = pszBuf;
-
- } else {
-
- int i;
-
- // Cache the old item
- pszBuf = psl->papszList[iOldPos];
-
- if (iNewPos > iOldPos)
- {
- // Move items in between one down
- for (i=iNewPos; i<iOldPos; i++)
- psl->papszList[i+1] = psl->papszList[i];
- } else {
- // Move items in between one up
- for (i=(iOldPos+1); i<=iNewPos; i++)
- psl->papszList[i] = psl->papszList[i+1];
- }
-
- psl->papszList[iNewPos] = pszBuf;
- }
-
- LeaveCriticalSection(&psl->csListAccess);
- return TRUE;
-}
-*/
-
-BOOL SLIsValid(LPSTRINGLIST psl, int iPos)
-{
- BOOL bReturn;
-
- if (!psl) return FALSE;
- EnterCriticalSection(&psl->csListAccess);
- bReturn = (psl->papszList && (iPos>=SL_MIN_POS) && (iPos<(int)psl->uCount));
- LeaveCriticalSection(&psl->csListAccess);
- return bReturn;
-}
-
-WCHAR* SLGetItem(LPSTRINGLIST psl, int iPos)
-{
- WCHAR* pszReturn;
-
- EnterCriticalSection(&psl->csListAccess); // other operations finished
- pszReturn = SLIsValid(psl, iPos) ? psl->papszList[iPos] : NULL;
- LeaveCriticalSection(&psl->csListAccess);
- return pszReturn;
-}
-
-int SLGetMaxPos(LPSTRINGLIST psl)
-{
- int iReturn;
-
- if (!psl) return SL_INVALID_POS;
- EnterCriticalSection(&psl->csListAccess); // other operations finished
- iReturn = (psl->uCount > 0) ? (int)(psl->uCount-1) : SL_INVALID_POS;
- LeaveCriticalSection(&psl->csListAccess);
- return iReturn;
-}
-
-
-int SLGetItemCount(LPSTRINGLIST psl)
-{
- int iReturn;
- if (!psl) return 0;
-
- EnterCriticalSection(&psl->csListAccess); // other operations finished
- iReturn = (int)psl->uCount;
- LeaveCriticalSection(&psl->csListAccess);
- return iReturn;
-}
-
-
-int SLGetSize(LPSTRINGLIST psl, BOOL bAlsoTerminatingZeros) // character count size
-{
- int i, iReturn;
-
- if (!psl) return 0;
- EnterCriticalSection(&psl->csListAccess);
- iReturn = 0;
- for (i=SL_MIN_POS; i<(int)psl->uCount; i++)
- iReturn += lstrlen(psl->papszList[i]);
- if (bAlsoTerminatingZeros)
- iReturn += (int)psl->uCount;
- LeaveCriticalSection(&psl->csListAccess);
- return iReturn;
-}
-
-BOOL SLClearList(LPSTRINGLIST psl)
-{
- int i;
-
- if (!psl) return FALSE;
- EnterCriticalSection(&psl->csListAccess);
-
- // Free string memory
- for (i=SL_MIN_POS; i<(int)psl->uCount; i++)
- SLFree(psl->papszList[i]);
-
- // Free the array
- psl->uCount = 0;
- if (psl->papszList) SLFree(psl->papszList);
- psl->papszList = NULL;
-
- LeaveCriticalSection(&psl->csListAccess);
- return TRUE;
-}
-
-/*
-BOOL SLBlockList(LPSTRINGLIST psl)
-{
- if (!psl) return FALSE;
- EnterCriticalSection(&psl->csListAccess);
- return TRUE;
-}
-
-BOOL SLUnBlockList(LPSTRINGLIST psl)
-{
- if (!psl) return FALSE;
- LeaveCriticalSection(&psl->csListAccess);
- return TRUE;
-}
-*/
-
-LPSTRINGLIST SLNewList(void)
-{
- LPSTRINGLIST psl = (LPSTRINGLIST)SLAlloc(sizeof(STRINGLIST));
- psl->papszList = NULL;
- psl->uCount = 0;
- InitializeCriticalSection(&psl->csListAccess);
- return psl;
-
-}
-
-void SLFreeList(LPSTRINGLIST psl)
-{
- if (!psl) return;
- SLClearList(psl);
- DeleteCriticalSection(&psl->csListAccess);
- SLFree(psl);
+/* + +"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" + +// -- Macros +#define SLAlloc(s) mir_alloc(s) +#define SLReAlloc(p, s) mir_realloc((p), (s)) +#define SLFree(p) mir_free(p) +//#define SLAlloc(s) HeapAlloc(GetProcessHeap(), 0, (s)) +//#define SLReAlloc(p, s) HeapReAlloc(GetProcessHeap(), 0, (p), (s)) +//#define SLFree(p) HeapFree(GetProcessHeap(), 0, (p)) + + +// ----------------------------------------- + + +BOOL SLAssignToListBoxCtrl(LPSTRINGLIST psl, HWND hwndListBox) +{ + BOOL bReturn = FALSE; + int i; + + if (!psl || !hwndListBox) return FALSE; + SendMessage(hwndListBox, LB_RESETCONTENT, 0, 0); + SendMessage(hwndListBox, LB_INITSTORAGE, (WPARAM)psl->uCount, (LPARAM)(SLGetSize(psl, TRUE)*sizeof(WCHAR))); + EnterCriticalSection(&psl->csListAccess); + for (i=SL_MIN_POS; i<(int)psl->uCount; i++) + if (SendMessage(hwndListBox, LB_ADDSTRING, 0, (LPARAM)psl->papszList[i]) >= 0) + bReturn = TRUE; + LeaveCriticalSection(&psl->csListAccess); + return bReturn; +} + +BOOL SLRetrieveFromListBoxCtrl(LPSTRINGLIST psl, HWND hwndListBox) +{ + int iCount, i, iPos; + BOOL bReturn; + + if (!psl || !hwndListBox) return FALSE; + bReturn = FALSE; + EnterCriticalSection(&psl->csListAccess); + iCount = SendMessage(hwndListBox, LB_GETCOUNT, 0, 0); + for (i=0; i<iCount; i++) + { + iPos = SLPrepareItem(psl, SendMessage(hwndListBox, LB_GETTEXTLEN, (WPARAM)i, 0)); + if (iPos != SL_INVALID_POS) + { + if (SendMessage(hwndListBox, LB_GETTEXT, (WPARAM)i, (LPARAM)psl->papszList[iPos]) != LB_ERR) + bReturn = TRUE; + else + SLDeleteItem(psl, iPos); + } + } + LeaveCriticalSection(&psl->csListAccess); + return bReturn; +} + +/* +BOOL SLLoadFromIniFile(LPSTRINGLIST psl, const TCHAR* pszSearchPath, const TCHAR* pszSection, const TCHAR* pszSettingPrefix) +{ + TCHAR szFile[MAX_PATH]; + BOOL bFileFound; + BOOL bReturn = FALSE; + int i, iLen, iSize; + TCHAR* pszItem; + TCHAR* pszBuf; + WIN32_FIND_DATA wfd; + HANDLE hFind; + + if (!psl || !pszSection || !pszSearchPath) + return FALSE; + + ZeroMemory(&wfd, sizeof(wfd)); + + EnterCriticalSection(&psl->csListAccess); + + // Enum all files in the directory + hFind = FindFirstFile(pszSearchPath, &wfd); + for (bFileFound=(hFind!=INVALID_HANDLE_VALUE); bFileFound; bFileFound=FindNextFile(hFind, &wfd)) + { + if (wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) + continue; + + // Construct the file name + mir_sntprintf(szFile, ARRAYSIZE(szFile), _T("%s"), pszSearchPath); + PathRemoveFileSpec(szFile); + PathAppend(szFile, wfd.cFileName); + + // Load the data from ini file + iSize = (pszSettingPrefix?(lstrlen(pszSettingPrefix)+1):0)+MAX_INT_LENGTH+1); + pszItem = (TCHAR*)mir_alloc(iSize*sizeof(TCHAR)); + if (!pszItem) continue; + + for (i=SL_MIN_POS;;i++) // no break condition + { + mir_sntprintf(pszItem, _T("%s%s%i"), iSize, pszSettingPrefix?pszSettingPrefix:_T(""), pszSettingPrefix?_T("|"):_T(""), i); + + iLen = GetPrivateProfileString(pszSection, pszItem, NULL, NULL, 0, szFile); + if (iLen < 0) break; + + pszBuf = (TCHAR*)mir_alloc((iLen+1)*sizeof(TCHAR)); + if (!pszBuf) continue; + + GetPrivateProfileString(pszSection, pszItem, NULL, pszBuf, iLen, szFile); + if (lstrlen(pszBuf) <= 0) break; + + if (SLAddItem(psl, pszBuf) != SL_INVALID_POS) + if (!bReturn) bReturn = TRUE; + + mir_free(pszBuf); + } + + mir_free(pszItem); + } + + LeaveCriticalSection(&psl->csListAccess); + + if (hFind) FindClose(hFind); + + return bReturn; +} + + + +BOOL SLSaveToIniFile(LPSTRINGLIST psl, const TCHAR* pszFileName, const TCHAR* pszSection, const TCHAR* pszSettingPrefix) +{ + int i; + char* pszItem; + int iSize; + BOOL bReturn = FALSE; + + if (!psl || !pszSection || !pszFileName) + return FALSE; + + iSize = (pszSettingPrefix?(lstrlen(pszSettingPrefix)+1):0)+MAX_INT_LENGTH+1; + pszItem = (TCHAR*)mir_alloc(iSize*sizeof(TCHAR)); + + if (pszItem) + { + EnterCriticalSection(&psl->csListAccess); + + // Delete old items (empty section) + WritePrivateProfileString(pszSection, NULL, NULL, pszFileName); + + for (i=SL_MIN_POS; i<(int)psl->uCount; i++) + { + mir_sntprintf(pszItem, iSize, _T("%s%s%i"), pszSettingPrefix?pszSettingPrefix:_T(""), pszSettingPrefix?_T("|"):_T(""), i); + + if (WritePrivateProfileString(pszSection, pszItem, psl->papszList[i], pszFileName)) + bReturn = TRUE; + } + + LeaveCriticalSection(&psl->csListAccess); + + mir_free(pszItem); + } + + return bReturn; +} +*/ + + +BOOL SLLoadFromFile(LPSTRINGLIST psl, const WCHAR* pszSearchPath) +{ + BOOL bReturn; + WIN32_FIND_DATA wfd; + HANDLE hFind; + BOOL bFileFound; + WCHAR szFile[MAX_PATH]; + HANDLE hFile; + DWORD dwRead; + int iAllocBufSize; + int iAllocBufStep; + char* pszAllocBuf; + char* pszAllocBufTmp; + const char szBOM[3] = {0xEF, 0xBB, 0xBF}; + BOOL bWatchBOM; + BOOL bEndOfFile; + WCHAR* pszContentConv; + WCHAR* pszBuf; + + if (!psl || !pszSearchPath) return FALSE; + EnterCriticalSection(&psl->csListAccess); + + // Initial buffer size (gets auto-enlarged if needed) + iAllocBufSize = 128; // read-in chars buffer + pszAllocBuf = NULL; + + // Enum all files in the directory + bReturn = FALSE; + hFind = FindFirstFile(pszSearchPath, &wfd); + for (bFileFound=(hFind!=INVALID_HANDLE_VALUE); bFileFound; bFileFound=FindNextFile(hFind, &wfd)) + { + if (wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) + continue; + mir_sntprintf(szFile, ARRAYSIZE(szFile), _T("%s"), pszSearchPath); + PathRemoveFileSpec(szFile); + PathAppend(szFile, wfd.cFileName); + + hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) continue; + bWatchBOM = TRUE; + bEndOfFile = FALSE; + iAllocBufStep = 0; + while (!bEndOfFile) + { + // Enlarge buffer if needed + if (!pszAllocBuf || (iAllocBufStep >= iAllocBufSize)) + { + pszAllocBufTmp = (char*)mir_realloc(pszAllocBuf, (iAllocBufSize*2)*sizeof(char)); + if (pszAllocBufTmp) { + if (pszAllocBuf) iAllocBufSize *= 2; + pszAllocBuf = pszAllocBufTmp; + } else { + bEndOfFile = TRUE; // out of memory + } + } + if (!bEndOfFile) { + if (!ReadFile(hFile, &pszAllocBuf[iAllocBufStep], sizeof(char), &dwRead, NULL)) + bEndOfFile = TRUE; + if (dwRead < sizeof(char)) + bEndOfFile = TRUE; + } + if ((pszAllocBuf[iAllocBufStep] == '\n') || bEndOfFile) + { + if (!bEndOfFile && (iAllocBufStep>0) && (pszAllocBuf[iAllocBufStep-1] == '\r')) + pszAllocBuf[iAllocBufStep-1] = '\0'; + else + pszAllocBuf[iAllocBufStep] = '\0'; + + if (lstrlenA(pszAllocBuf) > 0) + { + // Test UTF-8 BOM + // EF BB BF = UTF-8 + // -> indicating UTF-8 Unicode text file (check only once) + if (bWatchBOM) + { + if (StrCmpNA(pszAllocBuf, szBOM, ARRAYSIZE(szBOM)) == 0) + MoveMemory(pszAllocBuf, (PBYTE)pszAllocBuf+sizeof(szBOM), ((lstrlenA(pszAllocBuf)+1)*sizeof(char))-sizeof(szBOM)); + bWatchBOM = FALSE; + } + + // Decode Utf8 + mir_utf8decode(pszAllocBuf,&pszContentConv); + if (pszContentConv) + { + pszBuf = pszContentConv; + while (pszBuf) + { + // Find comment indicator + pszBuf = StrChr(pszBuf, _T(';')); // find ";" comment indicator + if (pszBuf && (*CharPrev(pszContentConv, pszBuf) != _T('\\'))) // ignore "\;" chars + { + *pszBuf = _T('\0'); + break; + } + } + + // Replace no-comment indicators + pszBuf = ReplaceSubStringWithString(pszContentConv, _T("\\;"), _T(";"), TRUE, FALSE, NULL); + + // Add item to list (disallow empty items) + if (lstrlen(pszContentConv) > 0) + if (SLAddItem(psl, pszBuf?pszBuf:pszContentConv) >= 0) + bReturn = TRUE; + + mir_free(pszContentConv); + if (pszBuf) mir_free(pszBuf); + } + } + + // Reset step count + iAllocBufStep = 0; + + } else { + // Step up in string + iAllocBufStep++; + } + + } // while (!bEndOfFile) + + CloseHandle(hFile); + } + + if (hFind) FindClose(hFind); + if (pszAllocBuf) mir_free(pszAllocBuf); + LeaveCriticalSection(&psl->csListAccess); + return bReturn; +} + + +BOOL SLSaveToFile(LPSTRINGLIST psl, const WCHAR* pszFileName) +{ + BOOL bReturn; + int i; + const char szBOM[3] = {0xEF, 0xBB, 0xBF}; + HANDLE hFile; + DWORD dwWritten; // Win98 compatibility + WCHAR* pszBuf; + char* pszContentUtf8; + + if (!psl || !pszFileName) return FALSE; + hFile = CreateFile(pszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) return FALSE; + bReturn = FALSE; + EnterCriticalSection(&psl->csListAccess); + + // Write UTF-8 BOM + // EF BB BF = UTF-8 + // -> indicating UTF-8 Unicode text file + if (WriteFile(hFile, &szBOM, sizeof(szBOM), &dwWritten, NULL)) + for (i=SL_MIN_POS; i<(int)psl->uCount; i++) + { + // Replace comment indicators + pszBuf = ReplaceSubStringWithString(psl->papszList[i], _T(";"), _T("\\;"), TRUE, FALSE, NULL); + if (!pszBuf) continue; + pszContentUtf8 = mir_utf8encodeW(pszBuf); + if (pszContentUtf8) { + if (WriteFile(hFile, pszContentUtf8, lstrlenA(pszContentUtf8)*sizeof(char), &dwWritten, NULL)) + if (WriteFile(hFile, "\r\n", 2*sizeof(char), &dwWritten, NULL)) + bReturn = TRUE; + mir_free(pszContentUtf8); + } + mir_free(pszBuf); + } + + LeaveCriticalSection(&psl->csListAccess); + SetEndOfFile(hFile); // if it was longer before + FlushFileBuffers(hFile); // just to be sure + CloseHandle(hFile); + return bReturn; +} + + +/* +BOOL SLConvertFromString(LPSTRINGLIST psl, const TCHAR* pszString, int cchSize, const TCHAR* pszSeparator, BOOL bIgnoreEmptyItems) +{ + // If pszSeparator is NULL a _T('\0') is taken as separator + BOOL bReturn; + int cchSepLen; + + BOOL bReachedEnd; + TCHAR* pszAfterPrev; + TCHAR* pszNext; + int iPos; + + if (!pszString || !psl) return 0; + + if (cchSize < 0) cchSize = lstrlen(pszString)+1; + cchSepLen = pszSeparator?lstrlen(pszSeparator):1; + + EnterCriticalSection(&psl->csListAccess); + + // Loop through string + bReturn = 0; + pszAfterPrev = (TCHAR*)pszString; + bReachedEnd = FALSE; + while (!bReachedEnd) + { + // Find first/next occurence + if (pszSeparator) + { + pszNext = StrStr(pszAfterPrev, pszSeparator); + if (!pszNext) + { + bReachedEnd = TRUE; + pszNext = (TCHAR*)pszString+(cchSize*sizeof(TCHAR)); + } + + } else { + + // Find NULL separator + pszNext = pszAfterPrev; + while (*pszNext != _T('\0')); + { + pszNext = CharNext(pszNext); + if ( pszNext >= (szString+((cchSize-1)*sizeof(TCHAR)) ) + { + bReachedEnd = TRUE; + break; + } + } + } + + // Add item + if (!bIgnoreEmptyItems || (pszNext != pszAfterPrev)) + { + i2 + if (iPos < 0) continue; + CopyMemory((PBYTE)psl->papszList[iPos], pszAfterPrev, ((PBYTE)pszNext-(PBYTE)pszAfterPrev)); + + bReturn = TRUE; + } + + // Step up one separated item + pszAfterPrev = pszNext+(cchSepLen*sizeof(TCHAR)); + if ( pszAfterPrev >= pszString+((cchSize-1)*sizeof(TCHAR)) ) + bReachedEnd = TRUE; + } + + LeaveCriticalSection(&psl->csListAccess); + + return bReturn; +} +*/ + + +WCHAR* SLConvertToString(LPSTRINGLIST psl, const WCHAR* pszSeparator, BOOL bAlsoDoFirst, BOOL bAlsoDoLast, int* piSize) +{ + // Returned string needs to be freed with SLFreeReturn() + // If pszSeparator is NULL a _T('\0') is taken as separator + + int i; + int iSepLen; + int iSize; + WCHAR* pszReturn; + WCHAR* pszStep; + + if (piSize) *piSize = 0; + if (!psl) return NULL; + + EnterCriticalSection(&psl->csListAccess); + + // Get needed size + iSepLen = pszSeparator?lstrlen(pszSeparator):1; + iSize = SLGetSize(psl, FALSE)+1; // character count in string list + if (psl->uCount > 0) iSize += (psl->uCount-1)*iSepLen; + if ((psl->uCount > 0) && bAlsoDoFirst) iSize += iSepLen; + if (bAlsoDoLast) iSize += iSepLen; + + pszReturn = (WCHAR*)SLAlloc(iSize*sizeof(WCHAR)); + if (!pszReturn) { + LeaveCriticalSection(&psl->csListAccess); + return NULL; + } + if (piSize) *piSize = iSize; + + // Add items to memory + pszStep = pszReturn; + for (i=SL_MIN_POS; i<(int)psl->uCount; i++) + { + if ((i>SL_MIN_POS) || bAlsoDoFirst) + { + if (pszSeparator) + CopyMemory(pszStep, pszSeparator, iSepLen*sizeof(WCHAR)); // no terminating zero + else + ZeroMemory(pszStep, sizeof(WCHAR)); + pszStep = &pszStep[iSepLen]; + } + + // Add item + CopyMemory(pszStep, psl->papszList[i], lstrlen(psl->papszList[i])*sizeof(WCHAR)); // no terminating zero + pszStep = &pszStep[lstrlen(psl->papszList[i])]; + } + LeaveCriticalSection(&psl->csListAccess); + + if (bAlsoDoLast) + { + if (pszSeparator) + CopyMemory(pszStep, pszSeparator, iSepLen*sizeof(WCHAR)); // no terminating zero + else + ZeroMemory(pszStep, sizeof(WCHAR)); + pszStep = &pszStep[iSepLen]; + } + + ZeroMemory(pszStep, sizeof(WCHAR)); + return pszReturn; +} + +void SLFreeReturn(void* pPntr) +{ + if (pPntr) SLFree(pPntr); +} + +BOOL SLConvertToStringBuf(LPSTRINGLIST psl, WCHAR* pszOutput, int cchMaxSize, const WCHAR* pszSeparator, BOOL bAlsoDoFirst, BOOL bAlsoDoLast) +{ + BOOL bReturn; + int iSize; + WCHAR* pszBuf; + + if (!psl || !pszOutput || (cchMaxSize <= 0)) return FALSE; + pszBuf = SLConvertToString(psl, pszSeparator, bAlsoDoFirst, bAlsoDoLast, &iSize); + if (pszBuf) { + if (cchMaxSize < iSize) iSize = cchMaxSize; + CopyMemory(pszOutput, pszBuf, iSize*sizeof(WCHAR)); + SLFreeReturn(pszBuf); + bReturn = TRUE; + } else { + iSize = 1; + bReturn = FALSE; + } + if (cchMaxSize > 1) + ZeroMemory(&pszOutput[iSize-1], sizeof(WCHAR)); + if (!pszSeparator && bAlsoDoLast && (cchMaxSize > 2)) + ZeroMemory(&pszOutput[iSize], sizeof(WCHAR)); + return bReturn; +} + + +BOOL SLMergeList(LPSTRINGLIST pslDest, LPSTRINGLIST pslFrom) +{ + BOOL bReturn; + int i; + + if (!pslDest || !pslFrom || (pslDest == pslFrom)) return FALSE; + EnterCriticalSection(&pslFrom->csListAccess); // first list + if (pslFrom->uCount == 0) { + LeaveCriticalSection(&pslFrom->csListAccess); + return TRUE; + } + EnterCriticalSection(&pslDest->csListAccess); // second list + bReturn = FALSE; + for (i=SL_MIN_POS; i<(int)(pslFrom->uCount); i++) + if (SLAddItem(pslDest, pslFrom->papszList[i]) != SL_INVALID_POS) + bReturn = TRUE; + LeaveCriticalSection(&pslFrom->csListAccess); // first list + LeaveCriticalSection(&pslDest->csListAccess); // second list + return bReturn; +} + + +int SLFindItem(LPSTRINGLIST psl, const WCHAR* pszItem, BOOL bCaseSensitive, int iStartPos) +{ + int i, iReturn; + + if (!psl || !pszItem) return SL_INVALID_POS; + EnterCriticalSection(&psl->csListAccess); + if (!SLIsValid(psl, iStartPos)) { + LeaveCriticalSection(&psl->csListAccess); + return SL_INVALID_POS; + } + iReturn = SL_INVALID_POS; + for (i=iStartPos; i<(int)psl->uCount; i++) + if ((bCaseSensitive?StrCmp(psl->papszList[i], pszItem):StrCmpI(psl->papszList[i], pszItem)) == 0) { + iReturn = i; + break; + } + LeaveCriticalSection(&psl->csListAccess); + return iReturn; +} + +BOOL SLIsItem(LPSTRINGLIST psl, const WCHAR* pszItem, BOOL bCaseSensitive) +{ + return (SLFindItem(psl, pszItem, bCaseSensitive, SL_MIN_POS) != SL_INVALID_POS); +} + +int SLAddItem(LPSTRINGLIST psl, const WCHAR* pszNewItem) +{ + WCHAR** apszBuf; + WCHAR* pszBuf; + int i; + + if (!psl) return SL_INVALID_POS; + EnterCriticalSection(&psl->csListAccess); + if (((int)(psl->uCount+1) <= 0) || ((int)(psl->uCount+1) == psl->uCount)) { + #if defined(_DEBUG) + OutputDebugString(_T("Spam Filter: Stringlist overflow.\r\n")); + DebugBreak(); + #endif + LeaveCriticalSection(&psl->csListAccess); + return SL_INVALID_POS; + } + + // Create/Resize the array + if (!psl->papszList) { + apszBuf = (WCHAR**)SLAlloc(sizeof(WCHAR*)); + psl->uCount = 0; + } else { + apszBuf = (WCHAR**)SLReAlloc(psl->papszList, (psl->uCount+1)*sizeof(WCHAR*)); + } + if (apszBuf) { + psl->papszList = apszBuf; + } else { + LeaveCriticalSection(&psl->csListAccess); + return SL_INVALID_POS; + } + + // Prepare new string memory + pszBuf = (WCHAR*)SLAlloc(((pszNewItem?lstrlen(pszNewItem):0)+1)*sizeof(WCHAR)); + if (!pszBuf) { + LeaveCriticalSection(&psl->csListAccess); + return SL_INVALID_POS; + } + // Prepare new string + if (pszNewItem) + CopyMemory(pszBuf, pszNewItem, (lstrlen(pszNewItem)+1)*sizeof(WCHAR)); + else + ZeroMemory(pszBuf, sizeof(WCHAR)); + + // Insert the new string + i = psl->uCount; + psl->papszList[i] = pszBuf; + psl->uCount++; + + LeaveCriticalSection(&psl->csListAccess); + return i; +} + +int SLAddItemPair(LPSTRINGLIST psl, const WCHAR* pszNewItem1, const WCHAR* pszNewItem2) +{ + int iPos; + + if (!psl) return SL_INVALID_POS; + EnterCriticalSection(&psl->csListAccess); + iPos = SLAddItem(psl, pszNewItem1); + if (iPos != SL_INVALID_POS) + if (SLAddItem(psl, pszNewItem2) == SL_INVALID_POS) + SLDeleteItem(psl, iPos); + LeaveCriticalSection(&psl->csListAccess); + return iPos; +} + +int SLPrepareItem(LPSTRINGLIST psl, int cchLength) +{ + int iPos; + + if (!psl) return SL_INVALID_POS; + EnterCriticalSection(&psl->csListAccess); + iPos = SLAddItem(psl, NULL); // empty item + if (iPos != SL_INVALID_POS) + if (!SLSetItemLength(psl, iPos, cchLength)) { + SLDeleteItem(psl, iPos); + iPos = SL_INVALID_POS; + } + LeaveCriticalSection(&psl->csListAccess); + return iPos; +} + +/* +BOOL SLAddItems(LPSTRINGLIST psl, const TCHAR* apszNewItems[], UINT uNewItemsCount) +{ + int i; + TCHAR** apszBuf; + + if (!psl || !apszNewItems || (uNewItemsCount <= 0)) + return FALSE; + + EnterCriticalSection(&psl->csListAccess); + + // Create/Resize the array + if (!psl->papszList) { + apszBuf = (TCHAR**)SLAlloc(uNewItemCount*sizeof(TCHAR*)); + psl->uCount = 0; // just to be sure + } else { + apszBuf = (TCHAR**)SLReAlloc(psl->papszList, (psl->uCount+uNewItemCount)*sizeof(TCHAR*)); + } + + if (apszBuf) { + psl->papszList = apszBuf; + } else { + LeaveCriticalSection(&psl->csListAccess); + return FALSE; + } + + // Insert the new string + for (i=SL_MIN_POS; i<=iNewItemCount; i++) + { + psl->papszList[psl->uCount+i] = (TCHAR*)SLAlloc((lstrlen(apszNewItems[i])+1)*sizeof(TCHAR)); + + if (psl->papszList[psl->uCount+i]) + { + CopyMemory((PBYTE)psl->papszList[psl->uCount+i], apszNewItems[i], (lstrlen(apszNewItems[i])+1)*sizeof(TCHAR)); + // Increase list count + psl->uCount++; + + } else { + LeaveCriticalSection(&psl->csListAccess); + return FALSE; + } + } + + LeaveCriticalSection(&psl->csListAccess); + return TRUE; +} +*/ + +BOOL SLDeleteItems(LPSTRINGLIST psl, int iPosFirst, int iPosLast) +{ + int i; + WCHAR** apszBuf; + + if (!psl) return FALSE; + if (iPosLast < iPosFirst) { + i = iPosLast; + iPosLast = iPosFirst; + iPosFirst = i; + } + EnterCriticalSection(&psl->csListAccess); + if (!SLIsValid(psl, iPosFirst) || !SLIsValid(psl, iPosLast)) { + LeaveCriticalSection(&psl->csListAccess); + return FALSE; + } + + for (i=iPosFirst; i<=iPosLast; i++) + SLFree(psl->papszList[i]); + if ((iPosLast+1) < (int)uMsgTypesCount) + MoveMemory(&pamtdMsgTypes[iPosFirst], &pamtdMsgTypes[iPosLast+1], (iPosLast-iPosFirst+1)*sizeof(WCHAR)); + + psl->uCount -= (iPosLast-iPosFirst+1); + + if (psl->papszList && (psl->uCount > 0)) { + apszBuf = (WCHAR**)SLReAlloc(psl->papszList, psl->uCount*sizeof(WCHAR*)); + if (apszBuf) psl->papszList = apszBuf; + } else { + if (psl->papszList) SLFree(psl->papszList); + psl->papszList = NULL; + psl->uCount = 0; + } + + LeaveCriticalSection(&psl->csListAccess); + return TRUE; +} + +BOOL SLDeleteItem(LPSTRINGLIST psl, int iPos) +{ + return SLDeleteItems(psl, iPos, iPos); +} + +BOOL SLSetItemLength(LPSTRINGLIST psl, int iPos, int cchLength) +{ + WCHAR* pszBuf; + int iOldLen; + BOOL bReturn; + + if (!psl) return FALSE; + if (cchLength < 0) cchLength = 0; + EnterCriticalSection(&psl->csListAccess); + if (!SLIsValid(psl, iPos)) { + LeaveCriticalSection(&psl->csListAccess); + return FALSE; + } + + iOldLen = lstrlen(psl->papszList[iPos]); + pszBuf = (WCHAR*)SLReAlloc(psl->papszList[iPos], (cchLength+1)*sizeof(WCHAR)); + if (pszBuf) { + psl->papszList[iPos] = pszBuf; + if (cchLength <= iOldLen) + ZeroMemory(&pszBuf[cchLength], sizeof(WCHAR)); + else + ZeroMemory(&pszBuf[iOldLen], (cchLength-iOldLen+1)*sizeof(WCHAR)); + bReturn = TRUE; + } else { + bReturn = FALSE; + } + + LeaveCriticalSection(&psl->csListAccess); + return bReturn; +} + + +BOOL SLChangeItem(LPSTRINGLIST psl, int iPos, WCHAR* pszNewStr, BOOL bDoAppend) +{ + BOOL bReturn; + WCHAR* pszBuf; + + if (!psl) return FALSE; + EnterCriticalSection(&psl->csListAccess); + if (!SLIsValid(psl, iPos)) { + LeaveCriticalSection(&psl->csListAccess); + return FALSE; + } + + pszBuf = (WCHAR*)SLReAlloc(psl->papszList[iPos], ((pszNewStr?lstrlen(pszNewStr):0) + (bDoAppend?lstrlen(psl->papszList[iPos]):0) + 1)*sizeof(WCHAR)); + if (pszBuf) + { + psl->papszList[iPos] = pszBuf; + + if (bDoAppend && pszNewStr) + CopyMemory(&pszBuf[lstrlen(pszBuf)], pszNewStr, (lstrlen(pszNewStr)+1)*sizeof(WCHAR)); + else if (pszNewStr) + CopyMemory(pszBuf, pszNewStr, (lstrlen(pszNewStr)+1)*sizeof(WCHAR)); + else if (!bDoAppend) + ZeroMemory(psl->papszList[iPos], sizeof(WCHAR)); + + bReturn = TRUE; + } else { + if (!bDoAppend) ZeroMemory(psl->papszList[iPos], sizeof(WCHAR)); + bReturn = FALSE; + } + + LeaveCriticalSection(&psl->csListAccess); + return bReturn; +} + + + +BOOL SLItemPrintf(LPSTRINGLIST psl, int iPos, int cchArgMaxLen, ...) +{ + BOOL bReturn = FALSE; + WCHAR* pszBuf; + WCHAR* pszFmt; + va_list arglist; + + if (!psl) return FALSE; + if (cchArgMaxLen < 0) cchArgMaxLen = 0; + EnterCriticalSection(&psl->csListAccess); + if (SLIsValid(psl, iPos)) + { + pszFmt = (WCHAR*)SLAlloc((lstrlen(psl->papszList[iPos])+1)*sizeof(WCHAR)); + if (pszFmt) + { + CopyMemory(pszFmt, psl->papszList[iPos], (lstrlen(psl->papszList[iPos])+1)*sizeof(WCHAR)); + pszBuf = (WCHAR*)SLReAlloc(psl->papszList[iPos], (lstrlen(psl->papszList[iPos])+cchArgMaxLen+1)*sizeof(WCHAR)); + if (pszBuf) + { + psl->papszList[iPos] = pszBuf; + + va_start(arglist, cchArgMaxLen); + mir_vsntprintf(pszBuf, lstrlen(pszBuf)+cchArgMaxLen+1, pszFmt, arglist); + va_end(arglist); + + bReturn = TRUE; + mir_free(pszFmt); + } + } + } + + LeaveCriticalSection(&psl->csListAccess); + return bReturn; +} + + +/* +BOOL SLMoveItem(LPSTRINGLIST psl, int iOldPos, int iNewPos, BOOL bOnlySwitch) +{ + TCHAR* pszBuf; + + if (!psl) return FALSE; + + EnterCriticalSection(&psl->csListAccess); + + if (!SLIsValid(psl, iOldPos) || !SLIsValid(psl, iNewPos)) { + LeaveCriticalSection(&psl->csListAccess); + return FALSE; + } + + if (iNewPos == iOldPos) { + LeaveCriticalSection(&psl->csListAccess); + return TRUE; + } + + if (bOnlySwitch) + { + // Switch the items + pszBuf = psl->papszList[iOldPos]; + psl->papszList[iOldPos] = psl->papszList[iNewPos]; + psl->papszList[iOldPos] = pszBuf; + + } else { + + int i; + + // Cache the old item + pszBuf = psl->papszList[iOldPos]; + + if (iNewPos > iOldPos) + { + // Move items in between one down + for (i=iNewPos; i<iOldPos; i++) + psl->papszList[i+1] = psl->papszList[i]; + } else { + // Move items in between one up + for (i=(iOldPos+1); i<=iNewPos; i++) + psl->papszList[i] = psl->papszList[i+1]; + } + + psl->papszList[iNewPos] = pszBuf; + } + + LeaveCriticalSection(&psl->csListAccess); + return TRUE; +} +*/ + +BOOL SLIsValid(LPSTRINGLIST psl, int iPos) +{ + BOOL bReturn; + + if (!psl) return FALSE; + EnterCriticalSection(&psl->csListAccess); + bReturn = (psl->papszList && (iPos>=SL_MIN_POS) && (iPos<(int)psl->uCount)); + LeaveCriticalSection(&psl->csListAccess); + return bReturn; +} + +WCHAR* SLGetItem(LPSTRINGLIST psl, int iPos) +{ + WCHAR* pszReturn; + + EnterCriticalSection(&psl->csListAccess); // other operations finished + pszReturn = SLIsValid(psl, iPos) ? psl->papszList[iPos] : NULL; + LeaveCriticalSection(&psl->csListAccess); + return pszReturn; +} + +int SLGetMaxPos(LPSTRINGLIST psl) +{ + int iReturn; + + if (!psl) return SL_INVALID_POS; + EnterCriticalSection(&psl->csListAccess); // other operations finished + iReturn = (psl->uCount > 0) ? (int)(psl->uCount-1) : SL_INVALID_POS; + LeaveCriticalSection(&psl->csListAccess); + return iReturn; +} + + +int SLGetItemCount(LPSTRINGLIST psl) +{ + int iReturn; + if (!psl) return 0; + + EnterCriticalSection(&psl->csListAccess); // other operations finished + iReturn = (int)psl->uCount; + LeaveCriticalSection(&psl->csListAccess); + return iReturn; +} + + +int SLGetSize(LPSTRINGLIST psl, BOOL bAlsoTerminatingZeros) // character count size +{ + int i, iReturn; + + if (!psl) return 0; + EnterCriticalSection(&psl->csListAccess); + iReturn = 0; + for (i=SL_MIN_POS; i<(int)psl->uCount; i++) + iReturn += lstrlen(psl->papszList[i]); + if (bAlsoTerminatingZeros) + iReturn += (int)psl->uCount; + LeaveCriticalSection(&psl->csListAccess); + return iReturn; +} + +BOOL SLClearList(LPSTRINGLIST psl) +{ + int i; + + if (!psl) return FALSE; + EnterCriticalSection(&psl->csListAccess); + + // Free string memory + for (i=SL_MIN_POS; i<(int)psl->uCount; i++) + SLFree(psl->papszList[i]); + + // Free the array + psl->uCount = 0; + if (psl->papszList) SLFree(psl->papszList); + psl->papszList = NULL; + + LeaveCriticalSection(&psl->csListAccess); + return TRUE; +} + +/* +BOOL SLBlockList(LPSTRINGLIST psl) +{ + if (!psl) return FALSE; + EnterCriticalSection(&psl->csListAccess); + return TRUE; +} + +BOOL SLUnBlockList(LPSTRINGLIST psl) +{ + if (!psl) return FALSE; + LeaveCriticalSection(&psl->csListAccess); + return TRUE; +} +*/ + +LPSTRINGLIST SLNewList(void) +{ + LPSTRINGLIST psl = (LPSTRINGLIST)SLAlloc(sizeof(STRINGLIST)); + psl->papszList = NULL; + psl->uCount = 0; + InitializeCriticalSection(&psl->csListAccess); + return psl; + +} + +void SLFreeList(LPSTRINGLIST psl) +{ + if (!psl) return; + SLClearList(psl); + DeleteCriticalSection(&psl->csListAccess); + SLFree(psl); }
\ No newline at end of file |