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; }