mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-12-19 16:35:53 +01:00
130 lines
3.4 KiB
C++
130 lines
3.4 KiB
C++
#include "./stringvector.h"
|
|
#include <strsafe.h>
|
|
|
|
StringVector::StringVector(size_t cchAllocate, int cchAllocateStep) : pointers(NULL), ptCount(0), ptAllocated(0)
|
|
{
|
|
if (cchAllocate)
|
|
{
|
|
cchBuffer = cchAllocate;
|
|
buffer = (wchar_t*)HeapAlloc(GetProcessHeap(), NULL, cchBuffer * sizeof(wchar_t));
|
|
}
|
|
else
|
|
{
|
|
cchBuffer = 0;
|
|
buffer = NULL;
|
|
}
|
|
|
|
tail = buffer;
|
|
allocateStep = cchAllocateStep;
|
|
}
|
|
|
|
StringVector::~StringVector(void)
|
|
{
|
|
if (buffer)
|
|
{
|
|
HANDLE hHeap = GetProcessHeap();
|
|
HeapFree(hHeap, NULL, buffer);
|
|
cchBuffer = 0;
|
|
tail = NULL;
|
|
buffer = NULL;
|
|
if (pointers)
|
|
{
|
|
HeapFree(hHeap, NULL, pointers);
|
|
ptCount = 0;
|
|
ptAllocated =0;
|
|
pointers = NULL;
|
|
}
|
|
}
|
|
}
|
|
size_t StringVector::Count(void) { return ptCount; }
|
|
size_t StringVector::GetCbAllocated(void){ return cchBuffer * sizeof(wchar_t); }
|
|
size_t StringVector::GetCchAllocated(void) { return cchBuffer; }
|
|
LPCWSTR StringVector::GetString(size_t index) { return (index >= 0 && index < ptCount) ? buffer + pointers[index].offset : NULL; }
|
|
int StringVector::GetStringLength(size_t index) { return (index >= 0 && index < ptCount) ? pointers[index].length : -1; }
|
|
|
|
void StringVector::Clear(void)
|
|
{
|
|
tail = buffer;
|
|
ptCount = 0;
|
|
}
|
|
|
|
int StringVector::SetAllocateStep(int cchNewStep)
|
|
{
|
|
if (cchNewStep < 1) return allocateStep;
|
|
int tmp = allocateStep;
|
|
allocateStep = cchNewStep;
|
|
return tmp;
|
|
}
|
|
|
|
size_t StringVector::Add(const wchar_t *entry, int cchLen)
|
|
{
|
|
if (!entry) return -1;
|
|
if (cchLen < 0) cchLen = lstrlenW(entry);
|
|
if (cchLen == 0) return -1;
|
|
|
|
size_t cchNeed = (size_t)(tail - buffer) + cchLen + 2;
|
|
|
|
if (cchBuffer < cchNeed)
|
|
{
|
|
while ( cchBuffer < cchNeed) cchBuffer += allocateStep;
|
|
size_t offset_tail = (size_t)(tail - buffer);
|
|
buffer = (wchar_t*)( (buffer) ? HeapReAlloc(GetProcessHeap(), NULL, buffer, cchBuffer*sizeof(wchar_t)) : HeapAlloc(GetProcessHeap(), NULL, cchBuffer*sizeof(wchar_t)));
|
|
tail = buffer + offset_tail;
|
|
}
|
|
if (S_OK != StringCchCopyNW(tail, cchBuffer - (size_t)(tail - buffer), entry, cchLen)) return -1;
|
|
|
|
if (ptCount == ptAllocated)
|
|
{
|
|
ptAllocated += 24;
|
|
pointers = (HRECORD)( (pointers) ? HeapReAlloc(GetProcessHeap(), NULL, pointers, ptAllocated*sizeof(RECORD)) : HeapAlloc(GetProcessHeap(), NULL, ptAllocated*sizeof(RECORD)));
|
|
if (pointers == NULL)
|
|
{
|
|
DWORD err = GetLastError();
|
|
err += 1;
|
|
}
|
|
}
|
|
pointers[ptCount].offset = tail - buffer;
|
|
pointers[ptCount].length = cchLen;
|
|
|
|
tail += cchLen + 1;
|
|
ptCount++;
|
|
|
|
return ptCount -1;
|
|
}
|
|
|
|
BOOL StringVector::Remove(size_t index)
|
|
{
|
|
if (index < 0 || index >= ptCount) return FALSE;
|
|
|
|
ptCount--;
|
|
for (size_t i = index; i < ptCount; i++) pointers[i] = pointers[i + 1];
|
|
return TRUE;
|
|
}
|
|
|
|
void StringVector::TrimCount(size_t newCount)
|
|
{
|
|
if (newCount >= ptCount) return;
|
|
if (newCount <= 0) { Clear(); return; }
|
|
tail = buffer + pointers[newCount].offset;
|
|
ptCount = newCount;
|
|
}
|
|
|
|
size_t StringVector::FindString(LCID lcid, LPCWSTR string, int cchLen, BOOL igonreCase)
|
|
{
|
|
if (!string) return -1;
|
|
if (cchLen < 0) cchLen = lstrlenW(string);
|
|
if (cchLen == 0) return -1;
|
|
|
|
for (size_t i = 0; i < ptCount; i ++)
|
|
{
|
|
if ((cchLen == pointers[i].length) &&
|
|
( string == (buffer + pointers[i].offset) || CSTR_EQUAL == CompareStringW(lcid, (igonreCase) ? NORM_IGNORECASE : NULL,
|
|
buffer + pointers[i].offset,
|
|
cchLen,
|
|
string,
|
|
cchLen)))
|
|
return i;
|
|
|
|
}
|
|
return -1;
|
|
} |