|
|
//---------------------------------------------------------------------------
//
// Module: clist.cpp
//
// Description:
//
//
//@@BEGIN_MSINTERNAL
// Development Team:
// Mike McLaughlin
//
// History: Date Author Comment
//
// To Do: Date Author Comment
//
//@@END_MSINTERNAL
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1996-1999 Microsoft Corporation. All Rights Reserved.
//
//---------------------------------------------------------------------------
#include "common.h"
//---------------------------------------------------------------------------
// CListSingle Class
//---------------------------------------------------------------------------
ENUMFUNC CListSingle::EnumerateList( IN ENUMFUNC (CListSingleItem::*pfn)( ) ) { NTSTATUS Status = STATUS_CONTINUE; PCLIST_SINGLE_ITEM plsi;
Assert(this); FOR_EACH_CLIST_ITEM_DELETE(this, plsi, CLIST_SINGLE_ITEM) { Status = (plsi->*pfn)(); if(Status != STATUS_CONTINUE) { goto exit; } } END_EACH_CLIST_ITEM exit: return(Status); }
ENUMFUNC CListSingle::EnumerateList( IN ENUMFUNC (CListSingleItem::*pfn)( PVOID pReference ), PVOID pReference ) { NTSTATUS Status = STATUS_CONTINUE; PCLIST_SINGLE_ITEM plsi;
Assert(this); FOR_EACH_CLIST_ITEM_DELETE(this, plsi, CLIST_SINGLE_ITEM) { Status = (plsi->*pfn)(pReference); if(Status != STATUS_CONTINUE) { goto exit; } } END_EACH_CLIST_ITEM exit: return(Status); }
PCLIST_SINGLE_ITEM * CListSingle::GetListEnd( ) { PCLIST_SINGLE_ITEM *pplsi;
for(pplsi = &m_plsiHead; !IsListEnd(*pplsi); pplsi = &(*pplsi)->m_plsiNext) { Assert(*pplsi); } return(pplsi); }
void CListSingle::ReverseList( ) { PCLIST_SINGLE_ITEM plsi = m_plsiHead; PCLIST_SINGLE_ITEM plsiNext; PCLIST_SINGLE_ITEM plsiTemp;
if (NULL != plsi) { plsiNext = plsi->m_plsiNext; plsi->m_plsiNext = NULL; while (NULL != plsiNext) { plsiTemp = plsiNext->m_plsiNext; plsiNext->m_plsiNext = plsi; plsi = plsiNext; plsiNext = plsiTemp; }
m_plsiHead = plsi; } }
//---------------------------------------------------------------------------
// CListSingleItem Class
//---------------------------------------------------------------------------
VOID CListSingleItem::RemoveList( IN PCLIST_SINGLE pls ) { PCLIST_SINGLE_ITEM *pplsi;
Assert(pls); Assert(this);
for(pplsi = &pls->m_plsiHead; !pls->IsListEnd(*pplsi); pplsi = &(*pplsi)->m_plsiNext) { Assert(*pplsi); if(*pplsi == this) { break; } } *pplsi = m_plsiNext; }
//---------------------------------------------------------------------------
// CListDouble Class
//---------------------------------------------------------------------------
ULONG CListDouble::CountList( ) { PCLIST_DOUBLE_ITEM pldi; ULONG c = 0;
Assert(this); FOR_EACH_CLIST_ITEM(this, pldi) { Assert(pldi); c++; } END_EACH_CLIST_ITEM return(c); }
ENUMFUNC CListDouble::EnumerateList( IN ENUMFUNC (CListDoubleItem::*pfn)( ) ) { NTSTATUS Status = STATUS_CONTINUE; PCLIST_DOUBLE_ITEM plbi;
Assert(this); FOR_EACH_CLIST_ITEM_DELETE(this, plbi, CLIST_DOUBLE_ITEM) { Status = (plbi->*pfn)(); if(Status != STATUS_CONTINUE) { goto exit; } } END_EACH_CLIST_ITEM exit: return(Status); }
ENUMFUNC CListDouble::EnumerateList( IN ENUMFUNC (CListDoubleItem::*pfn)( PVOID pReference ), PVOID pReference ) { NTSTATUS Status = STATUS_CONTINUE; PCLIST_DOUBLE_ITEM plbi;
Assert(this); FOR_EACH_CLIST_ITEM_DELETE(this, plbi, CLIST_DOUBLE_ITEM) { Status = (plbi->*pfn)(pReference); if(Status != STATUS_CONTINUE) { goto exit; } } END_EACH_CLIST_ITEM exit: return(Status); }
//---------------------------------------------------------------------------
// CListData Class
//---------------------------------------------------------------------------
VOID CListData::DestroyList() { PCLIST_DATA_DATA pldd;
Assert(this); FOR_EACH_CLIST_ITEM_DELETE(this, pldd, CLIST_DATA_DATA) { delete pldd; } END_EACH_CLIST_ITEM CListSingle::DestroyList(); }
ULONG CListData::CountList( ) { PCLIST_DATA_DATA pldd; ULONG c = 0;
Assert(this); FOR_EACH_CLIST_ITEM(this, pldd) { Assert(pldd); c++; } END_EACH_CLIST_ITEM return(c); }
ENUMFUNC CListData::EnumerateList( IN ENUMFUNC (CListDataItem::*pfn)( ) ) { NTSTATUS Status = STATUS_CONTINUE; PCLIST_DATA_DATA pldd;
Assert(this); FOR_EACH_CLIST_ITEM_DELETE(this, pldd, CLIST_DATA_DATA) { Status = (GetListData(pldd)->*pfn)(); if(Status != STATUS_CONTINUE) { goto exit; } } END_EACH_CLIST_ITEM exit: return(Status); }
ENUMFUNC CListData::EnumerateList( IN ENUMFUNC (CListDataItem::*pfn)( PVOID pReference ), PVOID pReference ) { NTSTATUS Status = STATUS_CONTINUE; PCLIST_DATA_DATA pldd;
Assert(this); FOR_EACH_CLIST_ITEM_DELETE(this, pldd, CLIST_DATA_DATA) { Status = (GetListData(pldd)->*pfn)(pReference); if(Status != STATUS_CONTINUE) { goto exit; } } END_EACH_CLIST_ITEM exit: return(Status); }
NTSTATUS CListData::CreateUniqueList( OUT PCLIST_DATA pldOut, IN PVOID (*GetFunction)( IN PVOID pData ), IN BOOL (*CompareFunction)( IN PVOID pIn, IN PVOID pOut ) ) { NTSTATUS Status = STATUS_SUCCESS; PCLIST_DATA_DATA plddIn, plddOut; PVOID pIn, pOut; BOOL fFoundMatch;
FOR_EACH_CLIST_ITEM(this, plddIn) {
pIn = (*GetFunction)((PVOID)GetListData(plddIn)); if(pIn == NULL) { continue; } AssertAligned(pIn); fFoundMatch = FALSE; FOR_EACH_CLIST_ITEM(pldOut, plddOut) {
pOut = (PVOID)pldOut->GetListData(plddOut); if((*CompareFunction)(pIn, pOut)) { fFoundMatch = TRUE; break; }
} END_EACH_CLIST_ITEM
if(!fFoundMatch) { Status = pldOut->AddListEnd(pIn); if(!NT_SUCCESS(Status)) { Trap(); goto exit; } }
} END_EACH_CLIST_ITEM exit: if(!NT_SUCCESS(Status)) { pldOut->DestroyList(); } return(Status); }
BOOL CListData::CheckDupList( PVOID p ) { PCLIST_DATA_DATA pldd;
Assert(this); FOR_EACH_CLIST_ITEM(this, pldd) { if(GetListData(pldd) == p) { return(TRUE); } } END_EACH_CLIST_ITEM return(FALSE); }
NTSTATUS CListData::AddList( PVOID p ) { Assert(this); if(CheckDupList(p)) { return(STATUS_SUCCESS); } return(AddListDup(p)); }
NTSTATUS CListData::AddListDup( PVOID p ) { Assert(this); PCLIST_DATA_DATA pldd = new CLIST_DATA_DATA(p); if(pldd == NULL) { return(STATUS_INSUFFICIENT_RESOURCES); } pldd->AddList(this); return(STATUS_SUCCESS); }
NTSTATUS CListData::AddListEnd( PVOID p ) { ASSERT(!CheckDupList(p));
PCLIST_DATA_DATA pldd = new CLIST_DATA_DATA(p); if(pldd == NULL) { return(STATUS_INSUFFICIENT_RESOURCES); } *(GetListEnd()) = pldd; return(STATUS_SUCCESS); }
NTSTATUS CListData::AddListOrdered( PVOID p, LONG lFieldOffset ) { PCLIST_DATA_DATA pldd, *ppldd; ULONG ulOrder;
ASSERT(!CheckDupList(p)); ulOrder = *((PULONG)(((PCHAR)p) + lFieldOffset));
pldd = new CLIST_DATA_DATA(p); if(pldd == NULL) { return(STATUS_INSUFFICIENT_RESOURCES); } for(ppldd = (PCLIST_DATA_DATA *)&m_plsiHead; !IsListEnd(*ppldd); ppldd = (PCLIST_DATA_DATA *)&(*ppldd)->m_plsiNext) { Assert(*ppldd); if(ulOrder < *((PULONG)(((PCHAR)GetListData(*ppldd)) + lFieldOffset))) { break; } } pldd->m_plsiNext = *ppldd; *ppldd = pldd; return(STATUS_SUCCESS); }
VOID CListData::RemoveList( PVOID p ) { PCLIST_DATA_DATA pldd;
Assert(this); FOR_EACH_CLIST_ITEM_DELETE(this, pldd, CLIST_DATA_DATA) { if(GetListData(pldd) == p) { pldd->RemoveList(this); delete pldd; } } END_EACH_CLIST_ITEM }
VOID CListData::JoinList( PCLIST_DATA pld ) { *GetListEnd() = pld->GetListFirst(); pld->CListSingle::DestroyList(); }
//---------------------------------------------------------------------------
// CListMulti Class
//---------------------------------------------------------------------------
VOID CListMulti::DestroyList( ) { PCLIST_MULTI_DATA plmd;
Assert(this); FOR_EACH_CLIST_ITEM_DELETE(this, plmd, CLIST_MULTI_DATA) { delete plmd; } END_EACH_CLIST_ITEM CListDouble::DestroyList(); }
ENUMFUNC CListMulti::EnumerateList( ENUMFUNC (CListMultiItem::*pfn)( ) ) { NTSTATUS Status = STATUS_CONTINUE; PCLIST_MULTI_DATA plmd;
Assert(this); FOR_EACH_CLIST_ITEM_DELETE(this, plmd, CLIST_MULTI_DATA) { Status = (GetListData(plmd)->*pfn)(); if(Status != STATUS_CONTINUE) { goto exit; } } END_EACH_CLIST_ITEM exit: return(Status); }
ENUMFUNC CListMulti::EnumerateList( ENUMFUNC (CListMultiItem::*pfn)( PVOID pReference ), PVOID pReference ) { NTSTATUS Status = STATUS_CONTINUE; PCLIST_MULTI_DATA plmd;
Assert(this); FOR_EACH_CLIST_ITEM_DELETE(this, plmd, CLIST_MULTI_DATA) { Status = (GetListData(plmd)->*pfn)(pReference); if(Status != STATUS_CONTINUE) { goto exit; } } END_EACH_CLIST_ITEM exit: return(Status); }
BOOL CListMulti::CheckDupList( PVOID p ) { PCLIST_MULTI_DATA plmd;
FOR_EACH_CLIST_ITEM(this, plmd) { if(GetListData(plmd) == p) { return(TRUE); } } END_EACH_CLIST_ITEM return(FALSE); }
NTSTATUS CListMulti::AddList( PVOID p, CListMultiItem *plmi ) { Assert(this); Assert(plmi); if(CheckDupList(p)) { return(STATUS_SUCCESS); } PCLIST_MULTI_DATA plmd = new CLIST_MULTI_DATA(p); if(plmd == NULL) { return(STATUS_INSUFFICIENT_RESOURCES); } plmd->AddList(this); plmd->m_ldiItem.AddList(plmi); return(STATUS_SUCCESS); }
NTSTATUS CListMulti::AddListEnd( PVOID p, CListMultiItem *plmi ) { Assert(this); Assert(plmi); if(CheckDupList(p)) { return(STATUS_SUCCESS); } PCLIST_MULTI_DATA plmd = new CLIST_MULTI_DATA(p); if(plmd == NULL) { return(STATUS_INSUFFICIENT_RESOURCES); } plmd->AddListEnd(this); plmd->m_ldiItem.AddListEnd(plmi); return(STATUS_SUCCESS); }
NTSTATUS CListMulti::AddListOrdered( PVOID p, CListMultiItem *plmi, LONG lFieldOffset ) { PCLIST_MULTI_DATA plmd, plmdNew; ULONG ulOrder;
ASSERT(!CheckDupList(p)); ulOrder = *((PULONG)(((PCHAR)p) + lFieldOffset));
plmdNew = new CLIST_MULTI_DATA(p); if(plmdNew == NULL) { return(STATUS_INSUFFICIENT_RESOURCES); } plmdNew->m_ldiItem.AddList(plmi);
FOR_EACH_CLIST_ITEM(this, plmd) { if(ulOrder < *((PULONG)(((PCHAR)GetListData(plmd)) + lFieldOffset))) { break; } } END_EACH_CLIST_ITEM
InsertTailList(&plmd->m_le, &plmdNew->m_le); return(STATUS_SUCCESS); }
VOID CListMulti::RemoveList( PVOID p ) { PCLIST_MULTI_DATA plmd;
Assert(this); FOR_EACH_CLIST_ITEM_DELETE(this, plmd, CLIST_MULTI_DATA) { if(GetListData(plmd) == p) { delete plmd; } } END_EACH_CLIST_ITEM }
VOID CListMulti::JoinList( PCLIST_MULTI plm ) { Assert(this); Assert(plm); ASSERT(this->m_leHead.Blink->Flink == &this->m_leHead); ASSERT(plm->m_leHead.Blink->Flink == &plm->m_leHead); ASSERT(this->m_leHead.Flink->Blink == &this->m_leHead); ASSERT(plm->m_leHead.Flink->Blink == &plm->m_leHead);
if(!plm->IsLstEmpty()) { this->m_leHead.Blink->Flink = plm->m_leHead.Flink; plm->m_leHead.Flink->Blink = this->m_leHead.Blink; plm->m_leHead.Blink->Flink = &this->m_leHead; this->m_leHead.Blink = plm->m_leHead.Blink; InitializeListHead(&plm->m_leHead); } }
//---------------------------------------------------------------------------
// CListMultiItem Class
//---------------------------------------------------------------------------
CListMultiItem::~CListMultiItem() { PCLIST_MULTI_DATA plmd, plmdNext;
for(plmd = CONTAINING_RECORD(GetListFirst(), CLIST_MULTI_DATA, m_ldiItem); !IsListEnd(&plmd->m_ldiItem); plmd = plmdNext) {
Assert(plmd); plmdNext = CONTAINING_RECORD( GetListNext(&plmd->m_ldiItem), CLIST_MULTI_DATA, m_ldiItem);
delete plmd; } }
//---------------------------------------------------------------------------
// end of clist.cpp
//---------------------------------------------------------------------------
|