gusucode.com > 通用协议编解码模块C#源码程序 > 通用协议编解码模块/codec_src/Codec_src/MsgCodec/MsgNode.cpp

    // MsgNode.cpp: implementation of the CMsgNode class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MsgNode.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


IMPLEMENT_OBJECT_CUSTOM_INIT(CMsgNode)

CMsgNode::CMsgNode()
{
	::memset(&m_PosInfo, 0, sizeof(m_PosInfo));
	m_mntNodeType = mntUnknown;
	m_pRoot = NULL;
	m_pParent = NULL;
	m_pEnumTable = NULL;
	m_bFixLength = TRUE;
}

CMsgNode::~CMsgNode()
{
	ClearChildren();
}

BOOL CMsgNode::NeedRefresh()
{
	return m_pRoot->RefreshNodes();
}

BOOL CMsgNode::GetValue(DWORD &nValue)
{
	if (m_pRoot)
	{
		switch (m_mntNodeType)
		{
		case (mntNumber):
			return m_pRoot->GetMsgSeg(	&nValue, 
										m_PosInfo.nByteStart, 
										m_PosInfo.nBitStart, 
										m_PosInfo.nBitLen);

		default:
#ifdef _DEBUG
		TRACE("Error: Get Number Error in node - %s @%d:%d;%dbit\n", 
			m_strNodeName, m_PosInfo.nByteStart, m_PosInfo.nBitStart, m_PosInfo.nBitLen);
#endif //_DEBUG
			break;
		}
	}
	return FALSE;
}

BOOL CMsgNode::GetValue(const BYTE** pszValue, LONG &nByteLength)
{
	if (! pszValue)
		return FALSE;

	if (m_pRoot)
	{
		switch (m_mntNodeType)
		{
		case (mntOctet):
		case (mntASCII):
		case (mntBCD):
			if (m_pRoot->GetMsgSeg(pszValue, m_PosInfo.nByteStart, m_PosInfo.nBitLen / 8))
			{
				nByteLength = m_PosInfo.nBitLen / 8;
				return TRUE;
			}

		default:
#ifdef _DEBUG
		TRACE("Error: Get String Error in node - %s @%d;%dbyte\n",
			m_strNodeName, m_PosInfo.nByteStart, m_PosInfo.nBitLen / 8);
#endif //_DEBUG
			break;
		}
	}
	return FALSE;
}

BOOL CMsgNode::SetValue(DWORD nValue)
{
	if (m_pRoot)
	{
		switch (m_mntNodeType)
		{
		case (mntNumber):
			return m_pRoot->SetMsgSeg(	nValue, 
										m_PosInfo.nByteStart, 
										m_PosInfo.nBitStart, 
										m_PosInfo.nBitLen);

		default:
#ifdef _DEBUG
		TRACE("Error: Set Number Error in node - %s @%d:%d;%dbit\n", 
			m_strNodeName, m_PosInfo.nByteStart, m_PosInfo.nBitStart, m_PosInfo.nBitLen);
#endif //_DEBUG
			break;
		}
	}
	return FALSE;
}

BOOL CMsgNode::SetValue(const BYTE* szValue, LONG nByteLength)
{
	if (m_pRoot)
	{
		switch (m_mntNodeType)
		{
		case (mntOctet):
		case (mntASCII):
		case (mntBCD):
			if ((!m_bFixLength) || (nByteLength == (m_PosInfo.nBitLen / 8)))
			{
				if (szValue || (nByteLength == 0))
				{
					if (m_pRoot->SetMsgSeg(szValue, m_PosInfo.nByteStart, m_PosInfo.nBitLen / 8, nByteLength))
					{
						if ((m_PosInfo.nBitLen != nByteLength * 8) || (GetChildCount() > 0))
						{
							//	The Length of Source message was changed
							m_PosInfo.nBitLen = nByteLength * 8;
						}
						return TRUE;
					}
				}
			}

		default:
#ifdef _DEBUG
		TRACE("Error: Set String Error in node - %s @%d;%dbyte\n",
			m_strNodeName, m_PosInfo.nByteStart, m_PosInfo.nBitLen / 8);
#endif //_DEBUG
			break;
		}
	}
	return FALSE;
}

BOOL CMsgNode::ClearChildren()
{
	IMsgNode *pNode = NULL;
	while (! m_ChildrenList.IsEmpty())
	{
		m_ChildrenList.RemoveTail()->DestroyInstance();
	}
	return TRUE;
}

