525 lines
9.4 KiB
C++
525 lines
9.4 KiB
C++
// -----------------------------------------------------------------------------------
|
|
// Created by RogerJ, October 4th, 2000
|
|
// Implementation of MultiSZ smart Array
|
|
//
|
|
|
|
#include <windows.h>
|
|
#include "MultiSZArray.h"
|
|
|
|
// class CMultiSZString
|
|
|
|
// defatul constructor
|
|
CMultiSZString::CMultiSZString()
|
|
{
|
|
m_nSize = m_nStringCount = m_nIndex = 0;
|
|
m_bFound = FALSE;
|
|
m_szHardwareId = NULL;
|
|
prev = next = NULL;
|
|
}
|
|
|
|
// constructor
|
|
CMultiSZString::CMultiSZString(LPCTSTR pszHardwareId, int nSize)
|
|
{
|
|
prev = next = NULL;
|
|
m_nSize = m_nStringCount = m_nIndex = 0;
|
|
m_bFound = FALSE;
|
|
m_szHardwareId = NULL;
|
|
if (pszHardwareId)
|
|
{
|
|
|
|
if (nSize >= 0)
|
|
{
|
|
// passed in a regular LPCTSTR
|
|
m_nSize = nSize;
|
|
m_nStringCount = 1;
|
|
}
|
|
else
|
|
{
|
|
// passed in a multi-sz LPCTSTR
|
|
// get the size
|
|
LPTSTR pTemp = const_cast<LPTSTR>(pszHardwareId);
|
|
while (*pTemp)
|
|
{
|
|
int nTempSize = lstrlen(pTemp) + 1;
|
|
m_nSize += nTempSize;
|
|
pTemp += nTempSize;
|
|
|
|
m_nStringCount++;
|
|
}
|
|
}
|
|
|
|
|
|
// allocate memory
|
|
m_szHardwareId = new TCHAR [m_nSize+1];
|
|
|
|
if (!m_szHardwareId)
|
|
// failed to allocate memory
|
|
throw ERROR_OUTOFMEMORY;
|
|
|
|
// initialize allocated memory
|
|
ZeroMemory (m_szHardwareId, (m_nSize+1) * sizeof(TCHAR)); // +1 for a possible trail NULL
|
|
CopyMemory ((PVOID)m_szHardwareId, (CONST VOID*)pszHardwareId, m_nSize*sizeof(TCHAR));
|
|
m_nSize ++;
|
|
}
|
|
}
|
|
|
|
// copy constructor
|
|
CMultiSZString::CMultiSZString(CMultiSZString& CopyInfo)
|
|
{
|
|
prev = next = NULL;
|
|
m_nIndex = 0;
|
|
m_nSize = CopyInfo.m_nSize;
|
|
m_bFound = CopyInfo.m_bFound;
|
|
|
|
// allocate memory
|
|
m_szHardwareId = new TCHAR [m_nSize];
|
|
if (!m_szHardwareId)
|
|
// failed to allocate memory
|
|
throw ERROR_OUTOFMEMORY;
|
|
// initialize allocated memory
|
|
ZeroMemory (m_szHardwareId, m_nSize * sizeof(TCHAR));
|
|
CopyMemory ((PVOID)m_szHardwareId, (CONST VOID*)(CopyInfo.m_szHardwareId), m_nSize*sizeof(TCHAR));
|
|
}
|
|
|
|
// destructor
|
|
CMultiSZString::~CMultiSZString()
|
|
{
|
|
if (m_szHardwareId)
|
|
delete [] m_szHardwareId;
|
|
m_szHardwareId = NULL;
|
|
prev = next = NULL;
|
|
m_nSize = m_nIndex = 0;
|
|
}
|
|
|
|
|
|
BOOL CMultiSZString::ToString (LPTSTR pszBuffer, int* pnBufferLen)
|
|
{
|
|
if (!pszBuffer)
|
|
{
|
|
// query for output buffer length
|
|
if (m_nSize <= 0)
|
|
*pnBufferLen = 1;
|
|
else
|
|
*pnBufferLen = m_nSize;
|
|
return TRUE;
|
|
}
|
|
|
|
if (*pnBufferLen < m_nSize)
|
|
{
|
|
*pnBufferLen = m_nSize;
|
|
return FALSE;
|
|
}
|
|
|
|
// duel with NULL string special case
|
|
if (m_nSize <= 0)
|
|
{
|
|
*pszBuffer = NULL;
|
|
return TRUE;
|
|
}
|
|
|
|
ZeroMemory(pszBuffer, *pnBufferLen * sizeof(TCHAR));
|
|
|
|
LPTSTR pTemp = m_szHardwareId;
|
|
LPTSTR pTemp2 = pszBuffer;
|
|
while (*pTemp)
|
|
{
|
|
lstrcpy(pTemp2,pTemp);
|
|
// add space in the place of NULL character
|
|
pTemp2 += lstrlen(pTemp2);
|
|
*pTemp2 = ' ';
|
|
pTemp2++;
|
|
// move to next string in Multi-SZ string
|
|
pTemp += lstrlen(pTemp) + 1;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// compare two multi-sz string
|
|
BOOL CMultiSZString::Compare (CMultiSZString& CompareSZ)
|
|
{
|
|
LPTSTR pThis = m_szHardwareId;
|
|
LPTSTR pComp = CompareSZ.m_szHardwareId;
|
|
|
|
// compare size first
|
|
if (m_nSize != CompareSZ.m_nSize) return FALSE;
|
|
|
|
// size are same
|
|
while (*pThis && *pComp)
|
|
{
|
|
// compare one string in the list
|
|
if (0 != lstrcmp(pThis, pComp))
|
|
return FALSE;
|
|
|
|
// move to next string
|
|
int nIncrement = lstrlen(pThis);
|
|
pThis += nIncrement + 1;
|
|
pComp += nIncrement + 1;
|
|
}
|
|
|
|
// one multi-sz terminates, check to see if both terminates
|
|
if (*pThis || *pComp) return FALSE;
|
|
else return TRUE;
|
|
|
|
}
|
|
|
|
|
|
// compare two multi-sz string case insensitively
|
|
BOOL CMultiSZString::CompareNoCase (CMultiSZString& CompareSZ)
|
|
{
|
|
LPTSTR pThis = m_szHardwareId;
|
|
LPTSTR pComp = CompareSZ.m_szHardwareId;
|
|
|
|
// compare size first
|
|
if (m_nSize != CompareSZ.m_nSize) return FALSE;
|
|
|
|
// size are same
|
|
while (*pThis && *pComp)
|
|
{
|
|
// compare one string in the list
|
|
if (0 != lstrcmpi(pThis, pComp))
|
|
return FALSE;
|
|
|
|
// move to next string
|
|
int nIncrement = lstrlen(pThis) + 1;
|
|
pThis += nIncrement;
|
|
pComp += nIncrement;
|
|
}
|
|
|
|
// one multi-sz terminates, check to see if both terminates
|
|
if (*pThis || *pComp) return FALSE;
|
|
else return TRUE;
|
|
|
|
}
|
|
|
|
LPCTSTR CMultiSZString::GetNextString(void)
|
|
{
|
|
// reached end of the multiSZ string
|
|
if (m_nIndex >= m_nSize) return NULL;
|
|
|
|
// else
|
|
LPTSTR pTemp = m_szHardwareId + m_nIndex;
|
|
m_nIndex += lstrlen(pTemp) + 1;
|
|
return pTemp;
|
|
}
|
|
|
|
// return TRUE if pszIn is in the Multi-SZ string
|
|
BOOL CMultiSZString::Contains(LPCTSTR pszIn)
|
|
{
|
|
LPTSTR pThis = m_szHardwareId;
|
|
|
|
while (*pThis)
|
|
{
|
|
if (!lstrcmp(pThis, pszIn))
|
|
// match found
|
|
return TRUE;
|
|
pThis += (lstrlen(pThis) +1);
|
|
}
|
|
|
|
// not found
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// return TRUE if pszIn is in the Multi-SZ string
|
|
BOOL CMultiSZString::ContainsNoCase(LPCTSTR pszIn)
|
|
{
|
|
LPTSTR pThis = m_szHardwareId;
|
|
|
|
while (*pThis)
|
|
{
|
|
if (!lstrcmpi(pThis, pszIn))
|
|
// match found
|
|
return TRUE;
|
|
pThis += (lstrlen(pThis) +1);
|
|
}
|
|
|
|
// not found
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CMultiSZString::PositionIndex(LPCTSTR pszIn, int* pPosition)
|
|
{
|
|
if (!pPosition) return FALSE;
|
|
*pPosition = 0;
|
|
|
|
LPTSTR pThis = m_szHardwareId;
|
|
|
|
while (*pThis)
|
|
{
|
|
if (!lstrcmpi(pThis, pszIn))
|
|
{
|
|
// match found
|
|
return TRUE;
|
|
}
|
|
pThis += (lstrlen(pThis) +1);
|
|
(*pPosition)++;
|
|
}
|
|
|
|
// not found
|
|
*pPosition = -1;
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// Class CMultiSZArray
|
|
|
|
// default constructor
|
|
CMultiSZArray::CMultiSZArray()
|
|
{
|
|
m_nCount = 0;
|
|
m_pHead = m_pTail = m_pIndex = NULL;
|
|
}
|
|
|
|
// other constructors
|
|
CMultiSZArray::CMultiSZArray(LPCTSTR pszHardwareId, int nSize)
|
|
{
|
|
CMultiSZString *pNode = new CMultiSZString(pszHardwareId, nSize);
|
|
|
|
if (!pNode) throw ERROR_OUTOFMEMORY;
|
|
|
|
m_nCount = 1;
|
|
m_pHead = m_pTail = m_pIndex = pNode;
|
|
}
|
|
|
|
CMultiSZArray::CMultiSZArray(CMultiSZString* pNode)
|
|
{
|
|
if (!pNode) return;
|
|
|
|
m_nCount = 1;
|
|
m_pHead = m_pTail = m_pIndex =pNode;
|
|
}
|
|
|
|
// destructor
|
|
CMultiSZArray::~CMultiSZArray(void)
|
|
{
|
|
RemoveAll();
|
|
}
|
|
|
|
// member functions
|
|
|
|
// Function RemoveAll() delete all the memory allocated for the array and set the status back to initial state
|
|
BOOL CMultiSZArray::RemoveAll(void)
|
|
{
|
|
CMultiSZString* pTemp = NULL;
|
|
|
|
for (int i=0; i<m_nCount; i++)
|
|
{
|
|
pTemp = m_pHead;
|
|
m_pHead = m_pHead->next;
|
|
|
|
delete pTemp;
|
|
}
|
|
|
|
m_pHead = m_pTail = m_pIndex = NULL;
|
|
m_nCount = 0;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CMultiSZArray::Add(CMultiSZString* pInfo)
|
|
{
|
|
if (!pInfo) return TRUE;
|
|
|
|
if (!m_nCount)
|
|
m_pHead = pInfo;
|
|
else
|
|
{
|
|
// link
|
|
m_pTail->next = pInfo;
|
|
pInfo->prev = m_pTail;
|
|
pInfo->next = NULL;
|
|
}
|
|
// move tail
|
|
m_pTail = pInfo;
|
|
m_nCount++;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CMultiSZArray::Add(LPCSTR pszHardwareId, int nSize)
|
|
{
|
|
CMultiSZString* pNode = new CMultiSZString(pszHardwareId, nSize);
|
|
return Add(pNode);
|
|
}
|
|
|
|
|
|
BOOL CMultiSZArray::Remove(LPCSTR pszHardwareId)
|
|
{
|
|
CMultiSZString* pTemp = m_pHead;
|
|
while (pTemp)
|
|
{
|
|
if (pTemp->m_szHardwareId == pszHardwareId)
|
|
{
|
|
// found match
|
|
if (pTemp->prev)
|
|
// not the head node
|
|
pTemp->prev->next = pTemp->next;
|
|
else
|
|
{
|
|
// head node, move the head node
|
|
m_pHead = pTemp->next;
|
|
if (m_pHead) m_pHead->prev = NULL;
|
|
}
|
|
|
|
if (pTemp->next)
|
|
// not the tail node
|
|
pTemp->next->prev = pTemp->prev;
|
|
else
|
|
{
|
|
// tail node, move the tail node
|
|
m_pTail = pTemp->prev;
|
|
if (m_pTail) m_pTail->next = NULL;
|
|
}
|
|
delete pTemp;
|
|
m_nCount--;
|
|
return TRUE;
|
|
}
|
|
pTemp = pTemp->next;
|
|
}
|
|
// no match found or no node in the array
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CMultiSZArray::ToString(LPTSTR pszBuffer, int* pnBufferLen)
|
|
{
|
|
int nTempLen = 0;
|
|
CMultiSZString* pTemp = m_pHead;
|
|
|
|
for (int i=0; i<m_nCount; i++)
|
|
{
|
|
nTempLen += pTemp->m_nSize;
|
|
pTemp = pTemp->next;
|
|
}
|
|
|
|
nTempLen++; // the trailing NULL character
|
|
|
|
if (!pszBuffer)
|
|
{
|
|
// request for length
|
|
*pnBufferLen = nTempLen;
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (*pnBufferLen < nTempLen)
|
|
{
|
|
// buffer too small
|
|
*pnBufferLen = nTempLen;
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
ZeroMemory(pszBuffer, *pnBufferLen * sizeof (TCHAR));
|
|
|
|
LPTSTR pszTemp = pszBuffer;
|
|
int nSizeLeft = *pnBufferLen;
|
|
pTemp = m_pHead;
|
|
|
|
for (int j=0; j<m_nCount; j++)
|
|
{
|
|
pTemp->ToString(pszTemp, &nSizeLeft);
|
|
pszTemp += pTemp->m_nSize - 1;
|
|
*pszTemp = '\n';
|
|
nSizeLeft -= pTemp->m_nSize;
|
|
|
|
pTemp = pTemp->next;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
int CMultiSZArray::GetTotalStringCount()
|
|
{
|
|
CMultiSZString* pTemp = m_pHead;
|
|
int nTotalCount = 0;
|
|
|
|
for (int i = 0; i<m_nCount; i++)
|
|
{
|
|
nTotalCount += pTemp->m_nStringCount;
|
|
|
|
pTemp = pTemp->next;
|
|
}
|
|
|
|
return nTotalCount;
|
|
}
|
|
|
|
CMultiSZString* CMultiSZArray::GetNextMultiSZString()
|
|
{
|
|
CMultiSZString* pTemp = m_pIndex;
|
|
|
|
if (m_pIndex) m_pIndex = m_pIndex->next;
|
|
|
|
return pTemp;
|
|
}
|
|
|
|
BOOL CMultiSZArray::Contains(LPCTSTR pszIn)
|
|
{
|
|
CMultiSZString* pTemp = m_pHead;
|
|
|
|
for (int i=0; i<m_nCount; i++)
|
|
{
|
|
if (pTemp->Contains(pszIn))
|
|
return TRUE;
|
|
pTemp = pTemp->next;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CMultiSZArray::ContainsNoCase(LPCTSTR pszIn)
|
|
{
|
|
CMultiSZString* pTemp = m_pHead;
|
|
|
|
for (int i=0; i<m_nCount; i++)
|
|
{
|
|
if (pTemp->ContainsNoCase(pszIn))
|
|
return TRUE;
|
|
pTemp = pTemp->next;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CMultiSZArray::PositionIndex(LPCTSTR pszIn, PosIndex* pPosition)
|
|
{
|
|
if (!pPosition) return FALSE;
|
|
CMultiSZString* pTemp = m_pHead;
|
|
|
|
pPosition->y = 0;
|
|
pPosition->x = 0;
|
|
|
|
for (int i=0; i<m_nCount; i++)
|
|
{
|
|
if (pTemp->PositionIndex(pszIn, &(pPosition->y)))
|
|
return TRUE;
|
|
(pPosition->x)++;
|
|
pTemp = pTemp->next;
|
|
}
|
|
|
|
pPosition->x = pPosition->y = -1;
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CMultiSZArray::CheckFound(int nIndex)
|
|
{
|
|
if (nIndex > m_nCount) return FALSE;
|
|
|
|
CMultiSZString* pTemp = NULL;
|
|
ResetIndex();
|
|
|
|
for (int i=0; i<=nIndex; i++)
|
|
{
|
|
pTemp = GetNextMultiSZString();
|
|
}
|
|
|
|
pTemp->CheckFound();
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|