⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bcgpoutlineparser.cpp

📁 远程网络监视程序的源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
									   const BlockType* pBlockType, CObList& lstIgnore,
									   CString& strName)
{
	ASSERT (nStartFrom >= 0);
	ASSERT (nSearchTo >= 0);
	ASSERT (pBlockType != NULL);

	int nOffset = nStartFrom - 1;
	const int nCharsMaxNum = 256;
	nSearchTo = max (nSearchTo, nStartFrom - nCharsMaxNum);
	LPCTSTR lpszDelimiters = _T(";{}");

	const CStringList* pListKeywords = &(pBlockType->m_lstKeywords);
	ASSERT_VALID (pListKeywords);
	
	while (nOffset >= nSearchTo)
	{
		CString strWord;
		nOffset = GetPrevWord (strIn, nOffset, nSearchTo, lpszDelimiters, strWord);
		if (nOffset >= nSearchTo &&
			!IsInRange (lstIgnore, nOffset, nOffset + strWord.GetLength ()))
		{
			// Compare strWord with keywords
			if (pListKeywords->Find (strWord) != NULL)
			{
				strName = strWord;
				return nStartFrom - nOffset;
			}
			else if (IsBlockName (strIn, strWord, nOffset, nStartFrom))
			{
				strName = strWord;
				return nStartFrom - nOffset;
			}
		}
		nOffset--;
	}

	strName = _T("");
	return 0;
}
//************************************************************************************
int CBCGPOutlineParser::GetPrevWord (const CString& strIn, int nStartFrom, 
							int nSearchTo, LPCTSTR lpszStopDelimiters, CString& strWord)
{
	ASSERT (nStartFrom >= 0);
	ASSERT (nStartFrom < strIn.GetLength ());
	ASSERT (nSearchTo >= 0);
	ASSERT (lpszStopDelimiters != NULL);

	CString strStopDelimiters = lpszStopDelimiters;
	CString strWordDelimeters = _T(" \t\n,./?><;:\"'{[}]~`%^&*()-+=!");

	// -------------------------------------------------------------------
	// Reverse search for a word till nSearchTo or one of spec delimiters:
	// -------------------------------------------------------------------
	strWord.Empty ();
	int i = nStartFrom;

	if (i >= nSearchTo &&
		strWordDelimeters.Find (strIn [i]) != -1)
	{
		// Inside delimiters - move to end of delimiters string:
		for (; i >= nSearchTo; i--)
		{
			TCHAR chNext = strIn.GetAt (i);
			if (strStopDelimiters.Find (chNext) != -1)
			{
				return -1;
			}
			if (strWordDelimeters.Find (chNext) == -1)
			{
				break;
			}
		}
	}
	if (i >= nSearchTo &&
		strWordDelimeters.Find (strIn [i]) == -1)
	{
		// Inside word - move to end of word:
		int iWordEnd = i;

		for (; i >= nSearchTo; i--)
		{
			TCHAR chNext = strIn.GetAt (i);
			if (strStopDelimiters.Find (chNext) != -1)
			{
				break;
			}
			if (strWordDelimeters.Find (chNext) != -1)
			{
				break;
			}
		}

		if (i < iWordEnd)
		{
			strWord = strIn.Mid (i + 1, iWordEnd - i);
			return i + 1;
		}
	}

	return -1;
}
//************************************************************************************
BOOL CBCGPOutlineParser::IsBlockName (const CString& strIn, CString& strWord, const int nOffset, const int nSearchTo)
{
	ASSERT (nOffset >= 0);
	ASSERT (nSearchTo >=0);

	CString strDelimeters = _T(" \t\n");
	int const nWordLength = strWord.GetLength ();
	
	// skip delimiters:
	int i = nOffset + nWordLength;
	int iMax = min (nSearchTo, strIn.GetLength ());
	while (i < iMax && strDelimeters.Find (strIn [i]) >= 0)
	{
		i++;
	}

	if (strIn [i] == _T('('))
	{
		strWord += strIn.Mid (i, iMax - i);
		return TRUE;
	}

	return FALSE;
}
//************************************************************************************
int CBCGPOutlineParser::GetStartOffset (const CString& strIn, int nStartFrom, int nSearchTo, CObList& lstIgnore)
{
	ASSERT (nStartFrom >= 0);
	ASSERT (nSearchTo >= 0);
	
	CString strDelimeters = _T(" \t\n");
	int i = nStartFrom;

	while (i > nSearchTo)
	{
		i--;
		if (strDelimeters.Find (strIn[i]) == -1 && 
			!IsInRange (lstIgnore, i, i))
		{
			nStartFrom = i + 1;
			break;
		}
	}
		
	return nStartFrom;
}
//************************************************************************************
int CBCGPOutlineParser::GetEndOffset (const CString& strIn, int nStartFrom, int nSearchTo)
{
	return nStartFrom;
}
//************************************************************************************
BOOL CBCGPOutlineParser::AddMarker (CBCGPOutlineNode* pMarkerBlock, CBCGPOutlineNode* pParentNode,
									BCGP_EDIT_OUTLINE_CHANGES& changes) const
{
	ASSERT_VALID (pMarkerBlock);
	ASSERT_VALID (pParentNode);
	ASSERT ((pMarkerBlock->m_dwFlags & g_dwOBFLeft) != 0 ||
			(pMarkerBlock->m_dwFlags & g_dwOBFRight) != 0);

	// ---------------------------------------
	// Search for marker fitting for this one:
	// ---------------------------------------
	CBCGPOutlineNode* pComposeWith = FindFittingBlock (pMarkerBlock, pParentNode);

	if (pComposeWith != NULL)
	{
		ASSERT_VALID (pComposeWith);

		// ---------------------------------------------------------
		// Combine new marker with existed block or with pair marker
		// ---------------------------------------------------------
		CBCGPOutlineBaseNode* pLeft = NULL;
		CBCGPOutlineBaseNode* pRight = NULL;

		if ((pMarkerBlock->m_dwFlags & g_dwOBFLeft) != 0)
		{
			ASSERT ((pComposeWith->m_dwFlags & g_dwOBFComplete) != 0 ||
					(pComposeWith->m_dwFlags & g_dwOBFRight) != 0);

			pLeft = pMarkerBlock;
			pRight = pComposeWith;
		}
		else if ((pMarkerBlock->m_dwFlags & g_dwOBFRight) != 0)
		{
			ASSERT ((pComposeWith->m_dwFlags & g_dwOBFComplete) != 0 ||
					(pComposeWith->m_dwFlags & g_dwOBFLeft) != 0);

			pLeft = pComposeWith;
			pRight = pMarkerBlock;
		}
		else
		{
			ASSERT (FALSE);
			return FALSE;
		}

		CBCGPOutlineNode* pParent = pComposeWith->GetParentNode ();
		ASSERT_VALID (pParent);

		if (pLeft != NULL && pRight != NULL)
		{
			ASSERT (pLeft->m_nStart < pRight->m_nEnd);
			ASSERT (pLeft->m_strReplace == pRight->m_strReplace);

			// ---------------
			// Make new block:
			// ---------------
			RemoveNode (pComposeWith, pParent, changes);
			CBCGPOutlineNode* pNewBlock = new CBCGPOutlineNode (*pLeft);
			pNewBlock->m_dwFlags &= ~g_dwOBFLeft;
			pNewBlock->m_dwFlags |= g_dwOBFComplete;
			pNewBlock->m_bCollapsed = FALSE;
			pNewBlock->m_nEnd = pRight->m_nEnd;

			AddNode (pNewBlock, pParent, changes);
		}
		else
		{
			ASSERT (FALSE);
			return FALSE;
		}

		if ((pComposeWith->m_dwFlags & g_dwOBFComplete) != 0)
		{
			// ----------------------------------------------------------------------
			// The rest of old block contains start/close sequence - add it as marker
			// ----------------------------------------------------------------------
			CBCGPOutlineNode* pNewMarker = new CBCGPOutlineNode (*pComposeWith->GetValue ());
			const BlockType* pBlockType = GetBlockType (pNewMarker->m_nBlockType);
			if ((pMarkerBlock->m_dwFlags & g_dwOBFLeft) != 0)
			{
				// add start marker (g_dwOBFLeft):
				const int nOpenStrLen = (pBlockType != NULL) ? pBlockType->m_strOpen.GetLength () : 1;
				pNewMarker->m_dwFlags &= ~g_dwOBFComplete;
				pNewMarker->m_dwFlags |= g_dwOBFLeft;
				pNewMarker->m_bCollapsed = FALSE;
				pNewMarker->m_nEnd = pNewMarker->m_nStart + nOpenStrLen - 1;
			}
			else if ((pMarkerBlock->m_dwFlags & g_dwOBFRight) != 0)
			{
				// add end marker (g_dwOBFRight):
				const int nCloseStrLen = (pBlockType != NULL) ? pBlockType->m_strClose.GetLength () : 1;
				pNewMarker->m_dwFlags &= ~g_dwOBFComplete;
				pNewMarker->m_dwFlags |= g_dwOBFRight;
				pNewMarker->m_bCollapsed = FALSE;
				pNewMarker->m_nStart = pNewMarker->m_nEnd - nCloseStrLen - 1;
				pNewMarker->DestroyData (); // end marker has no data
			}

			// Recursive call:
			AddMarker (pNewMarker, pParent, changes);
		}

		// ------------------
		// Delete old blocks:
		// ------------------
		delete pMarkerBlock;
	}
	else
	{
		// --------------------------------------------
		// Add non-completed block (marker) in the root
		// --------------------------------------------
		CBCGPOutlineNode* pRoot = pParentNode;
		while (pRoot->GetParentNode () != NULL)
		{
			ASSERT_VALID (pRoot);
			pRoot = pParentNode->GetParentNode ();
		}
		AddNode (pMarkerBlock, pRoot, changes);
	}

	return TRUE;
}
//************************************************************************************
CBCGPOutlineNode* CBCGPOutlineParser::FindFittingBlock (CBCGPOutlineNode* pBlock, CBCGPOutlineNode* pParentNode) const
{
	ASSERT_VALID (pBlock);

	if ((pBlock->m_dwFlags & g_dwOBFComplete) != 0)
	{
		return NULL;
	}

	if (pParentNode == NULL)
	{
		return NULL;
	}

	ASSERT_VALID (pParentNode);

	// ----------------------------------------------------------------------
	// Search through the current level for the block fitting for this marker
	// ----------------------------------------------------------------------
	if ((pBlock->m_dwFlags & g_dwOBFLeft) != 0)
	{
		for (POSITION pos = pParentNode->GetNodes ()->GetHeadPosition (); pos != NULL;)
		{
			CBCGPOutlineNode* pNode = (CBCGPOutlineNode*) pParentNode->GetNodes ()->GetNext (pos);
			ASSERT_VALID (pNode);

			if (pNode->m_nBlockType == pBlock->m_nBlockType)
			{
				if ((pNode->m_dwFlags & g_dwOBFComplete) != 0 &&
					pBlock->m_nEnd < pNode->m_nEnd &&
					pBlock->m_nStart > pNode->m_nStart)
				{
					return pNode;
				}
				else if ((pNode->m_dwFlags & g_dwOBFRight) != 0 &&
						 pBlock->m_nStart < pNode->m_nStart)
				{
					return pNode;
				}
			}
		}

		// Recursive call:
		return FindFittingBlock (pBlock, pParentNode->GetParentNode ());
	}
	else if ((pBlock->m_dwFlags & g_dwOBFRight) != 0)
	{
		for (POSITION pos = pParentNode->GetNodes ()->GetTailPosition (); pos != NULL;)
		{
			CBCGPOutlineNode* pNode = (CBCGPOutlineNode*) pParentNode->GetNodes ()->GetPrev (pos);
			ASSERT_VALID (pNode);

			if (pNode->m_nBlockType == pBlock->m_nBlockType)
			{
				if ((pNode->m_dwFlags & g_dwOBFComplete) != 0 &&
					pBlock->m_nStart > pNode->m_nStart &&
					pBlock->m_nEnd < pNode->m_nEnd)
				{
					return pNode;
				}
				else if ((pNode->m_dwFlags & g_dwOBFLeft) != 0 &&
						 pBlock->m_nStart > pNode->m_nStart)
				{
					return pNode;
				}
			}
		}

		// Recursive call:
		return FindFittingBlock (pBlock, pParentNode->GetParentNode ());
	}

	return NULL;
}