BOOL CMsgNode::LockMsg(DWORD nTimeOut)
{
	if (m_pRoot)
		return m_pRoot->LockMsg(nTimeOut);
	return FALSE;
}

BOOL CMsgNode::UnlockMsg()
{
	if (m_pRoot)
		return m_pRoot->UnlockMsg();
	return FALSE;
}

UINT CMsgNode::PrepareDecode(LONG &nByteStart, LONG &nBitStart)
{
	//	To Do: Calculate the Message Length, Position, etc.
	m_PosInfo.nByteStart = nByteStart;
	m_PosInfo.nBitStart = nBitStart;

	//	To Do: Create Children if any.

	return CDC_OK;
}

UINT CMsgNode::Decoding(LONG &nByteStart, LONG &nBitStart)
{
	// To Do: Decode the Source Message
	return CDC_OK;
}

UINT CMsgNode::FinishDecode(LONG &nByteStart, LONG &nBitStart)
{
	//	To Do: Calculate the New position of the Decode progress
	nByteStart = m_PosInfo.nByteStart + (m_PosInfo.nBitStart + m_PosInfo.nBitLen) / 8;
	nBitStart = (m_PosInfo.nBitStart + m_PosInfo.nBitLen) % 8;

	return CDC_OK;
}

BOOL CMsgNode::InstantNode(LPCTSTR szNodeName, LPCTSTR szParam)
{
	m_strNodeName = szNodeName;

	if (szParam)
		return ParseParam(szParam);

	return TRUE;
}

BOOL CMsgNode::InitInstance(IPrivateBlock *pRoot, IMsgNode *pParent)
{
	m_pRoot = pRoot;
	m_pParent = pParent;
	return TRUE;
}

UINT CMsgNode::RefreshNode(LONG &nByteStart, LONG &nBitStart)
{
	if (! (m_pRoot))
	{
#ifdef _DEBUG
		TRACE("Error: No Root Node in node - %s\n", m_strNodeName);
#endif //_DEBUG
		return CDC_INNER_ERROR;
	}

	UINT nResult = PrepareDecode(nByteStart, nBitStart);
//	if (nResult == CDC_OK)
	{
		nResult = Decoding(nByteStart, nBitStart);
//		if (nResult == CDC_OK)
		{
			nResult = FinishDecode(nByteStart, nBitStart);
		}
	}

	return nResult;
}

IMsgNodeInfo* CMsgNode::GetNodeInfo()
{
	return this;
}

BOOL CMsgNode::GetNodeValue(BYTE &nValue)
{
	BOOL bResult = FALSE;
	if (LockMsg())
	{
		if (m_PosInfo.nBitLen <= sizeof(BYTE) * 8)
		{
			DWORD nDW = 0;
			if (bResult = GetValue(nDW))
				nValue = (BYTE)nDW;
		}
		else
		{
#ifdef _DEBUG
		TRACE("Error: Buff too small when get Byte value of %d\n", m_strNodeName);
#endif //_DEBUG
		}
		UnlockMsg();
	}
	return bResult;
}

BOOL CMsgNode::GetNodeValue(WORD &nValue)
{
	BOOL bResult = FALSE;
	if (LockMsg())
	{
		if (m_PosInfo.nBitLen <= sizeof(WORD) * 8)
		{
			DWORD nDW = 0;
			if (bResult = GetValue(nDW))
				nValue = (WORD)nDW;
		}
		else
		{
#ifdef _DEBUG
		TRACE("Error: Buff too small when get Word value of %d\n", m_strNodeName);
#endif //_DEBUG
		}
		UnlockMsg();
	}
	return bResult;
}

BOOL CMsgNode::GetNodeValue(DWORD &nValue)
{
	BOOL bResult = FALSE;
	if (LockMsg())
	{
		if (m_PosInfo.nBitLen <= sizeof(DWORD) * 8)
		{
			DWORD nDW = 0;
			if (bResult = GetValue(nDW))
				nValue = (DWORD)nDW;
		}
		else
		{
#ifdef _DEBUG
		TRACE("Error: Buff too small when get DWord value of %d\n", m_strNodeName);
#endif //_DEBUG
		}
		UnlockMsg();
	}
	return bResult;
}

