www.pudn.com > IOCPNet_Demo.zip > LinkedListStatic.h


//////////////////////////////////////////////////////////////////////////////////////////////////// 
//	Module Name: 
//		LinkedList.h 
//	Author: 
//		Chun-Hyok, Chong. 
//	Description: 
//		It is a class that implements a linked list uses static memory area. 
//////////////////////////////////////////////////////////////////////////////////////////////////// 
 
#ifndef __LINKEDLISTSTATIC_H__ 
#define __LINKEDLISTSTATIC_H__ 
 
#include "PreAllocator.h" 
#include  
 
#define RET_SUCCESS							1 
#define RET_FAIL							-1 
#define RET_NO_MATCH						2 
#define RET_EQUAL							0 
#define RET_NOT_EQUAL						1 
#define RET_NO_ELEMENT						0 
 
#ifndef __OELEMENT__ 
#define __OELEMENT__ 
template class OElement 
{ 
public: 
	T Element; 
	OElement *pPrev; 
	OElement *pNext; 
}; 
#endif // __OELEMENT__ 
 
template class OLinkedListStatic 
{ 
	// Properties. 
private: 
	OElement *m_pHead; 
	OElement *m_pTail; 
	OElement *m_pCurrent; 
	DWORD m_Count; 
	OPreAllocator *m_pPreAllocator; 
 
public: 
 
	// Methods. 
private: 
	int Compare(BYTE *Compee, BYTE *Comper, DWORD Size); 
 
public: 
	OLinkedListStatic(); 
	OLinkedListStatic(OPreAllocator *pPA); 
	BOOL SetPreAllocator(OPreAllocator *pPA); 
	~OLinkedListStatic(); 
	int Add(T Element); 
	int AddBeforeCurrent(T Element); 
	int AddAfterCurrent(T Element); 
	int Subtract(T Element); 
	int SubtractAllDup(T Element); 
	int SubtractFirst(); 
	int SubtractLast(); 
	int SubtractCurrent(); 
	T *MoveFirst(); 
	T *MoveLast(); 
	T *MovePrev(); 
	T *MoveNext(); 
	T *GetCurrent(); 
	DWORD GetCount(); 
	int Reset(); 
}; 
 
template OLinkedListStatic::OLinkedListStatic() 
{ 
	m_pHead = NULL; 
	m_pTail = NULL; 
	m_pCurrent = NULL; 
	m_Count = 0; 
	m_pPreAllocator = 0; 
} // OLinkedListStatic() 
 
template OLinkedListStatic::OLinkedListStatic(OPreAllocator *pPA) 
{ 
	m_pHead = NULL; 
	m_pTail = NULL; 
	m_pCurrent = NULL; 
	m_Count = 0; 
	m_pPreAllocator = pPA; 
} // OLinkedListStatic() 
	 
template OLinkedListStatic::~OLinkedListStatic() 
{ 
	OElement *pNext; 
	OElement *pNextTemp; 
 
	if (NULL != m_pHead) 
	{ 
		pNext = m_pHead; 
		while (NULL != pNext) 
		{ 
			pNextTemp = pNext->pNext; 
			m_pPreAllocator->Free(pNext); 
			pNext = pNextTemp; 
		} 
	} 
} // ~OLinkecListStatic() 
 
template BOOL OLinkedListStatic::SetPreAllocator(OPreAllocator *pPA) 
{ 
	if (0 != m_pPreAllocator) 
	{ 
		m_pPreAllocator->FreePreAllocatedMemory(); 
		m_pPreAllocator = 0; 
	} 
 
	m_pPreAllocator = pPA; 
 
	return 1; 
} // SetPreAllocator() 
 
template int OLinkedListStatic::Add(T Element) 
{ 
	OElement *pElement; 
	OElement *pNext; 
 
	pElement = (OElement *)m_pPreAllocator->Allocate(sizeof (OElement)); 
	if (NULL == pElement) 
	{ 
		return RET_FAIL; 
	} 
 
	if (NULL == m_pHead) // The first element. 
	{ 
		pElement->pPrev = NULL; 
		pElement->pNext = NULL; 
		memcpy(&(pElement->Element), &Element, sizeof (Element)); 
		m_pCurrent = m_pHead = m_pTail = pElement; 
	} 
	else 
	{ 
		pNext = m_pTail; 
		pNext->pNext = pElement; 
		pElement->pPrev = pNext; 
		pElement->pNext = NULL; 
		m_pTail = pElement; 
		memcpy(&pElement->Element, &Element, sizeof (Element)); 
	} 
 
	m_Count++; 
 
	return RET_SUCCESS; 
} // Add() 
 
template int OLinkedListStatic::AddBeforeCurrent(T Element) 
{ 
	OElement *pElement; 
 
	if (NULL == m_pCurrent) 
	{ 
		return RET_FAIL; 
	} 
 
	pElement = (OElement *)m_pPreAllocator->Allocate(sizeof (OElement)); 
	if (NULL == pElement) 
	{ 
		return RET_FAIL; 
	} 
 
	if (NULL == m_pCurrent->pPrev) 
	{ 
		pElement->pPrev = NULL; 
		m_pHead = pElement; 
	} 
	else 
	{ 
		m_pCurrent->pPrev->pNext = pElement; 
		pElement->pPrev = m_pCurrent->pPrev; 
	} 
 
	pElement->pNext = m_pCurrent; 
	m_pCurrent->pPrev = pElement; 
	memcpy(&pElement->Element, &Element, sizeof (Element)); 
 
	m_Count++; 
 
	return RET_SUCCESS; 
} // AddBeforeCurrent() 
 
template int OLinkedListStatic::AddAfterCurrent(T Element) 
{ 
	OElement *pElement; 
 
	if (NULL == m_pCurrent) 
	{ 
		return RET_FAIL; 
	} 
 
	pElement = (OElement *)m_pPreAllocator->Allocate(sizeof (OElement)); 
	if (NULL == pElement) 
	{ 
		return RET_FAIL; 
	} 
 
	if (NULL == m_pCurrent->pNext) 
	{ 
		pElement->pNext = NULL; 
		m_pTail = pElement; 
	} 
	else 
	{ 
		m_pCurrent->pNext->pPrev = pElement; 
		pElement->pNext = m_pCurrent->pNext; 
	} 
 
	pElement->pPrev = m_pCurrent; 
	m_pCurrent->pNext = pElement; 
	memcpy(&pElement->Element, &Element, sizeof (Element)); 
 
	m_Count++; 
 
	return RET_SUCCESS; 
} // AddAfterCurrent() 
 
template int OLinkedListStatic::Subtract(T Element) 
{ 
	OElement *pNext; 
	int RetCode; 
 
	if (NULL == m_pHead) 
	{ 
		return RET_NO_ELEMENT; 
	} 
 
	RetCode = RET_NO_MATCH; 
	pNext = m_pHead; 
	while (NULL != pNext) 
	{ 
		if (RET_EQUAL == Compare((BYTE *)&pNext->Element, (BYTE *)&Element, sizeof (T))) 
		{ 
			if (NULL == pNext->pNext) 
			{ 
				if (NULL == pNext->pPrev) 
				{ 
					// There will be no element in the list. 
					m_pHead = NULL; 
					m_pTail = NULL; 
					m_pCurrent = NULL; 
					// m_Count = 0; see below 'm_Count--'. 
				} 
				else 
				{ 
					pNext->pPrev->pNext = NULL; 
					m_pTail = pNext->pPrev; 
					if (m_pCurrent == pNext) 
					{ 
						m_pCurrent = m_pTail; 
					} 
				} 
			} 
			else 
			{ 
				if (NULL == pNext->pPrev) 
				{ 
					m_pHead = pNext->pNext; 
					pNext->pNext->pPrev = NULL; 
					if (m_pCurrent == pNext) 
					{ 
						m_pCurrent = m_pHead; 
					} 
				} 
				else 
				{ 
					pNext->pNext->pPrev = pNext->pPrev; 
					pNext->pPrev->pNext = pNext->pNext; 
					if (m_pCurrent == pNext) 
					{ 
						m_pCurrent = pNext->pNext; 
					} 
				} 
			} 
			m_Count--; 
 
			if (0 == m_pPreAllocator->Free(pNext)) 
			{ 
				return RET_FAIL; 
			} 
			RetCode = RET_SUCCESS; 
			break; 
		} 
		pNext = pNext->pNext; 
	} 
 
	return RetCode; 
} // Subtract() 
 
