Grabby/CommonCfg/MultiString.c

196 lines
3.7 KiB
C
Raw Permalink Normal View History

#include "stdafx.h"
#define STRSAFE_NO_DEPRECATE
#include <Strsafe.h>
#define CurAlloc Reserved[0]
BOOL
MultiString_Init(MultiString *ms,
DWORD dwInitLen)
{
HANDLE hHeap = GetProcessHeap();
if (!ms) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (dwInitLen) {
ms->CurAlloc = dwInitLen;
ms->Values = HeapAlloc(hHeap,
HEAP_ZERO_MEMORY,
sizeof(LPTSTR) * dwInitLen);
if (!ms->Values) return FALSE;
ms->Count = 0;
} else {
// Otherwise, this amounts to a zero-out
ZeroMemory(ms, sizeof(MultiString));
}
return TRUE;
}
__inline static LPTSTR
CreateStrCopy(LPCTSTR szStr)
{
HRESULT hrRes;
LPTSTR szNewCopy;
// dwLen needs to include the NULL terminator
size_t dwLen = _tcslen(szStr) + 1;
HANDLE hHeap = GetProcessHeap();
// Allocate the new string
szNewCopy = HeapAlloc(hHeap,
HEAP_ZERO_MEMORY,
sizeof(TCHAR) * dwLen);
if (!szNewCopy) return NULL;
// Copy the actual data over
hrRes = StringCchCopy(szNewCopy,
dwLen,
szStr);
if (FAILED(hrRes)) {
HeapFree(hHeap, 0, szNewCopy);
return NULL;
}
return szNewCopy;
}
BOOL
MultiString_Append(MultiString *ms,
LPCTSTR szNew)
{
LPTSTR szNewCopy = NULL;
DWORD dwNewLen;
HANDLE hHeap = GetProcessHeap();
if (!ms || !szNew) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
dwNewLen = (DWORD)_tcslen(szNew) + 1;
// Do we need to allocate more room for pointers?
if (ms->Values == NULL) {
// Oops, we have nothing! Let's allocate a couple
if (!MultiString_Init(ms, 3)) {
return FALSE;
}
} else if (ms->CurAlloc == ms->Count) {
DWORD dwNewAlloc = ms->CurAlloc + 3;
LPTSTR *pszNew = HeapReAlloc(hHeap,
0,
ms->Values,
sizeof(LPTSTR) * dwNewAlloc);
if (!pszNew) {
// ReAlloc failed :<
return FALSE;
}
ms->CurAlloc = dwNewAlloc;
ms->Values = pszNew;
}
szNewCopy = CreateStrCopy(szNew);
if (!szNewCopy) return FALSE;
// All set, append to the end and increment Count
ms->Values[ms->Count++] = szNewCopy;
ms->TotalLength += dwNewLen;
return TRUE;
}
BOOL
MultiString_Remove(MultiString *ms,
DWORD dwIdx)
{
DWORD dwLen = 0;
HANDLE hHeap = GetProcessHeap();
if (!ms) return FALSE;
if (dwIdx >= ms->Count) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
} else if (ms->Values[dwIdx] != NULL) {
dwLen = (DWORD)_tcslen(ms->Values[dwIdx]) + 1;
HeapFree(hHeap, 0, ms->Values[dwIdx]);
}
// Shift down the remaining strings
if (dwIdx < ms->Count - 1) {
size_t i;
for (i = dwIdx; i < ms->Count - 1; i++) {
ms->Values[i] = ms->Values[i + 1];
}
}
ms->Count--;
ms->TotalLength -= dwLen;
return TRUE;
}
BOOL
MultiString_Replace(MultiString *ms,
DWORD dwIdx,
LPCTSTR szNew)
{
DWORD dwOldLen = 0,
dwNewLen = 0;
LPTSTR szTmp;
HANDLE hHeap = GetProcessHeap();
if (!ms || !szNew) return FALSE;
if (dwIdx >= ms->Count) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
dwNewLen = (DWORD)_tcslen(szNew) + 1;
// Create the copied new string
szTmp = CreateStrCopy(szNew);
if (!szTmp) return FALSE;
// Perform the switcheroo
if (ms->Values[dwIdx] != NULL) {
dwOldLen = (DWORD)_tcslen(ms->Values[dwIdx]) + 1;
HeapFree(hHeap, 0, ms->Values[dwIdx]);
}
ms->Values[dwIdx] = szTmp;
ms->TotalLength = ms->TotalLength + dwNewLen - dwOldLen;
return TRUE;
}
void
MultiString_Dispose(MultiString *ms)
{
HANDLE hHeap = GetProcessHeap();
DWORD i;
if (!ms) return;
if (ms->Values != NULL) {
for (i = 0; i < ms->Count; i++) {
HeapFree(hHeap, 0, ms->Values[i]);
}
HeapFree(hHeap, 0, ms->Values);
ms->Values = NULL;
}
ms->Count = 0;
ms->CurAlloc = 0;
return;
}