BOOL CMsgNode::GetNodeValue(const BYTE** ppBuff, LONG &nBuffLen)
{
	BOOL bResult = FALSE;
	if (LockMsg())
	{
		if ((m_PosInfo.nBitStart == 0) && (m_PosInfo.nBitLen % 8 == 0))
		{
			bResult = GetValue(ppBuff, nBuffLen);
		}
		else
		{
#ifdef _DEBUG
		TRACE("Error: Get String value of %s\n", m_strNodeName);
#endif //_DEBUG
		}
		UnlockMsg();
	}
	return bResult;
}

BOOL CMsgNode::GetNodeValue(IBase* pObj)
{
#ifdef _DEBUG
		TRACE("Error: Get Custum value of %s\n", m_strNodeName);
#endif //_DEBUG
	return FALSE;
}

BOOL CMsgNode::SetNodeValue(BYTE nValue)
{
	BOOL bResult = FALSE;
	if (LockMsg())
	{
		bResult = SetValue(nValue);
		m_pRoot->RefreshNodes();
		UnlockMsg();
	}
	NeedRefresh();	//	Redecode!
	return bResult;
}

BOOL CMsgNode::SetNodeValue(WORD nValue)
{
	BOOL bResult = FALSE;
	if (LockMsg())
	{
		bResult = SetValue(nValue);
		m_pRoot->RefreshNodes();
		UnlockMsg();
	}
	NeedRefresh();	//	Redecode!
	return bResult;
}

BOOL CMsgNode::SetNodeValue(DWORD nValue)
{
	BOOL bResult = FALSE;
	if (LockMsg())
	{
		bResult = SetValue(nValue);
		UnlockMsg();
	}
	NeedRefresh();	//	Redecode!
	return bResult;
}

BOOL CMsgNode::SetNodeValue(const BYTE* pBuff, LONG nBuffLen)
{
	BOOL bResult = FALSE;
	if (LockMsg())
	{
		if ((m_PosInfo.nBitStart == 0) && (m_PosInfo.nBitLen % 8 == 0))
		{
			bResult = SetValue(pBuff, nBuffLen);
		}
		else
		{
#ifdef _DEBUG
		TRACE("Error: Set String value of %s\n", m_strNodeName);
#endif //_DEBUG
		}
		UnlockMsg();
	}
	NeedRefresh();	//	Redecode!
	return bResult;
}

BOOL CMsgNode::SetNodeValue(IBase* pObj)
{
#ifdef _DEBUG
		TRACE("Error: Set Custum value of %s\n", m_strNodeName);
#endif //_DEBUG
	NeedRefresh();	//	Redecode!
	return FALSE;
}

IMsgNode* CMsgNode::GetParentNode()
{
	IMsgNode* pNode = NULL;
	if (LockMsg())
	{
		pNode = m_pParent;
		UnlockMsg();
	}
	return pNode;
}

IMsgNode* CMsgNode::GetRootNode()
{
	IMsgNode* pNode = NULL;
	if (LockMsg())
	{
		m_pRoot->GetInterface(IN_IMsgNode, (void**)&pNode);
		UnlockMsg();
	}
	return pNode;
}

LONG CMsgNode::GetChildCount()
{
	LONG nCount = -1;
	if (LockMsg())
	{
		nCount = m_ChildrenList.GetCount();
		UnlockMsg();
	}
	return nCount;
}

COLPOS CMsgNode::FindChild(LONG nIndex)
{
	POSITION nPos = NULL;
	if (LockMsg())
	{
		if (nIndex < m_ChildrenList.GetCount())
		{
			nPos = m_ChildrenList.GetHeadPosition();
			while (nIndex --)
				m_ChildrenList.GetNext(nPos);
		}
		UnlockMsg();
	}
	return (COLPOS)nPos;
}

COLPOS CMsgNode::FindChild(LPCTSTR szName)
{
	POSITION nPos = NULL;
	if (LockMsg())
	{
		IMsgNode *pNode = NULL;
		POSITION posOld, pos = m_ChildrenList.GetHeadPosition();
		while (pos)
		{
			posOld = pos;
			pNode = m_ChildrenList.GetNext(pos);
			if (::strcmp(pNode->GetNodeInfo()->GetNodeName(), szName) == 0)
			{
				nPos = posOld;
				break;
			}
		}
		UnlockMsg();
	}
	return (COLPOS)nPos;
}

COLPOS CMsgNode::FindNextChild(COLPOS nPos)
{
	if (LockMsg())
	{
		POSITION pos = (POSITION)nPos;
		m_ChildrenList.GetNext(pos);
		nPos = (COLPOS)pos;
		UnlockMsg();
	}
	return nPos;
}