template int OLinkedListStatic::SubtractAllDup(T Element) 
{ 
	OElement *pNext; 
	OElement *pNextTemp; 
	int RetCode; 
 
	if (NULL == m_pHead) 
	{ 
		return RET_NO_ELEMENT; 
	} 
 
	RetCode = RET_NO_MATCH; 
	pNext = m_pHead; 
	while (NULL != pNext) 
	{ 
		pNextTemp = pNext->pNext; 
		if (RET_EQUAL == Compare((BYTE *)&pNext->Element, (BYTE *)&Element, sizeof (T))) 
		{ 
			if (NULL == pNext->pNext) 
			{ 
				if (NULL == pNext->pPrev) 
				{ 
					// There will be no element in the list. 
					m_pHead = NULL; 
					m_pTail = NULL; 
					m_pCurrent = NULL; 
					// m_Count = 0; see below 'm_Count--'. 
					pNextTemp = NULL; 
				} 
				else 
				{ 
					pNext->pPrev->pNext = NULL; 
					m_pTail = pNext->pPrev; 
					if (m_pCurrent == pNext) 
					{ 
						m_pCurrent = m_pTail; 
					} 
					pNextTemp = NULL; 
				} 
			} 
			else 
			{ 
				if (NULL == pNext->pPrev) 
				{ 
					m_pHead = pNextTemp = pNext->pNext; 
					pNext->pNext->pPrev = NULL; 
					if (m_pCurrent == pNext) 
					{ 
						m_pCurrent = m_pHead; 
					} 
				} 
				else 
				{ 
					pNext->pNext->pPrev = pNext->pPrev; 
					pNext->pPrev->pNext = pNextTemp = pNext->pNext; 
					if (m_pCurrent == pNext) 
					{ 
						m_pCurrent = pNext->pNext; 
					} 
				} 
			} 
			m_Count--; 
 
			if (0 == m_pPreAllocator->Free(pNext)) 
			{ 
				return RET_FAIL; 
			} 
			RetCode = RET_SUCCESS; 
 
			if (NULL == pNextTemp) 
			{ 
				break; 
			} 
		} 
		pNext = pNextTemp; 
	} 
 
	return RetCode; 
} // SubtractAllDup() 
 
template int OLinkedListStatic::SubtractFirst() 
{ 
	OElement *pNext; 
 
	if (NULL == m_pHead) 
	{ 
		return RET_NO_ELEMENT; 
	} 
 
	pNext = m_pHead; 
	if (NULL == pNext->pNext) 
	{ 
		m_pHead = NULL; 
		m_pTail = NULL; 
		m_pCurrent = NULL; 
	} 
	else 
	{ 
		pNext->pNext->pPrev = NULL; 
		m_pHead = pNext->pNext; 
		if (m_pCurrent == pNext) 
		{ 
			m_pCurrent = pNext->pNext; 
		} 
	} 
	m_Count--; 
	 
	if (0 == m_pPreAllocator->Free(pNext)) 
	{ 
		return RET_FAIL; 
	} 
 
	return RET_SUCCESS; 
} // SubtractFirst() 
 
template int OLinkedListStatic::SubtractCurrent() 
{ 
	OElement *pNext; 
 
	if (NULL == m_pCurrent) 
	{ 
		return RET_NO_ELEMENT; 
	} 
 
	pNext = m_pCurrent; 
	if (NULL == pNext->pNext) 
	{ 
		if (NULL == pNext->pPrev) 
		{ 
			m_pCurrent = m_pHead = m_pTail = NULL; 
		} 
		else 
		{ 
			pNext->pPrev->pNext = NULL; 
			m_pTail = m_pCurrent = pNext->pPrev; 
		} 
	} 
	else 
	{ 
		if (NULL == pNext->pPrev) 
		{ 
			m_pHead = m_pCurrent = pNext->pNext; 
			pNext->pNext->pPrev = NULL; 
			if (m_pCurrent == pNext) 
			{ 
				m_pCurrent = m_pHead; 
			} 
		} 
		else 
		{ 
			pNext->pNext->pPrev = pNext->pPrev; 
			pNext->pPrev->pNext = pNext->pNext; 
			if (m_pCurrent == pNext) 
			{ 
				m_pCurrent = pNext->pNext; 
			} 
		} 
	} 
	m_Count--; 
 
	if (0 == m_pPreAllocator->Free(pNext)) 
	{ 
		return RET_FAIL; 
	} 
 
	return RET_SUCCESS; 
} // SubtractCurrent() 
 
