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

    // MsgBlock.cpp: implementation of the CMsgBlock class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MsgBlock.h"

DEFINE_OBJECT_INDICATOR(MsgBlock)
IMPLEMENT_OBJECT_CUSTOM_INIT(CMsgBlock)

CMsgBlock::CMsgBlock()
{
	m_pBuff = NULL;
	m_nBuffLen = 0;

	m_pAttach = NULL;

	VERIFY(m_hLockMtx = ::CreateMutex(NULL, FALSE, NULL));
	m_nLockCount = 0;
}

CMsgBlock::~CMsgBlock()
{
	if (m_pBuff)
		delete [] m_pBuff;

	if (m_pAttach)
		m_pAttach->DestroyInstance();

	::CloseHandle(m_hLockMtx);
}

BOOL CMsgBlock::InitBlock(LPCTSTR szNodeInd)
{
	m_strNodeInd = szNodeInd;
	return TRUE;
}

BOOL CMsgBlock::GetMsgSeg(DWORD *pnSeg, LONG nSegStart, LONG nSegBitStart, LONG nSegBitLen)
{
	if (! m_pBuff)
		return FALSE;

	LONG nSegEnd = nSegStart + (nSegBitStart + nSegBitLen) / 8 - 1;
	nSegEnd += ((nSegBitStart + nSegBitLen) % 8) ? 1 : 0;

	if ((pnSeg) && (nSegStart >= 0) && (nSegEnd < m_nBuffLen) && (nSegBitLen <= 32))
	{
		BYTE nByte;
		LONG nFetchLen;
		DWORD nValue = 0;
		while (nSegBitLen > 0)
		{
			nFetchLen = 8 - nSegBitStart;
			nFetchLen = min(nFetchLen, nSegBitLen);

			nByte = m_pBuff[nSegStart];
			nByte = (nByte >> (8 - nFetchLen - nSegBitStart)) & (0xFF >> (8 - nFetchLen));

			nValue = (nValue << nFetchLen) | nByte;

			nSegBitLen -= nFetchLen;
			nSegStart ++;
			nSegBitStart = 0;
		}

		*pnSeg = nValue;
		return TRUE;
	}

	return FALSE;
}

BOOL CMsgBlock::GetMsgSeg(const BYTE **pszSeg, LONG nSegStart, LONG nSegByteLen)
{
	if (! m_pBuff)
		return FALSE;

	if (pszSeg && (nSegStart >= 0) && (nSegStart+nSegByteLen <= m_nBuffLen))
	{
		*pszSeg = m_pBuff+nSegStart;
		return TRUE;
	}

	return FALSE;
}

BOOL CMsgBlock::SetMsgSeg(DWORD nSeg, LONG nSegStart, LONG nSegBitStart, LONG nSegBitLen)
{
	if (! m_pBuff)
		return FALSE;

	LONG nSegEnd = nSegStart + (nSegBitStart + nSegBitLen) / 8 - 1;
	nSegEnd += ((nSegBitStart + nSegBitLen) % 8) ? 1 : 0;

	if ((nSegStart >= 0) && (nSegEnd < m_nBuffLen) && (nSegBitLen <= 32))
	{
		BYTE nByte, nValue, nMask;
		LONG nFetchLen;
		while (nSegBitLen > 0)
		{
			nFetchLen = 8 - nSegBitStart;
			nFetchLen = min(nFetchLen, nSegBitLen);

			nMask = (0xFF >> (8 - nFetchLen)) << (8 - nSegBitStart - nFetchLen);
			nValue = (BYTE)((nSeg >> (nSegBitLen - nFetchLen)) << (8 - nSegBitStart - nFetchLen));
			nByte = m_pBuff[nSegStart];
			nByte = (nByte & (~nMask)) | (nValue & nMask);
			m_pBuff[nSegStart] = nByte;

			nSegBitLen -= nFetchLen;
			nSegStart ++;
			nSegBitStart = 0;
		}

		return TRUE;
	}

	return FALSE;
}