IMsgNode* CMsgNode::GetChildAt(COLPOS nPos)
{
	IMsgNode *pNode = NULL;
	if (LockMsg())
	{
		POSITION pos = (POSITION)nPos;
		pNode = m_ChildrenList.GetAt(pos);
		UnlockMsg();
	}
	return pNode;
}

LPCTSTR CMsgNode::GetChildNameAt(COLPOS nPos)
{
	LPCTSTR szName = NULL;
	if (LockMsg())
	{
		IMsgNode *pNode = GetChildAt(nPos);
		if (pNode)
			szName = pNode->GetNodeInfo()->GetNodeName();
		UnlockMsg();
	}
	return szName;
}

IMsgNode* CMsgNode::LocateNode(LPCTSTR szLocator)
{
	CString str = szLocator;
	if (str.GetLength() == 0)
		return this;

	IMsgNode* pNode = NULL;
	if (LockMsg())
	{
		if (szLocator)
		{
			if ((str.Left(1).Compare("\\") == 0) || (str.Left(1).Compare("/") == 0))
			{
				m_pRoot->GetInterface(IN_IMsgNode, (void**)&pNode);
				str = str.Right(str.GetLength() - 1);
			}
			else if ((str.Left(3).Compare("..\\") == 0) || (str.Left(3).Compare("../") == 0))
			{
				pNode = m_pParent;
				str = str.Right(str.GetLength() - 3);
			}
			else
			{
				INT nFind1 = str.Find('\\');
				INT nFind2 = str.Find('/');
				INT nKeyLen = min(nFind1, nFind2);
				if (nKeyLen < 0)
					nKeyLen = max(nFind1, nFind2);

				if (nKeyLen < 0)
					nKeyLen = str.GetLength();

				COLPOS nPos = FindChild(str.Left(nKeyLen));
				if (nPos)
				{
					pNode = GetChildAt(nPos);

					if (nKeyLen <= str.GetLength())
						str = str.Right(str.GetLength() - (nKeyLen+1));
					else
						str.Empty();
				}
			}

			if (pNode)
				pNode = pNode->LocateNode(str);
		}

		UnlockMsg();
	}
	return pNode;
}

LPCTSTR CMsgNode::GetNodeName()
{
	LPCTSTR szName = NULL;
	if (LockMsg())
	{
		szName = m_strNodeName;
		UnlockMsg();
	}
	return szName;
}

MsgNodeType CMsgNode::GetNodeType()
{
	MsgNodeType mntType = mntUnknown;
	if (LockMsg())
	{
		mntType = m_mntNodeType;
		UnlockMsg();
	}
	return mntType;
}

LONG CMsgNode::GetNodeLength(MsgLengthUnit mluUnit)
{
	LONG nLen = -1;
	if (LockMsg())
	{
		nLen = m_PosInfo.nBitLen;
		switch (mluUnit)
		{
		case (mluBit):
			break;
		case (mluByte):
			nLen /= 8;
			break;
		case (mluWord):
			nLen /= 16;
			break;
		case (mluDWord):
			nLen /= 32;
			break;
		default:
			nLen = -1;
		}
		UnlockMsg();
	}
	return nLen;
}

LONG CMsgNode::GetNodeByteStart()
{
	LONG nStart = -1;
	if (LockMsg())
	{
		nStart = m_PosInfo.nByteStart;
		UnlockMsg();
	}
	return nStart;
}

LONG CMsgNode::GetNodeBitStart()
{
	LONG nStart = -1;
	if (LockMsg())
	{
		nStart = m_PosInfo.nBitStart;
		UnlockMsg();
	}
	return nStart;
}

IEnumTable* CMsgNode::GetEnumTable()
{
	return m_pEnumTable;
}

//	Some useful public function

BOOL GetParamElem(CString &strElem, CString &strParam, BOOL bRemoveElem/*=TRUE*/)
{
	int nFound = strParam.Find(';');
	if (nFound < 0)
		nFound = strParam.GetLength();

	strElem = strParam.Left(nFound);
	strElem.TrimLeft();
	strElem.TrimRight();

	if (bRemoveElem)
	{
		if (nFound >= strParam.GetLength())
			strParam.Empty();
		else
			strParam = strParam.Right(strParam.GetLength() - nFound - 1);
	}

	return TRUE;
}