template int OLinkedListStatic::SubtractLast() 
{ 
	OElement *pNext; 
 
	if (NULL == m_pTail) 
	{ 
		return RET_NO_ELEMENT; 
	} 
 
	pNext = m_pTail; 
	if (NULL == pNext->pPrev) 
	{ 
		m_pHead = NULL; 
		m_pTail = NULL; 
		m_pCurrent = NULL; 
	} 
	else 
	{ 
		pNext->pPrev->pNext = NULL; 
		m_pTail = pNext->pPrev; 
		if (m_pCurrent == pNext) 
		{ 
			m_pCurrent = pNext->pPrev; 
		} 
	} 
	m_Count--; 
	 
	if (0 == m_pPreAllocator->Free(pNext)) 
	{ 
		return RET_FAIL; 
	} 
 
	return RET_SUCCESS; 
} // SubtractLast() 
 
template T *OLinkedListStatic::MoveFirst() 
{ 
	if (NULL == m_pHead) 
	{ 
		return NULL; 
	} 
	 
	m_pCurrent = m_pHead; 
	 
	return &m_pCurrent->Element; 
} // MoveFirst() 
 
template T *OLinkedListStatic::MoveLast() 
{ 
	if (NULL == m_pTail) 
	{ 
		return NULL; 
	} 
	 
	m_pCurrent = m_pTail; 
 
	return &m_pCurrent->Element; 
} // MoveLast() 
 
template T *OLinkedListStatic::MovePrev() 
{ 
	if (NULL == m_pCurrent || NULL == m_pCurrent->pPrev) 
	{ 
		return NULL; 
	} 
	 
	m_pCurrent = m_pCurrent->pPrev; 
 
	return &m_pCurrent->Element; 
} // MovePrev() 
 
template T *OLinkedListStatic::MoveNext() 
{ 
	if (NULL == m_pCurrent || NULL == m_pCurrent->pNext) 
	{ 
		return NULL; 
	} 
 
	m_pCurrent = m_pCurrent->pNext; 
 
	return &m_pCurrent->Element; 
} // MoveNext() 
 
template T *OLinkedListStatic::GetCurrent() 
{ 
	if (NULL == m_pCurrent) 
	{ 
		return NULL; 
	} 
 
	return &m_pCurrent->Element; 
} // GetCurrent() 
 
template DWORD OLinkedListStatic::GetCount() 
{ 
	return m_Count; 
} // GetCount() 
 
template int OLinkedListStatic::Reset() 
{ 
	OElement *pNext; 
	OElement *pNextTemp; 
 
	if (NULL != m_pHead) 
	{ 
		pNext = m_pHead; 
		while (NULL != pNext) 
		{ 
			pNextTemp = pNext->pNext; 
			if (0 == m_pPreAllocator->Free(pNext)) 
			{ 
				return RET_FAIL; 
			} 
			pNext = pNextTemp; 
		} 
	} 
 
	m_pHead = NULL; 
	m_pTail = NULL; 
	m_pCurrent = NULL; 
	m_Count = 0; 
 
	return RET_SUCCESS; 
} // Reset() 
 
template int OLinkedListStatic::Compare(BYTE *Compee, BYTE *Comper, DWORD Size) 
{ 
	DWORD LCounter; 
 
	for (LCounter = 0; LCounter < Size; LCounter++) 
	{ 
		if (*(Compee + LCounter) != *(Comper + LCounter)) 
		{ 
			return RET_NOT_EQUAL; 
		} 
	} 
 
	return RET_EQUAL; 
} // Compare() 
 
#endif // __LINKEDLISTSTATIC_H__