www.pudn.com > pueblo.zip > ChList.cpp


/*---------------------------------------------------------------------------- 
                        _                              _ _        
        /\             | |                            | (_)       
       /  \   _ __   __| |_ __ ___  _ __ ___   ___  __| |_  __ _  
      / /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` | 
     / ____ \| | | | (_| | | | (_) | | | | | |  __/ (_| | | (_| | 
    /_/    \_\_| |_|\__,_|_|  \___/|_| |_| |_|\___|\__,_|_|\__,_| 
 
    The contents of this file are subject to the Andromedia Public 
	License Version 1.0 (the "License"); you may not use this file 
	except in compliance with the License. You may obtain a copy of 
	the License at http://www.andromedia.com/APL/ 
 
    Software distributed under the License is distributed on an 
	"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 
	implied. See the License for the specific language governing 
	rights and limitations under the License. 
 
    The Original Code is Pueblo client code, released November 4, 1998. 
 
    The Initial Developer of the Original Code is Andromedia Incorporated. 
	Portions created by Andromedia are Copyright (C) 1998 Andromedia 
	Incorporated.  All Rights Reserved. 
 
	Andromedia Incorporated                         415.365.6700 
	818 Mission Street - 2nd Floor                  415.365.6701 fax 
	San Francisco, CA 94103 
 
    Contributor(s): 
	-------------------------------------------------------------------------- 
	   Chaco team:  Dan Greening, Glenn Crocker, Jim Doubek, 
	                Coyote Lussier, Pritham Shetty. 
 
					Wrote and designed original codebase. 
 
------------------------------------------------------------------------------ 
 
	This file consists of implementation of the ChList class. 
 
----------------------------------------------------------------------------*/ 
 
// $Header: /home/cvs/chaco/api/ChList.cpp,v 2.1 1995/06/21 17:55:13 glenn Exp $ 
 
#include "headers.h" 
#include  
 
 
ChParamList::ChParamList() : m_pHead( 0 ), m_pTail( 0 ), m_lCount( 0 ) 
{ 
} 
 
ChParamList::~ChParamList() 
{ 
	Empty(); 
	ASSERT( m_lCount == 0 ); 
} 
 
 
chint32 ChParamList::GetCount() const 
{ 
	return m_lCount; 
} 
 
bool ChParamList::IsEmpty() const 
{ 
	return m_lCount == 0; 
} 
 
 
chparam& ChParamList::GetHead() 
{ 
	ASSERT( m_pHead != 0 ); 
	return m_pHead->item; 
} 
 
chparam ChParamList::GetHead() const 
{ 
	ASSERT( m_pHead != 0 ); 
	return m_pHead->item; 
} 
 
chparam& ChParamList::GetTail() 
{ 
	ASSERT( m_pTail != 0 ); 
	return m_pTail->item; 
} 
 
chparam ChParamList::GetTail() const 
{ 
	ASSERT( m_pTail != 0 ); 
	return m_pTail->item; 
} 
 
 
chparam& ChParamList::GetNext( ChPosition& pos ) 
{ 
	ChParamNode*	pNode = (ChParamNode*)pos; 
 
	#if defined( CH_MSW ) 
	{ 
		ASSERT( AfxIsValidAddress( pNode, sizeof( ChParamNode ) ) ); 
	} 
	#endif	// defined( CH_MSW ) 
 
	pos = (ChPosition)pNode->pNext; 
	return pNode->item; 
} 
 
 
chparam ChParamList::GetNext( ChPosition& pos ) const 
{ 
	ChParamNode*	pNode = (ChParamNode*)pos; 
 
	#if defined( CH_MSW ) 
	{ 
		ASSERT( AfxIsValidAddress( pNode, sizeof( ChParamNode ) ) ); 
	} 
	#endif	// defined( CH_MSW ) 
 
	pos = (ChPosition)pNode->pNext; 
	return pNode->item; 
} 
 
 
chparam& ChParamList::GetPrev( ChPosition& pos ) 
{ 
	ChParamNode*	pNode = (ChParamNode*)pos; 
 
	#if defined( CH_MSW ) 
	{ 
		ASSERT( AfxIsValidAddress( pNode, sizeof( ChParamNode ) ) ); 
	} 
	#endif	// defined( CH_MSW ) 
 
	pos = (ChPosition)pNode->pPrev; 
	return pNode->item; 
} 
 
 
chparam ChParamList::GetPrev( ChPosition& pos ) const 
{ 
	ChParamNode*	pNode = (ChParamNode*)pos; 
 
	#if defined( CH_MSW ) 
	{ 
		ASSERT( AfxIsValidAddress( pNode, sizeof( ChParamNode ) ) ); 
	} 
	#endif	// defined( CH_MSW ) 
 
	pos = (ChPosition)pNode->pPrev; 
	return pNode->item; 
} 
 
 
chparam& ChParamList::Get( ChPosition pos ) 
{ 
	ChParamNode*	pNode = (ChParamNode*)pos; 
 
	#if defined( CH_MSW ) 
	{ 
		ASSERT( AfxIsValidAddress( pNode, sizeof( ChParamNode ) ) ); 
	} 
	#endif	// defined( CH_MSW ) 
 
	return pNode->item; 
} 
 
 
chparam ChParamList::Get( ChPosition pos ) const 
{ 
	ChParamNode* pNode = (ChParamNode*)pos; 
 
	#if defined( CH_MSW ) 
	{ 
		ASSERT( AfxIsValidAddress( pNode, sizeof( ChParamNode ) ) ); 
	} 
	#endif	// defined( CH_MSW ) 
 
	return pNode->item; 
} 
 
 
void ChParamList::Set( ChPosition pos, chparam newVal ) 
{ 
	ChParamNode*	pNode = (ChParamNode*)pos; 
 
	#if defined( CH_MSW ) 
	{ 
		ASSERT( AfxIsValidAddress( pNode, sizeof( ChParamNode ) ) ); 
	} 
	#endif	// defined( CH_MSW ) 
 
	pNode->item = newVal; 
} 
 
 
void ChParamList::Empty() 
{ 
	ChParamNode*	pOldHead; 
											// Destroy elements 
	while (pOldHead = m_pHead) 
	{ 
		chparam		item = pOldHead->item; 
											// Call the destructor helper 
		ChDestructHelper( &item ); 
 
		m_pHead = pOldHead->pNext; 
		FreeNode( pOldHead ); 
	} 
 
	m_lCount = 0; 
	m_pHead = m_pTail = 0; 
} 
 
ChPosition ChParamList::GetHeadPosition() const 
{ 
	return (ChPosition)m_pHead; 
} 
 
ChPosition ChParamList::GetTailPosition() const 
{ 
	return (ChPosition)m_pTail; 
} 
 
ChPosition ChParamList::AddHead( chparam newVal ) 
{ 
	ChParamNode*	pNewNode; 
 
	pNewNode = NewNode( 0, m_pHead ); 
	pNewNode->item = newVal; 
	if (0 != m_pHead) 
	{ 
		m_pHead->pPrev = pNewNode; 
	} 
	else 
	{ 
		m_pTail = pNewNode; 
	} 
	m_pHead = pNewNode; 
 
	return (ChPosition)pNewNode; 
} 
 
 
ChPosition ChParamList::AddTail( chparam newVal ) 
{ 
	ChParamNode*	pNewNode; 
 
	pNewNode = NewNode( m_pTail, 0 ); 
 
	pNewNode->item = newVal; 
	if (m_pTail != 0) 
	{ 
		m_pTail->pNext = pNewNode; 
	} 
	else 
	{ 
		m_pHead = pNewNode; 
	} 
	m_pTail = pNewNode; 
 
	return (ChPosition)pNewNode; 
} 
 
 
void ChParamList::AddHead( ChParamList* pNewList ) 
{ 
	ChPosition	pos; 
 
	ASSERT( pNewList != 0 ); 
											/* add a list of same elements to 
												head (maintain order) */ 
	pos = pNewList->GetTailPosition(); 
	while (pos != 0) 
	{ 
		AddHead( pNewList->GetPrev( pos ) ); 
	} 
} 
 
 
void ChParamList::AddTail( ChParamList* pNewList ) 
{ 
	ChPosition	pos; 
 
	ASSERT( pNewList != 0 ); 
											// add a list of same elements 
	pos = pNewList->GetHeadPosition(); 
	while (pos != 0) 
	{ 
		AddTail( pNewList->GetNext( pos ) ); 
	} 
} 
 
 
chparam ChParamList::RemoveHead() 
{ 
	ASSERT( m_pHead != 0 );				// don't call on empty list 
 
	ChParamNode*	pOldNode = m_pHead; 
	chparam			returnValue = pOldNode->item; 
 
	m_pHead = pOldNode->pNext; 
	if (m_pHead != 0) 
	{ 
		m_pHead->pPrev = 0; 
	} 
	else 
	{ 
		m_pTail = 0; 
	} 
	FreeNode( pOldNode ); 
 
	return returnValue; 
} 
 
 
chparam ChParamList::RemoveTail() 
{ 
	ASSERT( m_pTail != 0 );				// don't call on empty list 
 
	ChParamNode*	pOldNode = m_pTail; 
	chparam			returnValue = pOldNode->item; 
 
	m_pTail = pOldNode->pPrev; 
	if (m_pTail != 0) 
	{ 
		m_pTail->pNext = 0; 
	} 
	else 
	{ 
		m_pHead = 0; 
	} 
	FreeNode( pOldNode ); 
 
	return returnValue; 
} 
 
 
ChPosition ChParamList::InsertBefore( ChPosition pos, chparam newVal ) 
{ 
	if (pos == 0) 
	{ 
		return AddHead( newVal ); 
	} 
 
	ChParamNode*	pOldNode = (ChParamNode*)pos; 
	ChParamNode*	pNewNode = NewNode( pOldNode->pPrev, pOldNode ); 
	 
	pNewNode->item = newVal; 
 
	if (pOldNode->pPrev != 0) 
	{ 
		#if defined( CH_MSW ) 
		{ 
			ASSERT( AfxIsValidAddress( pOldNode->pPrev, sizeof( ChParamNode ) ) ); 
		} 
		#endif	// defined( CH_MSW ) 
 
		pOldNode->pPrev->pNext = pNewNode; 
	} 
	else 
	{ 
		ASSERT( pOldNode == m_pHead ); 
 
		m_pHead = pNewNode; 
	} 
	pOldNode->pPrev = pNewNode; 
 
	return (ChPosition)pNewNode; 
} 
 
 
ChPosition ChParamList::InsertAfter( ChPosition pos, chparam newVal ) 
{ 
	ChParamNode*	pOldNode; 
	ChParamNode*	pNewNode; 
 
	if (pos == 0) 
	{ 
		return AddTail( newVal ); 
	} 
 
	pOldNode = (ChParamNode*)pos; 
 
	#if defined( CH_MSW ) 
	{ 
		ASSERT( AfxIsValidAddress( pOldNode, sizeof( ChParamNode ) ) ); 
	} 
	#endif	// defined( CH_MSW ) 
 
	pNewNode = NewNode( pOldNode, pOldNode->pNext ); 
	pNewNode->item = newVal; 
 
	if (pOldNode->pNext != 0) 
	{ 
		#if defined( CH_MSW ) 
		{ 
			ASSERT( AfxIsValidAddress( pOldNode->pNext, 
										sizeof( ChParamNode ) ) ); 
		} 
		#endif	// defined( CH_MSW ) 
 
		pOldNode->pNext->pPrev = pNewNode; 
	} 
	else 
	{ 
		ASSERT( pOldNode == m_pTail ); 
 
		m_pTail = pNewNode; 
	} 
	pOldNode->pNext = pNewNode; 
 
	return (ChPosition)pNewNode; 
} 
 
 
void ChParamList::Remove( ChPosition pos ) 
{ 
	ChParamNode*	pOldNode; 
 
	pOldNode = (ChParamNode*)pos; 
 
	#if defined( CH_MSW ) 
	{ 
		ASSERT( AfxIsValidAddress( pOldNode, sizeof( ChParamNode ) ) ); 
	} 
	#endif	// defined( CH_MSW ) 
 
											// remove pOldNode from list 
	if (pOldNode == m_pHead) 
	{ 
		m_pHead = pOldNode->pNext; 
	} 
	else 
	{ 
		#if defined( CH_MSW ) 
		{ 
			ASSERT( AfxIsValidAddress( pOldNode->pPrev, 
										sizeof( ChParamNode ) ) ); 
		} 
		#endif	// defined( CH_MSW ) 
 
		pOldNode->pPrev->pNext = pOldNode->pNext; 
	} 
 
	if (pOldNode == m_pTail) 
	{ 
		m_pTail = pOldNode->pPrev; 
	} 
	else 
	{ 
		#if defined( CH_MSW ) 
		{ 
			ASSERT( AfxIsValidAddress( pOldNode->pNext, 
										sizeof( ChParamNode ) ) ); 
		} 
		#endif	// defined( CH_MSW ) 
 
		pOldNode->pNext->pPrev = pOldNode->pPrev; 
	} 
 
	FreeNode( pOldNode ); 
} 
 
 
ChPosition ChParamList::FindIndex( chint32 lIndex ) const 
{ 
	ChParamNode*	pNode; 
 
	ASSERT( lIndex >= 0 ); 
 
	if (lIndex >= m_lCount) 
	{ 
		return 0; 
	} 
 
	pNode = m_pHead; 
	while (lIndex--) 
	{ 
		#if defined( CH_MSW ) 
		{ 
			ASSERT( AfxIsValidAddress( pNode, sizeof( ChParamNode ) ) ); 
		} 
		#endif	// defined( CH_MSW ) 
 
		pNode = pNode->pNext; 
	} 
 
	return (ChPosition)pNode; 
} 
 
 
ChPosition ChParamList::Find( chparam searchValue, 
								ChPosition startAfter ) const 
{ 
	ChParamNode*	pNode; 
 
	pNode = (ChParamNode*)startAfter; 
	if (pNode == 0) 
	{ 
		pNode = m_pHead; 
	} 
	else 
	{ 
		#if defined( CH_MSW ) 
		{ 
			ASSERT( AfxIsValidAddress( pNode, sizeof( ChParamNode ) ) ); 
		} 
		#endif	// defined( CH_MSW ) 
 
		pNode = pNode->pNext;				// start after the one specified 
	} 
 
	for (; pNode != 0; pNode = pNode->pNext) 
	{ 
		if (ChCompareHelper( pNode->item, searchValue )) 
		{ 
			return (ChPosition)pNode; 
		} 
	} 
 
	return 0; 
} 
 
 
ChParamNode* ChParamList::NewNode( ChParamNode* pPrev, ChParamNode* pNext ) 
{ 
	ChParamNode*	pNode; 
											// Create the new node 
	pNode = new ChParamNode; 
											// Stick the node into the chain 
	pNode->pPrev = pPrev; 
	pNode->pNext = pNext; 
											// Increment the node count 
	m_lCount++; 
	ASSERT( m_lCount > 0 ); 
											// Call construct helper 
	ChConstructHelper( &pNode->item ); 
 
	return pNode; 
} 
 
 
void ChParamList::FreeNode( ChParamNode* pNode ) 
{ 
	delete pNode; 
											// Decrement the node count 
	m_lCount--; 
	ASSERT( m_lCount >= 0 ); 
} 
 
 
// Local Variables: *** 
// tab-width:4 *** 
// End: ***