306 lines
6.8 KiB
C
306 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"
|
||
|
||
#ifdef IDirectInputDevice2Vtbl
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* 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;
|
||
|
||
}
|
||
|
||
#ifdef HID_SUPPORT
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* @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;
|
||
|
||
}
|
||
|
||
#endif
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* @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);
|
||
}
|
||
|
||
|
||
|
||
#endif
|
||
|