Sweden-Number/dlls/quartz/complist.c

310 lines
6.3 KiB
C

/*
* List of components. (for internal use)
*
* Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/obj_base.h"
#include "wine/debug.h"
WINE_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;
}