wine-wine/dlls/quartz/complist.c

296 lines
5.6 KiB
C

/*
* List of components. (for internal use)
*
* hidenori@a2.ctktv.ne.jp
*/
#include "config.h"
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/obj_base.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h"
#include "complist.h"
struct QUARTZ_CompList
{
QUARTZ_CompListItem* pFirst;
QUARTZ_CompListItem* pLast;
CRITICAL_SECTION csList;
};
struct QUARTZ_CompListItem
{
IUnknown* punk;
QUARTZ_CompListItem* pNext;
QUARTZ_CompListItem* pPrev;
void* pvData;
DWORD dwDataLen;
};
QUARTZ_CompList* QUARTZ_CompList_Alloc( void )
{
QUARTZ_CompList* pList;
pList = (QUARTZ_CompList*)QUARTZ_AllocMem( sizeof(QUARTZ_CompList) );
if ( pList != NULL )
{
/* construct. */
pList->pFirst = NULL;
pList->pLast = NULL;
InitializeCriticalSection( &pList->csList );
}
return pList;
}
void QUARTZ_CompList_Free( QUARTZ_CompList* pList )
{
QUARTZ_CompListItem* pCur;
QUARTZ_CompListItem* pNext;
if ( pList != NULL )
{
pCur = pList->pFirst;
while ( pCur != NULL )
{
pNext = pCur->pNext;
if ( pCur->punk != NULL )
IUnknown_Release( pCur->punk );
if ( pCur->pvData != NULL )
QUARTZ_FreeMem( pCur->pvData );
QUARTZ_FreeMem( pCur );
pCur = pNext;
}
DeleteCriticalSection( &pList->csList );
QUARTZ_FreeMem( pList );
}
}
void QUARTZ_CompList_Lock( QUARTZ_CompList* pList )
{
EnterCriticalSection( &pList->csList );
}
void QUARTZ_CompList_Unlock( QUARTZ_CompList* pList )
{
LeaveCriticalSection( &pList->csList );
}
QUARTZ_CompList* QUARTZ_CompList_Dup(
const QUARTZ_CompList* pList, BOOL fDupData )
{
QUARTZ_CompList* pNewList;
const QUARTZ_CompListItem* pCur;
HRESULT hr;
pNewList = QUARTZ_CompList_Alloc();
if ( pNewList == NULL )
return NULL;
pCur = pList->pFirst;
while ( pCur != NULL )
{
if ( pCur->punk != NULL )
{
if ( fDupData )
hr = QUARTZ_CompList_AddComp(
pNewList, pCur->punk,
pCur->pvData, pCur->dwDataLen );
else
hr = QUARTZ_CompList_AddComp(
pNewList, pCur->punk, NULL, 0 );
if ( FAILED(hr) )
{
QUARTZ_CompList_Free( pNewList );
return NULL;
}
}
pCur = pCur->pNext;
}
return pNewList;
}
static QUARTZ_CompListItem* QUARTZ_CompList_AllocComp(
QUARTZ_CompList* pList, IUnknown* punk,
const void* pvData, DWORD dwDataLen )
{
QUARTZ_CompListItem* pItem;
pItem = (QUARTZ_CompListItem*)QUARTZ_AllocMem( sizeof(QUARTZ_CompListItem) );
if ( pItem == NULL )
return NULL;
pItem->pvData = NULL;
pItem->dwDataLen = 0;
if ( pvData != NULL )
{
pItem->pvData = (void*)QUARTZ_AllocMem( dwDataLen );
if ( pItem->pvData == NULL )
{
QUARTZ_FreeMem( pItem );
return NULL;
}
memcpy( pItem->pvData, pvData, dwDataLen );
pItem->dwDataLen = dwDataLen;
}
pItem->punk = punk; IUnknown_AddRef(punk);
return pItem;
}
HRESULT QUARTZ_CompList_AddComp(
QUARTZ_CompList* pList, IUnknown* punk,
const void* pvData, DWORD dwDataLen )
{
QUARTZ_CompListItem* pItem;
pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen );
if ( pItem == NULL )
return E_OUTOFMEMORY;
if ( pList->pFirst != NULL )
pList->pFirst->pPrev = pItem;
else
pList->pLast = pItem;
pItem->pNext = pList->pFirst;
pList->pFirst = pItem;
pItem->pPrev = NULL;
return S_OK;
}
HRESULT QUARTZ_CompList_AddTailComp(
QUARTZ_CompList* pList, IUnknown* punk,
const void* pvData, DWORD dwDataLen )
{
QUARTZ_CompListItem* pItem;
pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen );
if ( pItem == NULL )
return E_OUTOFMEMORY;
if ( pList->pLast != NULL )
pList->pLast->pNext = pItem;
else
pList->pFirst = pItem;
pItem->pPrev = pList->pLast;
pList->pLast = pItem;
pItem->pNext = NULL;
return S_OK;
}
HRESULT QUARTZ_CompList_RemoveComp( QUARTZ_CompList* pList, IUnknown* punk )
{
QUARTZ_CompListItem* pCur;
pCur = QUARTZ_CompList_SearchComp( pList, punk );
if ( pCur == NULL )
return S_FALSE; /* already removed. */
/* remove from list. */
if ( pCur->pNext != NULL )
pCur->pNext->pPrev = pCur->pPrev;
else
pList->pLast = pCur->pPrev;
if ( pCur->pPrev != NULL )
pCur->pPrev->pNext = pCur->pNext;
else
pList->pFirst = pCur->pNext;
/* release this item. */
if ( pCur->punk != NULL )
IUnknown_Release( pCur->punk );
if ( pCur->pvData != NULL )
QUARTZ_FreeMem( pCur->pvData );
QUARTZ_FreeMem( pCur );
return S_OK;
}
QUARTZ_CompListItem* QUARTZ_CompList_SearchComp(
QUARTZ_CompList* pList, IUnknown* punk )
{
QUARTZ_CompListItem* pCur;
pCur = pList->pFirst;
while ( pCur != NULL )
{
if ( pCur->punk == punk )
return pCur;
pCur = pCur->pNext;
}
return NULL;
}
QUARTZ_CompListItem* QUARTZ_CompList_SearchData(
QUARTZ_CompList* pList, const void* pvData, DWORD dwDataLen )
{
QUARTZ_CompListItem* pCur;
pCur = pList->pFirst;
while ( pCur != NULL )
{
if ( pCur->dwDataLen == dwDataLen &&
!memcmp( pCur->pvData, pvData, dwDataLen ) )
return pCur;
pCur = pCur->pNext;
}
return NULL;
}
QUARTZ_CompListItem* QUARTZ_CompList_GetFirst(
QUARTZ_CompList* pList )
{
return pList->pFirst;
}
QUARTZ_CompListItem* QUARTZ_CompList_GetLast(
QUARTZ_CompList* pList )
{
return pList->pLast;
}
QUARTZ_CompListItem* QUARTZ_CompList_GetNext(
QUARTZ_CompList* pList, QUARTZ_CompListItem* pPrev )
{
return pPrev->pNext;
}
QUARTZ_CompListItem* QUARTZ_CompList_GetPrev(
QUARTZ_CompList* pList, QUARTZ_CompListItem* pNext )
{
return pNext->pPrev;
}
IUnknown* QUARTZ_CompList_GetItemPtr( QUARTZ_CompListItem* pItem )
{
return pItem->punk;
}
const void* QUARTZ_CompList_GetDataPtr( QUARTZ_CompListItem* pItem )
{
return pItem->pvData;
}
DWORD QUARTZ_CompList_GetDataLength( QUARTZ_CompListItem* pItem )
{
return pItem->dwDataLen;
}