301 lines
6.8 KiB
C
301 lines
6.8 KiB
C
/*****************************************************************************
|
|
*
|
|
* DIList.c
|
|
*
|
|
* Copyright (c) 1997 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* Abstract:
|
|
*
|
|
* List management. Really, array management, since our lists
|
|
* never get very big.
|
|
*
|
|
* We call them "GPA"s, which stands for "Growable Pointer Array".
|
|
*
|
|
* There is a more general GXA gizmo in Dr Watson, but we don't
|
|
* need it yet. So far, all we need to track is unsorted
|
|
* lists of pointers.
|
|
*
|
|
* Yes, there exists a matching concept in COMCTL32, but we can't
|
|
* use it because
|
|
*
|
|
* (1) it's not documented,
|
|
* (2) COMCTL32 puts them into shared memory, which is just
|
|
* begging for a memory leak.
|
|
*
|
|
* Contents:
|
|
*
|
|
* GPA_Init
|
|
* GPA_Term
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "dinputpr.h"
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* The sqiffle for this file.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#define sqfl sqflGpa
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func HRESULT | GPA_Print |
|
|
*
|
|
* Print state of the growing pointer array.
|
|
*
|
|
* @parm HGPA | hgpa |
|
|
*
|
|
* @returns void
|
|
*
|
|
*****************************************************************************/
|
|
void INTERNAL
|
|
GPA_Print(HGPA hgpa)
|
|
{
|
|
int ipv;
|
|
for (ipv = 0; ipv < hgpa->cpv; ipv++)
|
|
{
|
|
// 7/18/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers.
|
|
SquirtSqflPtszV( sqflError,
|
|
TEXT("ipv=%d,hgpa->rgpv[ipv]=%p"),
|
|
ipv, hgpa->rgpv[ipv]);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func HRESULT | GPA_Append |
|
|
*
|
|
* Add a new item to the growing pointer array.
|
|
*
|
|
* Note that we add 8 after doubling, so that we don't get
|
|
* stuck if cxAlloc is zero.
|
|
*
|
|
* @parm HGPA | hgpa |
|
|
*
|
|
* Handle to pointer array.
|
|
*
|
|
* @parm PV | pv |
|
|
*
|
|
* Pointer to add.
|
|
*
|
|
* @returns
|
|
*
|
|
* Returns a COM error code.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
STDMETHODIMP
|
|
GPA_Append(HGPA hgpa, PV pv)
|
|
{
|
|
HRESULT hres;
|
|
|
|
if (hgpa->cpv >= hgpa->cpvAlloc) {
|
|
hres = ReallocCbPpv(cbX(PV) * (hgpa->cpvAlloc * 2 + 8),
|
|
&hgpa->rgpv);
|
|
// Prefix: Whistler 45077.
|
|
if (FAILED(hres) || ( hgpa->rgpv == NULL) ) {
|
|
goto done;
|
|
}
|
|
|
|
hgpa->cpvAlloc = hgpa->cpvAlloc * 2 + 8;
|
|
}
|
|
|
|
//hgpa->rgpv[hgpa->cpv++] = pv;
|
|
hgpa->rgpv[hgpa->cpv] = pv;
|
|
InterlockedIncrement(&hgpa->cpv);
|
|
|
|
hres = S_OK;
|
|
|
|
|
|
done:;
|
|
//GPA_Print(hgpa);
|
|
return hres;
|
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func BOOL | GPA_FindPtr |
|
|
*
|
|
* Determine whether a pointer is in the GPA.
|
|
*
|
|
* @parm HGPA | hgpa |
|
|
*
|
|
* Handle to pointer array.
|
|
*
|
|
* @parm PV | pv |
|
|
*
|
|
* Pointer to locate.
|
|
*
|
|
* @returns
|
|
*
|
|
* Returns a COM error code on failure.
|
|
*
|
|
* On success, returns the number of items left in the GPA.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
BOOL EXTERNAL
|
|
GPA_FindPtr(HGPA hgpa, PV pv)
|
|
{
|
|
BOOL fRc;
|
|
int ipv;
|
|
|
|
for (ipv = 0; ipv < hgpa->cpv; ipv++) {
|
|
if (hgpa->rgpv[ipv] == pv) {
|
|
fRc = TRUE;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
fRc = FALSE;
|
|
|
|
done:;
|
|
return fRc;
|
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func HRESULT | GPA_DeletePtr |
|
|
*
|
|
* Remove the indicated pointer from the GPA. The order of
|
|
* the remaining items is unspecified.
|
|
*
|
|
* Note that CEm_LL_ThreadProc assumes that no items before
|
|
* the deleted item are affected by the deletion.
|
|
*
|
|
* @parm HGPA | hgpa |
|
|
*
|
|
* Handle to pointer array.
|
|
*
|
|
* @parm PV | pv |
|
|
*
|
|
* Pointer to delete.
|
|
*
|
|
* @returns
|
|
*
|
|
* Returns a COM error code on failure.
|
|
*
|
|
* On success, returns the number of items left in the GPA.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
STDMETHODIMP
|
|
GPA_DeletePtr(HGPA hgpa, PV pv)
|
|
{
|
|
HRESULT hres;
|
|
int ipv;
|
|
|
|
for (ipv = 0; ipv < hgpa->cpv; ipv++) {
|
|
if (hgpa->rgpv[ipv] == pv) {
|
|
//hgpa->rgpv[ipv] = hgpa->rgpv[--hgpa->cpv];
|
|
InterlockedDecrement(&hgpa->cpv);
|
|
hgpa->rgpv[ipv] = hgpa->rgpv[hgpa->cpv];
|
|
hres = hgpa->cpv;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
hres = E_FAIL;
|
|
|
|
done:;
|
|
//GPA_Print(hgpa);
|
|
return hres;
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func HRESULT | GPA_Clone |
|
|
*
|
|
* Copy the contents of one GPA to another.
|
|
*
|
|
* @parm HGPA | hgpaDst |
|
|
*
|
|
* Handle to destination pointer array.
|
|
*
|
|
* @parm HGPA | hgpaSrc |
|
|
*
|
|
* Handle to source pointer array.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
STDMETHODIMP
|
|
GPA_Clone(HGPA hgpaDst, HGPA hgpaSrc)
|
|
{
|
|
HRESULT hres;
|
|
|
|
hres = AllocCbPpv(cbCxX(hgpaSrc->cpv, PV), &hgpaDst->rgpv);
|
|
|
|
if (SUCCEEDED(hres)) {
|
|
CopyMemory(hgpaDst->rgpv, hgpaSrc->rgpv, cbCxX(hgpaSrc->cpv, PV));
|
|
hgpaDst->cpv = hgpaSrc->cpv;
|
|
hgpaDst->cpvAlloc = hgpaSrc->cpvAlloc;
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func void | GPA_Init |
|
|
*
|
|
* Initialize a GPA structure with no elements.
|
|
*
|
|
* @parm HGPA | hgpa |
|
|
*
|
|
* Handle to pointer array.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
void EXTERNAL
|
|
GPA_Init(HGPA hgpa)
|
|
{
|
|
hgpa->rgpv = 0;
|
|
hgpa->cpv = 0;
|
|
hgpa->cpvAlloc = 0;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func void | GPA_Term |
|
|
*
|
|
* Clean up an existing GPA.
|
|
*
|
|
* @parm HGPA | hgpa |
|
|
*
|
|
* Handle to pointer array.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
void EXTERNAL
|
|
GPA_Term(HGPA hgpa)
|
|
{
|
|
FreePpv(&hgpa->rgpv);
|
|
GPA_Init(hgpa);
|
|
}
|
|
|
|
|