CBCGPOutlineNode* CBCGPOutlineParser::AddNode (CBCGPOutlineNode* pNewNode, CBCGPOutlineNode* pParentNode, 
											   BCGP_EDIT_OUTLINE_CHANGES& changes) const
{
	ASSERT_VALID (pParentNode);

	const BlockType* pBlockTypeDef = GetBlockType (pNewNode->m_nBlockType);
	if (pBlockTypeDef != NULL && !pBlockTypeDef->m_bAllowNestedBlocks)
	{
		// Nested blocks are not allowed - delete nested blocks:
		pParentNode->DeleteBlocksInRange (
			pNewNode->m_nStart - pNewNode->m_nNameOffset, 
			pNewNode->m_nEnd, changes);
	}

	return pParentNode->AddNode (pNewNode, changes);
}

CBCGPOutlineNode* CBCGPOutlineParser::RemoveNode (CBCGPOutlineNode* pNode, CBCGPOutlineNode* pParentNode, 
												  BCGP_EDIT_OUTLINE_CHANGES& changes,
												  BOOL bRemoveSubNodes) const
{
	ASSERT_VALID (pNode);
	ASSERT_VALID (pParentNode);
	POSITION posNode = pParentNode->m_lstNodes.Find (pNode);
	ASSERT (posNode != NULL);

	return pParentNode->RemoveNode (posNode, changes, bRemoveSubNodes);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -