www.pudn.com > 221315556.rar > Support.h


#pragma once 
#include  
#include  
#include "public.h" 
class CSupport 
{ 
public: 
	CSupport(void); 
	~CSupport(void); 
}; 
 
inline int Getrand(int base) 
{ 
	int i = (int)((rand()*1.0f * base)/RAND_MAX); 
	return i; 
} 
//	dynamic, static,  
//	outsave, insave, 
template < int MAXCOUNT> 
class CIdMaker 
{ 
public: 
	CIdMaker() 
	{ 
		int i = 0; 
		for( i = 0;i < MAXCOUNT;i ++ ) 
		{ 
			m_NextFree[i] = i + 1; 
		} 
		m_NextFree[MAXCOUNT] = 0; 
		m_Free = 0; 
	} 
	~CIdMaker() 
	{ 
 
	} 
	int	GetId() 
	{ 
		int retid = m_Free +1; 
		if( retid <= 0 || retid > MAXCOUNT ) 
			return 0; 
		//if( m_NextFree[m_Free] == 0 ) 
		//	return 0; 
		m_Free = m_NextFree[m_Free]; 
		//m_NextFree[retid-1] = 0; 
		//printf( "GetId %d\n", retid ); 
		return retid; 
	} 
	BOOL DelId( int id ) 
	{ 
		if( id <= 0 || id > MAXCOUNT ) 
			return FALSE; 
		//if( m_NextFree[id-1] != 0 ) 
		//	return FALSE; 
		m_NextFree[id-1] = m_Free; 
		m_Free = id -1; 
		//printf( "DelId %d\n", id ); 
		return TRUE; 
	} 
private: 
	int	m_Free; 
	int m_NextFree[MAXCOUNT + 1]; 
}; 
typedef CHAR SSTRING[16]; 
 
template < int maxcount > 
class CIntHash 
{ 
	typedef struct __IHNode 
	{ 
		__IHNode *	pNext; 
		int		ivalue; 
		int		iptr; 
		USHORT	flag; 
		USHORT	High; 
	}IHNode,*PIHNode; 
public: 
	BOOL HAdd( int ikey, int ivalue ) 
	{ 
		USHORT	s1 = ikey & 0xffff; 
		USHORT	s2 = (ikey & 0xffff0000) >> 16; 
		PIHNode	pnode; 
		int p; 
		int		timecnt = 0; 
		if( m_HashBuffer[s1].flag == 0 ) 
		{ 
			m_HashBuffer[s1].ivalue = ivalue; 
			m_HashBuffer[s1].High = s2; 
			m_HashBuffer[s1].flag = 1; 
		} 
		else 
		{ 
			pnode = &m_HashBuffer[s1]; 
			while( pnode->pNext != NULL ) 
			{ 
				timecnt ++; 
				if( timecnt >= 1000 ) 
					return FALSE; 
				pnode = pnode->pNext; 
			} 
			p = m_IdMaker.GetId(); 
			//pnode->pNext = new IHNode; 
			pnode->pNext = &m_HashNodes[p]; 
			m_HashNodes[p].iptr = p; 
			//memset( (void*)pnode->pNext, 0, sizeof( IHNode )); 
			pnode->pNext->flag = 1; 
			pnode->pNext->ivalue = ivalue; 
			pnode->pNext->High = s2; 
			pnode->pNext->pNext = NULL; 
		} 
		return TRUE; 
		 
	}; 
	PIHNode Find( int ikey ) 
	{ 
		USHORT	s1 = ikey & 0xffff; 
		USHORT	s2 = (ikey & 0xffff0000) >> 16; 
		int timecnt = 0; 
		PIHNode pnode; 
		pnode = &m_HashBuffer[s1]; 
		while( NULL != pnode ) 
		{ 
			timecnt ++; 
			if( timecnt >= 1000 ) 
				return NULL; 
			if( pnode->flag != 0 ) 
			{ 
				if( pnode->High == s2 ) 
				{ 
					return pnode; 
				} 
			} 
			pnode = pnode->pNext; 
		} 
		return NULL; 
	}; 
	int HGet( int ikey ) 
	{ 
		PIHNode pnode = Find( ikey ); 
		if( pnode == NULL ) 
			return 0; 
		return pnode->ivalue; 
	}; 
	int HDel( int ikey ) 
	{ 
		USHORT	s1 = ikey & 0xffff; 
		USHORT	s2 = (ikey & 0xffff0000) >> 16; 
		int timecnt = 0; 
		PIHNode pnode,pnode2 = NULL; 
		pnode = &m_HashBuffer[s1]; 
		while( NULL != pnode ) 
		{ 
			timecnt ++; 
			if( timecnt >= 1000 ) 
				return FALSE; 
			if( pnode->flag != 0 ) 
			{ 
				if( pnode->High == s2 ) 
				{ 
					if( pnode2 == NULL ) 
					{ 
						pnode->flag = 0; 
						pnode->High = 0; 
						pnode->ivalue = 0; 
					} 
					else 
					{ 
						pnode2->pNext = pnode->pNext; 
						//delete pnode; 
						m_IdMaker.DelId( pnode->iptr ); 
					} 
					return TRUE; 
				} 
			} 
			pnode2 = pnode; 
			pnode = pnode->pNext; 
		} 
		return FALSE; 
	}; 
	CIntHash() 
	{ 
		memset( (void*)m_HashBuffer, 0, sizeof( IHNode ) * 0xffff ); 
	}; 
	~CIntHash() 
	{ 
	}; 
private: 
	IHNode	m_HashBuffer[0xffff]; 
	IHNode	m_HashNodes[maxcount+1]; 
	CIdMaker	m_IdMaker; 
}; 
template  
class CSuperList 
{ 
	typedef struct _slistnode 
	{ 
		_slistnode * pNext; 
		_slistnode * pLast; 
		T	*	pPtr; 
	}SLISTNODE; 
public: 
	CSuperList() 
	{ 
		m_pHead = 0; 
		m_pTail = 0; 
		m_Count = 0; 
		m_pCurrent = NULL; 
	} 
	~CSuperList() 
	{ 
	} 
	BOOL	Add( T * p ) 
	{ 
		int id = 0; 
		if( p == 0 ) 
		{ 
			//printf( "Can't add NULL ptr\n" ); 
			return FALSE; 
		} 
		id = m_IdMaker.GetId(); 
		if( id == 0 ) 
		{ 
			//printf( "Get a Zero id\n" ); 
			return FALSE; 
		} 
		//printf( "id = %d\n", id ); 
		m_PtrHash.HAdd( (int)p, id ); 
		if( m_pTail == NULL ) 
		{ 
			m_pHead = &m_Array[id]; 
			m_pTail = m_pHead; 
			m_pTail->pPtr = p; 
			m_pTail->pNext = 0; 
			m_pTail->pLast = 0; 
		} 
		else 
		{ 
			m_pTail->pNext = &m_Array[id]; 
			m_pTail->pNext->pLast = m_pTail; 
			m_pTail = m_pTail->pNext; 
			m_pTail->pPtr = p; 
			m_pTail->pNext = NULL; 
		} 
		m_Count ++; 
		return TRUE; 
	} 
	BOOL	Del( T * p ) 
	{ 
		if( p == NULL ) 
		{ 
			//printf( "Can't del a NULL ptr\n" ); 
			return FALSE; 
		} 
		int id = m_PtrHash.HGet( (int)p); 
		if( id == 0 ) 
		{ 
			//printf( "Hash get a zero id \n" ); 
			return FALSE; 
		} 
		if( m_Array[id].pPtr != p ) 
		{ 
			//printf( "The ptr is not the ptr in\n" ); 
			return FALSE; 
		} 
		if( DelNode( &m_Array[id] ) ) 
		{ 
			m_PtrHash.HDel( (int)p ); 
			m_IdMaker.DelId( id ); 
			return TRUE; 
		} 
		//printf( "Del node Error\n" ); 
		return FALSE; 
 
	} 
	T	*	Next( T * p ) 
	{ 
		if( p == NULL ) 
			return NULL; 
		int id = m_PtrHash.HGet( (int)p ); 
		if( id == 0 ) 
			return NULL; 
		if( m_Array[id].pPtr != p ) 
			return NULL; 
		m_pCurrent = m_Array[id].pNext; 
 
		return Current(); 
	} 
	T	*	Prev( T * p ) 
	{ 
		if( p == NULL ) 
			return NULL; 
		int id = m_PtrHash.HGet( (int)p ); 
		if( id == 0 ) 
			return NULL; 
		if( m_Array[id].pPtr != p ) 
			return NULL; 
		m_pCurrent = m_Array[id].pPrev; 
		return Current(); 
	} 
	T	*	Current() 
	{ 
		if( m_pCurrent == NULL ) 
			return NULL; 
		return m_pCurrent->pPtr; 
	} 
	T	*	First() 
	{ 
		m_pCurrent = m_pHead; 
		return Current(); 
	} 
	T	*	Last() 
	{ 
		m_pCurrent = m_pTail; 
		return Current(); 
	} 
private: 
	BOOL	DelNode( SLISTNODE * pNode ) 
	{ 
		if( pNode == NULL ) 
			return FALSE; 
		if( pNode->pLast != NULL ) 
			pNode->pLast->pNext = pNode->pNext; 
		if( pNode->pNext != NULL ) 
			pNode->pNext->pLast = pNode->pLast; 
		 
		m_Count--; 
		if( m_Count == 0 ) 
		{ 
			m_pTail = NULL; 
			m_pHead = NULL; 
		} 
		return TRUE; 
	} 
	SLISTNODE * m_pHead; 
	SLISTNODE * m_pTail; 
	SLISTNODE * m_pCurrent; 
	SLISTNODE	m_Array[MaxCount+1]; 
	CIntHash	m_PtrHash; 
	int			m_Count; 
	CIdMaker	m_IdMaker; 
 
}; 
class CLockableObject 
{ 
public: 
	CLockableObject(){} 
	virtual	~CLockableObject(){} 
	virtual	void Lock() = 0; 
	virtual	void Unlock() = 0; 
}; 
class CriticalSection:public CLockableObject 
{ 
public: 
	CriticalSection() 
	{ 
		InitializeCriticalSection( &m_critical_sec ); 
	}; 
	~CriticalSection() 
	{ 
		DeleteCriticalSection( &m_critical_sec ); 
	}; 
	virtual void Lock() 
	{ 
		EnterCriticalSection( &m_critical_sec ); 
	} 
	virtual void Unlock() 
	{ 
		LeaveCriticalSection( &m_critical_sec ); 
	} 
private: 
	CRITICAL_SECTION	m_critical_sec; 
}; 
class Lock 
{ 
public: 
	Lock(CLockableObject * pLockable) 
	{ 
		m_pLockable = pLockable; 
		m_pLockable->Lock(); 
	} 
	~Lock() 
	{ 
		m_pLockable->Unlock(); 
	} 
private: 
	CLockableObject * m_pLockable; 
}; 
 
class CriticalSectionLock 
{ 
public: 
	CriticalSectionLock( CRITICAL_SECTION	*	pCritSect ) 
	{ 
		m_pCritSect = pCritSect; 
		EnterCriticalSection( pCritSect ); 
	} 
	~CriticalSectionLock() 
	{ 
		LeaveCriticalSection( m_pCritSect ); 
	} 
private: 
	CRITICAL_SECTION	*	m_pCritSect; 
}; 
 
 
 
template < class T , int MAXCOUNT> 
class CIndexList 
{ 
	typedef struct	_node_ 
	{ 
		T				data; 
		_node_	*		pnext; 
		_node_	*		pprev; 
		unsigned int	nextfree; 
	}st_node; 
public: 
	CIndexList() 
	{ 
		//int	i = 0; 
		m_pArray = NULL; 
		m_pArray = new st_node[MAXCOUNT + 1]; 
 
		Clean(); 
	} 
	BOOL Clean() 
	{ 
		int	i = 0; 
 
		for( i = 0;i <= MAXCOUNT;i ++ ) 
		{ 
			m_pArray[i].pnext = NULL; 
			m_pArray[i].pprev = NULL; 
			m_pArray[i].nextfree = i + 1; 
		} 
		m_pArray[MAXCOUNT].nextfree = 0; 
		m_pArray[MAXCOUNT].pnext = NULL; 
		m_pArray[MAXCOUNT].pprev = NULL; 
		m_free = 1; 
		m_pHead = &m_pArray[0]; 
		m_pTail = m_pHead; 
		m_pThrough = m_pHead; 
		m_totel = 0; 
		return TRUE; 
	} 
	virtual ~CIndexList() 
	{ 
//		Lock m_lock(&m_CriticalSection); 
		if( m_pArray != NULL ) 
			delete []m_pArray; 
	} 
 
public: 
	unsigned int GetCount() 
	{ 
		Lock m_lock(&m_CriticalSection); 
		return m_totel; 
	} 
	int Reset() 
	{ 
		Lock m_lock(&m_CriticalSection); 
		m_pThrough = m_pHead; 
		return 1; 
	} 
 
	T * First() 
	{ 
		Lock m_lock(&m_CriticalSection); 
		if( m_pHead == NULL ) 
			return NULL; 
		m_pThrough = m_pHead->pnext; 
		if( m_pThrough != NULL ) 
			return &m_pThrough->data; 
		return NULL; 
	} 
	T * Cur() 
	{ 
		Lock m_lock(&m_CriticalSection); 
		if( m_pThrough != NULL ) 
			return &m_pThrough->data; 
		return NULL; 
	} 
	T * Next() 
	{ 
		Lock m_lock(&m_CriticalSection); 
		if( m_pThrough != NULL ) 
			m_pThrough = m_pThrough->pnext; 
		if( m_pThrough != NULL ) 
			return &m_pThrough->data; 
		return NULL; 
	} 
	T * End() 
	{ 
		Lock m_lock(&m_CriticalSection); 
		if( m_pTail != NULL ) 
			return &m_pTail->data; 
		return NULL; 
	} 
	unsigned int New( T ** t ) 
	{ 
		Lock m_lock(&m_CriticalSection); 
		unsigned int id = 0; 
		id = AllocId(); 
		if( id == 0 || id > MAXCOUNT ) 
			return 0; 
		*t = &m_pArray[id].data; 
		m_pTail->pnext = &m_pArray[id]; 
		m_pArray[id].pprev = m_pTail; 
		m_pArray[id].pnext = NULL; 
		m_pTail = &m_pArray[id]; 
		m_totel ++; 
		return id; 
	} 
	int	Del( unsigned int id ) 
	{ 
		Lock m_lock(&m_CriticalSection); 
		if( id > MAXCOUNT || id == 0 ) 
			return 0; 
 
		if( m_pArray[id].pnext != NULL ) 
			m_pArray[id].pnext->pprev = m_pArray[id].pprev; 
 
		if( m_pArray[id].pprev != NULL ) 
			m_pArray[id].pprev->pnext = m_pArray[id].pnext; 
 
		if( m_pTail == &m_pArray[id] ) 
		{ 
			m_pTail = m_pTail->pprev; 
		} 
 
		m_pArray[id].pprev = NULL; 
		m_pArray[id].pnext = NULL; 
 
		ResaveId( id ); 
		m_totel --; 
		return 1; 
	} 
	T *	Get( unsigned int id ) 
	{ 
		Lock m_lock(&m_CriticalSection); 
		if( id <= MAXCOUNT ) 
			return &m_pArray[id].data; 
		return NULL; 
	} 
private: 
	unsigned int AllocId() 
	{ 
		Lock m_lock(&m_CriticalSection); 
		unsigned int ret = m_free; 
		if( ret != 0 ) 
			m_free = m_pArray[ret].nextfree; 
		return ret; 
	} 
	int ResaveId( unsigned int id ) 
	{ 
		Lock m_lock(&m_CriticalSection); 
		if( id >= MAXCOUNT || id == 0 ) 
			return 0; 
		m_pArray[id].nextfree = m_free; 
		m_free = id; 
		return 1; 
	} 
private: 
	CriticalSection	m_CriticalSection; 
	unsigned int	m_free; 
	unsigned int	m_totel; 
	st_node	*		m_pArray; 
	st_node *		m_pHead; 
	st_node *		m_pThrough; 
	st_node *		m_pTail; 
}; 
class CSimpleMsgQueue 
{ 
public: 
	BOOL Clean() 
	{ 
		m_Getptr = 0; 
		m_Putptr = 0; 
		return TRUE; 
	}; 
	BOOL	SaveMsg( char * msgbuf, int len ) 
	{ 
		int leftlen = 0; 
		int continuelen = 0; 
		if( len <= 0 ) 
			return FALSE; 
		if( m_Putptr >= m_Getptr ) 
		{ 
			continuelen = MAXCLIENTBUFFER - m_Putptr; 
			leftlen = continuelen + m_Getptr; 
			if( len > leftlen ) 
				return FALSE; 
			if( len > continuelen ) 
			{ 
				memcpy( &this->m_MsgBuffer[m_Putptr], msgbuf, continuelen ); 
				memcpy( this->m_MsgBuffer, msgbuf, len - continuelen ); 
			} 
			else 
			{ 
				memcpy( &this->m_MsgBuffer[m_Putptr], msgbuf, len ); 
			} 
		} 
		else 
		{ 
			continuelen = m_Getptr - m_Putptr; 
			leftlen = continuelen; 
			if( len > leftlen ) 
				return FALSE; 
			memcpy( &this->m_MsgBuffer[m_Putptr], msgbuf, len ); 
		} 
 
		m_Putptr = (m_Putptr + len) % MAXCLIENTBUFFER; 
		//printf( "Put msg put = %d get = %d\n", m_Putptr, m_Getptr ); 
		return TRUE; 
	}; 
	//int	GetMoreMsg( SCMSG	*	pMsgArray, int Count) 
	//{ 
	//	int leftlen = 0; 
	//	char * buf = (char *)pmsg; 
	//	int continuelen = 0; 
	//	if( m_Getptr == m_Putptr ) 
	//		return FALSE; 
	//	if( m_Putptr > m_Getptr ) 
	//	{ 
	//		continuelen = m_Putptr - m_Getptr; 
	//		leftlen = continuelen; 
	//		if( MSGLENGTH > leftlen ) 
	//			return FALSE; 
	//		memcpy( (void*)buf, &this->m_MsgBuffer[m_Getptr], MSGLENGTH ); 
	//	} 
	//	else 
	//	{ 
	//		continuelen = MAXCLIENTBUFFER - m_Getptr; 
	//		leftlen = m_Putptr + continuelen; 
	//		if( MSGLENGTH > leftlen ) 
	//			return FALSE; 
	//		if( MSGLENGTH > continuelen ) 
	//		{ 
	//			memcpy( (void*)buf, &this->m_MsgBuffer[m_Getptr], continuelen); 
	//			memcpy( (void*)&buf[continuelen], (void*)this->m_MsgBuffer, MSGLENGTH - continuelen ); 
	//		} 
	//		else 
	//		{ 
	//			memcpy( (void*)buf, &this->m_MsgBuffer[m_Getptr], MSGLENGTH ); 
	//		} 
	//	} 
 
	//	m_Getptr = (m_Getptr + MSGLENGTH) % MAXCLIENTBUFFER; 
 
	//	return TRUE; 
	//} 
	BOOL	GetMsg( SCMSG	*	pmsg, INT	&nMaxCount) 
	{ 
		int requestlength = nMaxCount * MSGLENGTH; 
		int leftlen = 0; 
		char * buf = (char *)pmsg; 
		int continuelen = 0; 
		if( m_Getptr == m_Putptr ) 
			return FALSE; 
		if( m_Putptr > m_Getptr ) 
		{ 
			continuelen = m_Putptr - m_Getptr; 
			leftlen = continuelen; 
			if( MSGLENGTH > leftlen ) 
				return FALSE;	//	一条消息都没有,返回false 
			leftlen /= MSGLENGTH; 
			if(leftlen > nMaxCount ) 
				leftlen = nMaxCount; 
			else 
				nMaxCount = leftlen; 
			leftlen *= MSGLENGTH; 
			memcpy( (void*)buf, &this->m_MsgBuffer[m_Getptr], leftlen ); 
		} 
		else 
		{ 
			continuelen = MAXCLIENTBUFFER - m_Getptr; 
			leftlen = m_Putptr + continuelen; 
			if( MSGLENGTH > leftlen ) 
				return FALSE;	//	一条消息都没有,返回false 
			leftlen /= MSGLENGTH; 
			if( leftlen > nMaxCount ) 
				leftlen = nMaxCount; 
			else 
				nMaxCount = leftlen; 
			leftlen *= MSGLENGTH; 
 
			if( leftlen > continuelen ) 
			{ 
				memcpy( (void*)buf, &this->m_MsgBuffer[m_Getptr], continuelen); 
				memcpy( (void*)&buf[continuelen], (void*)this->m_MsgBuffer, leftlen - continuelen ); 
			} 
			else 
			{ 
				memcpy( (void*)buf, &this->m_MsgBuffer[m_Getptr], leftlen ); 
			} 
		} 
 
		m_Getptr = (m_Getptr + leftlen) % MAXCLIENTBUFFER; 
 
		return TRUE;	 
	} 
	BOOL	GetMsg( SCMSG * pmsg ) 
	{ 
		int leftlen = 0; 
		char * buf = (char *)pmsg; 
		int continuelen = 0; 
		if( m_Getptr == m_Putptr ) 
			return FALSE; 
		if( m_Putptr > m_Getptr ) 
		{ 
			continuelen = m_Putptr - m_Getptr; 
			leftlen = continuelen; 
			if( MSGLENGTH > leftlen ) 
				return FALSE; 
			memcpy( (void*)buf, &this->m_MsgBuffer[m_Getptr], MSGLENGTH ); 
		} 
		else 
		{ 
			continuelen = MAXCLIENTBUFFER - m_Getptr; 
			leftlen = m_Putptr + continuelen; 
			if( MSGLENGTH > leftlen ) 
				return FALSE; 
			if( MSGLENGTH > continuelen ) 
			{ 
				memcpy( (void*)buf, &this->m_MsgBuffer[m_Getptr], continuelen); 
				memcpy( (void*)&buf[continuelen], (void*)this->m_MsgBuffer, MSGLENGTH - continuelen ); 
			} 
			else 
			{ 
				memcpy( (void*)buf, &this->m_MsgBuffer[m_Getptr], MSGLENGTH ); 
			} 
		} 
		 
		m_Getptr = (m_Getptr + MSGLENGTH) % MAXCLIENTBUFFER; 
 
		return TRUE; 
	}; 
	CSimpleMsgQueue() 
	{ 
		m_Getptr = 0; 
		m_Putptr = 0; 
	}; 
	~CSimpleMsgQueue() 
	{ 
	}; 
private: 
	UINT	m_Getptr; 
	UINT	m_Putptr; 
	CHAR	m_MsgBuffer[MSGLENGTH * 1024]; 
}; 
template  
class CComplexMsgQueue 
{ 
public: 
	BOOL Clean() 
	{ 
		m_Getptr = 0; 
		m_Putptr = 0; 
		return TRUE; 
	}; 
	BOOL	SaveMsg( char * msgbuf, int len ) 
	{ 
		int leftlen = 0; 
		int continuelen = 0; 
		if( len <= 0 ) 
			return FALSE; 
		if( m_Putptr >= m_Getptr ) 
		{ 
			continuelen = m_MaxBufferSize - m_Putptr; 
			leftlen = continuelen + m_Getptr; 
			if( len > leftlen ) 
				return FALSE; 
			if( len > continuelen ) 
			{ 
				memcpy( &this->m_MsgBuffer[m_Putptr], msgbuf, continuelen ); 
				memcpy( this->m_MsgBuffer, msgbuf, len - continuelen ); 
			} 
			else 
			{ 
				memcpy( &this->m_MsgBuffer[m_Putptr], msgbuf, len ); 
			} 
		} 
		else 
		{ 
			continuelen = m_Getptr - m_Putptr; 
			leftlen = continuelen; 
			if( len > leftlen ) 
				return FALSE; 
			memcpy( &this->m_MsgBuffer[m_Putptr], msgbuf, len ); 
		} 
 
		m_Putptr = (m_Putptr + len) % m_MaxBufferSize; 
		//printf( "Put msg put = %d get = %d\n", m_Putptr, m_Getptr ); 
		return TRUE; 
	}; 
	BOOL	GetMsg( T * pmsg ) 
	{ 
		int leftlen = 0; 
		char * buf = (char *)pmsg; 
		int continuelen = 0; 
		if( m_Getptr == m_Putptr ) 
			return FALSE; 
		if( m_Putptr > m_Getptr ) 
		{ 
			continuelen = m_Putptr - m_Getptr; 
			leftlen = continuelen; 
			if( m_MsgLength > leftlen ) 
				return FALSE; 
			memcpy( (void*)buf, &this->m_MsgBuffer[m_Getptr], m_MsgLength ); 
		} 
		else 
		{ 
			continuelen = m_MaxBufferSize - m_Getptr; 
			leftlen = m_Putptr + continuelen; 
			if( m_MsgLength > leftlen ) 
				return FALSE; 
			if( m_MsgLength > continuelen ) 
			{ 
				memcpy( (void*)buf, &this->m_MsgBuffer[m_Getptr], continuelen); 
				memcpy( (void*)&buf[continuelen], (void*)this->m_MsgBuffer, m_MsgLength - continuelen ); 
			} 
			else 
			{ 
				memcpy( (void*)buf, &this->m_MsgBuffer[m_Getptr], m_MsgLength ); 
			} 
		} 
 
		m_Getptr = (m_Getptr + m_MsgLength) % m_MaxBufferSize; 
 
		return TRUE; 
	}; 
	CComplexMsgQueue():m_MsgLength(sizeof(T)),m_MaxBufferSize(sizeof(T)*Maxlength) 
	{ 
		m_Getptr = 0; 
		m_Putptr = 0; 
	}; 
	~CComplexMsgQueue() 
	{ 
	}; 
private: 
	UINT	m_Getptr; 
	UINT	m_Putptr; 
	const	int m_MsgLength;// = sizeof( T); 
	const	int m_MaxBufferSize;// = sizeof(T)*Maxlength; 
	CHAR	m_MsgBuffer[sizeof(T) * Maxlength]; 
}; 
 
template < class T , int MAXCOUNT> 
class CDataQueue   
{ 
public: 
	unsigned int GetCount() 
	{ 
		return (unsigned int )(( m_pPut + m_nMax - m_pGet )%m_nMax ); 
	} 
	BOOL GetData(T *msg) 
	{ 
		if(	msg == NULL)return FALSE; 
		if( m_pGet == m_pPut) return FALSE; 
		memcpy((void*)msg,(void*)&m_pdataqueue[m_pGet],sizeof( T )); 
		m_pGet++; 
		if( m_pGet >= m_nMAX ) m_pGet = 0; 
		return TRUE; 
	}; 
	BOOL PutData(T *msg) 
	{ 
		if(msg == NULL)return FALSE; 
		memcpy((void*)&m_pdataqueue[m_pPut],(void*)msg,sizeof( T )); 
		m_pPut ++; 
		if(m_pPut >= m_nMAX)m_pPut = 0; 
		return TRUE; 
	}; 
	void	Clear()				 
	{ 
		m_pGet = 0; 
		m_pPut = 0; 
	} 
	CDataQueue() 
	{ 
		//printf( "CDataQueue() max count is %d\n" , MAXCOUNT); 
		m_pdataqueue = new T[MAXCOUNT]; 
		m_nMAX = MAXCOUNT; 
		m_pGet = 0; 
		m_pPut = 0; 
	}; 
	virtual ~CDataQueue() 
	{ 
		if( m_pdataqueue != NULL ) 
			delete m_pdataqueue; 
	}; 
 
private: 
	int	m_pGet; 
	int	m_pPut; 
	T	* m_pdataqueue; 
	int	m_nMAX; 
}; 
class CNameHash 
{ 
	typedef struct	_2_hashnode 
	{ 
		_2_hashnode * pNext; 
		LPVOID				data; 
		SSTRING			key; 
		UINT					id; 
	}HashNode2; 
public: 
	CNameHash() 
	{ 
		memset( (void*)m_HashData, 0, sizeof( HashNode2 ) * 0xffff ); 
		m_Count = 0; 
	} 
	~CNameHash() 
	{ 
	} 
protected: 
	HashNode2	m_HashData[0xffff]; 
	int				m_Count; 
	CIndexList	m_HashDataMollocer; 
private: 
	HashNode2 * NewNode() 
	{ 
		HashNode2 * p; 
		UINT	id = m_HashDataMollocer.New(&p); 
		if( id == 0) 
			return 0; 
		p->id = id; 
		memset( (void*)p, 0, sizeof( HashNode2)); 
		return (p); 
	} 
	void				DelNode( HashNode2 * pNode ) 
	{ 
		if( pNode == 0 ) 
			return; 
		m_HashDataMollocer.Del(pNode->id); 
	} 
	BOOL	Del( HashNode2 * pNode) 
	{ 
		return FALSE; 
	} 
	HashNode2 * FindLastByCode( char * key, WORD wHashCode ) 
	{ 
		//SSTRING	s; 
		int time=0; 
		HashNode2 * pNode = &m_HashData[wHashCode]; 
		//strncpy( s, key, 16 ); 
		while( (pNode->pNext != NULL) && time < 1000) 
		{ 
			if( pNode->pNext->data != 0) 
			{ 
				if( strncmp( key, pNode->pNext->key, 16) == 0 ) 
				{ 
					return pNode; 
				} 
			} 
			pNode = pNode->pNext; 
			time ++; 
		} 
		return NULL; 
	} 
	HashNode2 * Find( char * key ) 
	{ 
		WORD	wCode = MakeHashCode(key); 
		return FindByCode(key, wCode); 
	} 
	HashNode2 * FindByCode( char * key, WORD	wHashCode) 
	{ 
		//SSTRING	s; 
		int time=0; 
		HashNode2 * pNode = &m_HashData[wHashCode]; 
		//strncpy( s, key, 16 ); 
		while( (pNode != NULL) && time < 1000) 
		{ 
			if( pNode->data != 0) 
			{ 
				if( strncmp( key, pNode->key, 16) == 0 ) 
				{ 
					return pNode; 
				} 
			} 
			pNode = pNode->pNext; 
			time ++; 
		} 
		return NULL; 
	} 
	WORD	MakeHashCode( char * key) 
	{ 
		int i = 0; 
		SSTRING	s; 
		WORD	t = 0,*	p = (WORD*)&s; 
		strncpy( s, key, 16 ); 
		for( i = 0;i < 8;i ++ ) 
		{ 
			t ^= p[i]; 
		} 
		return t; 
	} 
public: 
	BOOL	HAdd( char * key, LPVOID lpValue ) 
	{ 
		if( key == NULL ) 
			return FALSE; 
		if( lpValue == NULL ) 
			return FALSE; 
		WORD	wHashCode = MakeHashCode(key); 
		if( FindByCode(key, wHashCode)!= NULL) 
			return FALSE; 
		HashNode2 * pNode = &m_HashData[wHashCode], * pNextNode = pNode->pNext; 
		if( pNode->data != NULL ) 
		{ 
			pNode->pNext  = NewNode(); 
			pNode = pNode->pNext; 
			pNode->pNext = pNextNode; 
		} 
		strncpy( pNode->key, key, 16); 
		pNode->data = lpValue; 
		m_Count ++; 
		return TRUE; 
	} 
	BOOL	HDel( char * key ) 
	{ 
		HashNode2	* pNode; 
		WORD	wCode = MakeHashCode(key); 
		pNode = FindLastByCode(key, wCode); 
		if( pNode == NULL ) 
		{ 
			if( strncmp( m_HashData[wCode].key, key, 16 ) == 0 ) 
			{ 
				m_HashData[wCode].data = 0; 
			} 
			else 
			{ 
				return FALSE; 
			} 
		} 
		else 
		{ 
			HashNode2 * p2 = pNode->pNext; 
			pNode->pNext = pNode->pNext->pNext; 
			p2->data = 0; 
			DelNode( p2 ); 
		} 
		m_Count --; 
		return TRUE; 
	} 
	LPVOID HGet(char * key ) 
	{ 
		WORD	wCode = MakeHashCode(key); 
		HashNode2 * pNode = FindByCode(key, wCode); 
		if( pNode != NULL ) 
			return pNode->data; 
		return NULL; 
	} 
};