|
|
/*****************************************************************************
* * 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); }
|