BOOL CMsgBlock::SetMsgSeg(const BYTE *szSeg, LONG nSegStart, LONG nSegByteLen, LONG nNewByteLen/*=-1*/)
{
	if (! m_pBuff)
		return FALSE;

	if (nNewByteLen < 0)
		nNewByteLen = nSegByteLen;

	if (szSeg && (nSegStart >= 0) && (nSegStart+nSegByteLen <= m_nBuffLen))
	{
		if (nNewByteLen == nSegByteLen)
		{
			if (nSegByteLen > 0)
				::memcpy(m_pBuff + nSegStart, szSeg, nSegByteLen);
		}
		else
		{
			BYTE *szNewBuff = new BYTE [m_nBuffLen + nNewByteLen - nSegByteLen];

			if (nSegStart > 0)
				::memcpy(szNewBuff, m_pBuff, nSegStart);

			if (nNewByteLen > 0)
				::memcpy(szNewBuff + nSegStart, szSeg, nNewByteLen);

			if (m_nBuffLen > (nSegStart + nSegByteLen))
				::memcpy(szNewBuff+nSegStart+nNewByteLen, m_pBuff+nSegStart+nSegByteLen, m_nBuffLen - nSegStart - nSegByteLen);

			delete [] m_pBuff;
			m_pBuff = szNewBuff;
			m_nBuffLen = m_nBuffLen + nNewByteLen - nSegByteLen;
		}
		return TRUE;
	}

	return FALSE;
}

BOOL CMsgBlock::RefreshNodes()
{
	UINT nResult = CDC_INNER_ERROR;
	if (m_pAttach && (m_nLockCount == 0))
	{
		IPrivateNode *pNode = NULL;
		m_pAttach->GetInterface(IN_IPrivateNode, (void**)&pNode);

		if (pNode)
		{
			LONG nByteStart = 0, nBitStart = 0;
			nResult = pNode->RefreshNode(nByteStart, nBitStart);
		}
	}
	return (nResult == CDC_OK);
}

BOOL CMsgBlock::LockMsg(DWORD nTimeOut/*=INFINITE*/)
{
	if (::WaitForSingleObject(m_hLockMtx, nTimeOut) == WAIT_OBJECT_0)
	{
		m_nLockCount ++;
		return TRUE;
	}
	return FALSE;
}

BOOL CMsgBlock::UnlockMsg()
{
	m_nLockCount --;
	return ::ReleaseMutex(m_hLockMtx);
}


UINT CMsgBlock::DecodeMsg(const BYTE* pSrcString, LONG &nSrcLen)
{
	UINT nResult = CDC_INNER_ERROR;

	IPrivateNode *pNode = NULL;

	if (! m_pAttach)
	{
		m_pAttach = CodecPrivateServ::CreateNode(m_strNodeInd);
		m_pAttach->GetInterface(IN_IPrivateNode, (void**)&pNode);
		pNode->InitInstance(this, NULL);
	}
	else
	{
		m_pAttach->GetInterface(IN_IPrivateNode, (void**)&pNode);
	}

	if (pNode)
	{
		LONG nByteStart = 0, nBitStart = 0;

		if (m_pBuff)
			delete [] m_pBuff;
		m_pBuff = (BYTE*)pSrcString;
		m_nBuffLen = nSrcLen;

		nResult = pNode->RefreshNode(nByteStart, nBitStart);
		if (nResult == CDC_OK)
		{
			m_nBuffLen = nByteStart + (nBitStart ? 1 : 0);
			m_pBuff = new BYTE [m_nBuffLen];

			::memcpy(m_pBuff, pSrcString, m_nBuffLen);
			nSrcLen = m_nBuffLen;
		}
		else
		{
			m_pBuff = NULL;
			m_nBuffLen = 0;
		}
	}

	return nResult;
}

UINT CMsgBlock::CreateMsg(const BYTE* pTemplate/*=NULL*/, LONG nTempLen/*=0*/)
{
	if (! (pTemplate && nTempLen))
	{
		pTemplate = CodecPrivateServ::GetNodeDefaultTemplate(m_strNodeInd, nTempLen);
	}

	return DecodeMsg(pTemplate, nTempLen);
}

UINT CMsgBlock::EncodeMsg(BYTE *pTgtString, LONG &nTgtLen)
{
	return CDC_OK;
}


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

BOOL CMsgBlock::GetNodeValue(BYTE &nValue)
{
	if (m_pAttach)
		return m_pAttach->GetNodeValue(nValue);
	return FALSE;
}

BOOL CMsgBlock::GetNodeValue(WORD &nValue)
{
	if (m_pAttach)
		return m_pAttach->GetNodeValue(nValue);
	return FALSE;
}

