From 7fd9fe181150f166a098eaf4e006f878c28cb770 Mon Sep 17 00:00:00 2001 From: Gluzskiy Alexandr Date: Mon, 15 Feb 2010 05:51:01 +0300 Subject: sort --- stringlist.c | 1007 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1007 insertions(+) create mode 100644 stringlist.c (limited to 'stringlist.c') diff --git a/stringlist.c b/stringlist.c new file mode 100644 index 0000000..e1d6de5 --- /dev/null +++ b/stringlist.c @@ -0,0 +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; ipapszList[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; ipapszList[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 -- cgit v1.2.3