BOOL CMsgBlock::GetNodeValue(DWORD &nValue)
{
	if (m_pAttach)
		return m_pAttach->GetNodeValue(nValue);
	return FALSE;
}

BOOL CMsgBlock::GetNodeValue(const BYTE** ppBuff, LONG &nBuffLen)
{
	if (m_pAttach)
		return m_pAttach->GetNodeValue(ppBuff, nBuffLen);
	return FALSE;
}

BOOL CMsgBlock::GetNodeValue(IBase* pObj)
{
	if (m_pAttach)
		return m_pAttach->GetNodeValue(pObj);
	return FALSE;
}

BOOL CMsgBlock::SetNodeValue(BYTE nValue)
{
	if (m_pAttach)
		return m_pAttach->SetNodeValue(nValue);
	return FALSE;
}

BOOL CMsgBlock::SetNodeValue(WORD nValue)
{
	if (m_pAttach)
		return m_pAttach->SetNodeValue(nValue);
	return FALSE;
}

BOOL CMsgBlock::SetNodeValue(DWORD nValue)
{
	if (m_pAttach)
		return m_pAttach->SetNodeValue(nValue);
	return FALSE;
}

BOOL CMsgBlock::SetNodeValue(const BYTE* pBuff, LONG nBuffLen)
{
	if (m_pAttach)
		return m_pAttach->SetNodeValue(pBuff, nBuffLen);
	return FALSE;
}

BOOL CMsgBlock::SetNodeValue(IBase* pObj)
{
	if (m_pAttach)
		return m_pAttach->SetNodeValue(pObj);
	return FALSE;
}

IMsgNode* CMsgBlock::GetParentNode()
{
	if (m_pAttach)
		return m_pAttach->GetParentNode();
	return NULL;
}

IMsgNode* CMsgBlock::GetRootNode()
{
	if (m_pAttach)
		return m_pAttach->GetRootNode();
	return NULL;
}

LONG CMsgBlock::GetChildCount()
{
	if (m_pAttach)
		return m_pAttach->GetChildCount();
	return 0;
}

COLPOS CMsgBlock::FindChild(LONG nIndex)
{
	if (m_pAttach)
		return m_pAttach->FindChild(nIndex);
	return NULL;
}

COLPOS CMsgBlock::FindChild(LPCTSTR szName)
{
	if (m_pAttach)
		return m_pAttach->FindChild(szName);
	return NULL;
}

COLPOS CMsgBlock::FindNextChild(COLPOS nPos)
{
	if (m_pAttach)
		return m_pAttach->FindNextChild(nPos);
	return NULL;
}

IMsgNode* CMsgBlock::GetChildAt(COLPOS nPos)
{
	if (m_pAttach)
		return m_pAttach->GetChildAt(nPos);
	return NULL;
}

LPCTSTR CMsgBlock::GetChildNameAt(COLPOS nPos)
{
	if (m_pAttach)
		return m_pAttach->GetChildNameAt(nPos);
	return NULL;
}

IMsgNode* CMsgBlock::LocateNode(LPCTSTR szLocator)
{
	if (m_pAttach)
		return m_pAttach->LocateNode(szLocator);
	return NULL;
}


LPCTSTR CMsgBlock::GetNodeName()
{
	if (m_pAttach)
		return m_pAttach->GetNodeInfo()->GetNodeName();
	return NULL;
}

MsgNodeType CMsgBlock::GetNodeType()
{
	if (m_pAttach)
		return m_pAttach->GetNodeInfo()->GetNodeType();
	return mntUnknown;
}

LONG CMsgBlock::GetNodeLength(MsgLengthUnit mluUnit)
{
	if (m_pAttach)
		return m_pAttach->GetNodeInfo()->GetNodeLength(mluUnit);
	return -1;
}

LONG CMsgBlock::GetNodeByteStart()
{
	if (m_pAttach)
		return m_pAttach->GetNodeInfo()->GetNodeByteStart();
	return -1;
}

LONG CMsgBlock::GetNodeBitStart()
{
	if (m_pAttach)
		return m_pAttach->GetNodeInfo()->GetNodeBitStart();
	return -1;
}

IEnumTable* CMsgBlock::GetEnumTable()
{
	if (m_pAttach)
		return m_pAttach->GetNodeInfo()->GetEnumTable();
	return NULL;
}