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

📄 markupstl.cpp

📁 一个很好的vc底层代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			strResult.append(pFound);		}		else		{			strResult += cSource;		}		cSource = *(++pSource);	}	return strResult;}string CMarkupSTL::x_TextFromDoc( int nLeft, int nRight ) const{	//	// Conveniently the result is always the same or shorter in length	//	static char* szaCode[] = { "lt;","amp;","gt;","apos;","quot;" };	static int anCodeLen[] = { 3,4,3,5,5 };	static char* szSymbol = "<&>\'\"";	string strResult;	strResult.reserve( nRight - nLeft + 1 );	const char* pSource = m_strDoc.c_str();	int nChar = nLeft;	char cSource = pSource[nChar];	while ( nChar <= nRight )	{		if ( cSource == '&' )		{			// If no match is found it means XML doc is invalid			// no devastating harm done, ampersand code will just be left in result			for ( int nMatch = 0; nMatch < 5; ++nMatch )			{				if ( nChar <= nRight - anCodeLen[nMatch]					&& strncmp(szaCode[nMatch],&pSource[nChar+1],anCodeLen[nMatch]) == 0 )				{					cSource = szSymbol[nMatch];					nChar += anCodeLen[nMatch];					break;				}			}		}		strResult += cSource;		nChar++;		cSource = pSource[nChar];	}	return strResult;}void CMarkupSTL::x_DocChange( int nLeft, int nReplace, const string& strInsert ){	// Insert strInsert int m_strDoc at nLeft replacing nReplace chars	//	m_strDoc.replace( nLeft, nReplace, strInsert);}void CMarkupSTL::x_Adjust( int iPos, int nShift, bool bAfterPos ){	// Loop through affected elements and adjust indexes	// Algorithm:	// 1. update children unless bAfterPos	//    (if no children or bAfterPos is true, end tag of iPos not affected)	// 2. update next siblings and their children	// 3. go up until there is a next sibling of a parent and update end tags	// 4. step 2	int iPosTop = m_aPos[iPos].iElemParent;	bool bPosFirst = bAfterPos; // mark as first to skip its children	while ( iPos )	{		// Were we at containing parent of affected position?		bool bPosTop = false;		if ( iPos == iPosTop )		{			// Move iPosTop up one towards root			iPosTop = m_aPos[iPos].iElemParent;			bPosTop = true;		}		// Traverse to the next update position		if ( ! bPosTop && ! bPosFirst && m_aPos[iPos].iElemChild )		{			// Depth first			iPos = m_aPos[iPos].iElemChild;		}		else if ( m_aPos[iPos].iElemNext )		{			iPos = m_aPos[iPos].iElemNext;		}		else		{			// Look for next sibling of a parent of iPos			// When going back up, parents have already been done except iPosTop			while ( (iPos=m_aPos[iPos].iElemParent) != 0 && iPos != iPosTop )				if ( m_aPos[iPos].iElemNext )				{					iPos = m_aPos[iPos].iElemNext;					break;				}		}		bPosFirst = false;		// Shift indexes at iPos		if ( iPos != iPosTop )			m_aPos[iPos].AdjustStart( nShift );		m_aPos[iPos].AdjustEnd( nShift );	}}void CMarkupSTL::x_LocateNew( int iPosParent, int& iPosRel, int& nOffset, int nLength, int nFlags ){	// Determine where to insert new element or node	//	bool bInsert = (nFlags&1)?true:false;	bool bHonorWhitespace = (nFlags&2)?true:false;	int nStartL;	if ( nLength )	{		// Located at a non-element node		if ( bInsert )			nStartL = nOffset;		else			nStartL = nOffset + nLength;	}	else if ( iPosRel )	{		// Located at an element		if ( bInsert ) // precede iPosRel			nStartL = m_aPos[iPosRel].nStartL;		else // follow iPosRel			nStartL = m_aPos[iPosRel].nEndR + 1;	}	else if ( m_aPos[iPosParent].IsEmptyElement() )	{		// Parent has no separate end tag, so split empty element		nStartL = m_aPos[iPosParent].nStartR;	}	else	{		if ( bInsert ) // after start tag			nStartL = m_aPos[iPosParent].nStartR + 1;		else // before end tag			nStartL = m_aPos[iPosParent].nEndL;	}	// Go up to start of next node, unless its splitting an empty element	if ( ! bHonorWhitespace && ! m_aPos[iPosParent].IsEmptyElement() )	{		TokenPos token( m_strDoc.c_str() );		token.nNext = nStartL;		if ( ! x_FindToken(token) || m_strDoc[token.nL] == '<' )			nStartL = token.nL;	}	// Determine iPosBefore	int iPosBefore = 0;	if ( iPosRel )	{		if ( bInsert )		{			// Is iPosRel past first sibling?			int iPosPrev = m_aPos[iPosParent].iElemChild;			if ( iPosPrev != iPosRel )			{				// Find previous sibling of iPosRel				while ( m_aPos[iPosPrev].iElemNext != iPosRel )					iPosPrev = m_aPos[iPosPrev].iElemNext;				iPosBefore = iPosPrev;			}		}		else		{			iPosBefore = iPosRel;		}	}	else if ( m_aPos[iPosParent].iElemChild )	{		if ( ! bInsert )		{			// Find last element under iPosParent			int iPosLast = m_aPos[iPosParent].iElemChild;			int iPosNext = iPosLast;			while ( iPosNext )			{				iPosLast = iPosNext;				iPosNext = m_aPos[iPosNext].iElemNext;			}			iPosBefore = iPosLast;		}	}	nOffset = nStartL;	iPosRel = iPosBefore;}bool CMarkupSTL::x_AddElem( const char* szName, const char* szValue, bool bInsert, bool bAddChild ){	if ( bAddChild )	{		// Adding a child element under main position		if ( ! m_iPos )			return false;	}	else if ( m_iPosParent == 0 )	{		// Adding root element		if ( IsWellFormed() )			return false;		// Locate after any version and DTD		m_aPos[0].nEndL = m_strDoc.size();	}	// Locate where to add element relative to current node	int iPosParent, iPosBefore, nOffset = 0, nLength = 0;	if ( bAddChild )	{		iPosParent = m_iPos;		iPosBefore = m_iPosChild;	}	else	{		iPosParent = m_iPosParent;		iPosBefore = m_iPos;	}	int nFlags = bInsert?1:0;	x_LocateNew( iPosParent, iPosBefore, nOffset, nLength, nFlags );	bool bEmptyParent = m_aPos[iPosParent].IsEmptyElement();	if ( bEmptyParent )		nOffset += 2; // include CRLF	// Create element and modify positions of affected elements	// If no szValue is specified, an empty element is created	// i.e. either <NAME>value</NAME> or <NAME/>	//	int iPos = x_GetFreePos();	m_aPos[iPos].nStartL = nOffset;	// Set links	m_aPos[iPos].iElemParent = iPosParent;	m_aPos[iPos].iElemChild = 0;	m_aPos[iPos].iElemNext = 0;	if ( iPosBefore )	{		// Link in after iPosBefore		m_aPos[iPos].iElemNext = m_aPos[iPosBefore].iElemNext;		m_aPos[iPosBefore].iElemNext = iPos;	}	else	{		// First child		m_aPos[iPos].iElemNext = m_aPos[iPosParent].iElemChild;		m_aPos[iPosParent].iElemChild = iPos;	}	// Create string for insert	string strInsert;	int nLenName = strlen(szName);	int nLenValue = szValue? strlen(szValue) : 0;	if ( ! nLenValue )	{		// <NAME/> empty element		strInsert = "<";		strInsert += szName;		strInsert += "/>\r\n\t";		m_aPos[iPos].nStartR = m_aPos[iPos].nStartL + nLenName + 2;		m_aPos[iPos].nEndL = m_aPos[iPos].nStartR - 1;		m_aPos[iPos].nEndR = m_aPos[iPos].nEndL + 1;	}	else	{		// <NAME>value</NAME>		string strValue = x_TextToDoc( szValue );		nLenValue = strValue.size();		strInsert = "<";		strInsert += szName;		strInsert += ">";		strInsert += strValue;		strInsert += "</";		strInsert += szName;		strInsert += ">\r\n\t";		m_aPos[iPos].nStartR = m_aPos[iPos].nStartL + nLenName + 1;		m_aPos[iPos].nEndL = m_aPos[iPos].nStartR + nLenValue + 1;		m_aPos[iPos].nEndR = m_aPos[iPos].nEndL + nLenName + 2;	}	// Insert	int nReplace = 0, nLeft = m_aPos[iPos].nStartL;	if ( bEmptyParent )	{		string strParentTagName = x_GetTagName(iPosParent);		string strFormat;		strFormat = ">\r\n\t";		strFormat += strInsert;		strFormat += "</";		strFormat += strParentTagName;		strInsert = strFormat;		nLeft -= 3;		nReplace = 1;		// x_Adjust is going to update all affected indexes by one amount		// This will satisfy all except the empty parent		// Here we pre-adjust for the empty parent		// The empty tag slash is removed		m_aPos[iPosParent].nStartR -= 1;		// For the newly created end tag, see the following example:		// <A/> (len 4) becomes <A><B/></A> (len 11)		// In x_Adjust everything will be adjusted 11 - 4 = 7		// But the nEndL of element A should only be adjusted 5		m_aPos[iPosParent].nEndL -= (strParentTagName.size() + 1);	}	x_DocChange( nLeft, nReplace, strInsert );	x_Adjust( iPos, strInsert.size() - nReplace );	if ( bAddChild )		x_SetPos( m_iPosParent, iPosParent, iPos );	else		x_SetPos( iPosParent, iPos, 0 );	return true;}bool CMarkupSTL::x_AddSubDoc( const char* szSubDoc, bool bInsert, bool bAddChild ){	// Add subdocument, parse, and modify positions of affected elements	//	int nOffset = 0, iPosParent, iPosBefore;	if ( bAddChild )	{		// Add a subdocument under main position, after current child position		if ( ! m_iPos )			return false;		iPosParent = m_iPos;		iPosBefore = m_iPosChild;	}	else	{		iPosParent = m_iPosParent;		iPosBefore = m_iPos;	}	int nFlags = bInsert?1:0;	x_LocateNew( iPosParent, iPosBefore, nOffset, 0, nFlags );	bool bEmptyParent = m_aPos[iPosParent].IsEmptyElement();	if ( bEmptyParent )		nOffset += 2; // include CRLF	// if iPosBefore is NULL, insert as first element under parent	int nParentEndLBeforeAdd = m_aPos[iPosParent].nEndL;	int iPosFreeBeforeAdd = m_iPosFree;	// Skip version tag or DTD at start of subdocument	TokenPos token( szSubDoc );	int nNodeType = x_ParseNode( token );	while ( nNodeType && nNodeType != MNT_ELEMENT )	{		token.szDoc = &szSubDoc[token.nNext];		token.nNext = 0;		nNodeType = x_ParseNode( token );	}	string strInsert = token.szDoc;	// Insert subdocument	m_aPos[iPosParent].nEndL = nOffset;	int nReplace = 0, nLeft = nOffset;	string strParentTagName;	if ( bEmptyParent )	{		strParentTagName = x_GetTagName(iPosParent);		string strFormat;		strFormat = ">\r\n\t";		strFormat += strInsert;		strFormat += "</";		strFormat += strParentTagName;		strInsert = strFormat;		m_aPos[iPosParent].nEndL = m_aPos[iPosParent].nStartR + 2;		nLeft = m_aPos[iPosParent].nStartR - 1;		nReplace = 1;	}	x_DocChange( nLeft, nReplace, strInsert );	// Parse subdocument	int iPos = x_ParseElem(iPosParent);	m_aPos[iPosParent].nEndL = nParentEndLBeforeAdd;	if ( iPos <= 0 )	{		// Abort because not well-formed		string strRevert = bEmptyParent?"/":"";		x_DocChange( nLeft, strInsert.size(), strRevert );		m_iPosFree = iPosFreeBeforeAdd;		return false;	}	else	{		// Link in parent and siblings		m_aPos[iPos].iElemParent = iPosParent;		if ( iPosBefore )		{			m_aPos[iPos].iElemNext = m_aPos[iPosBefore].iElemNext;			m_aPos[iPosBefore].iElemNext = iPos;		}		else		{			m_aPos[iPos].iElemNext = m_aPos[iPosParent].iElemChild;			m_aPos[iPosParent].iElemChild = iPos;		}		// Make empty parent pre-adjustment		if ( bEmptyParent )		{			m_aPos[iPosParent].nStartR -= 1;			m_aPos[iPosParent].nEndL -= (strParentTagName.size() + 1);		}		// Adjust, but don't adjust children of iPos (bAfterPos=true)		x_Adjust( iPos, strInsert.size() - nReplace, true );	}	// Set position to top element of subdocument	if ( bAddChild )		x_SetPos( m_iPosParent, iPosParent, iPos );	else // Main		x_SetPos( m_iPosParent, iPos, 0 );	return true;}int CMarkupSTL::x_RemoveElem( int iPos ){	// Remove element and all contained elements	// Return new position	//	int iPosParent = m_aPos[iPos].iElemParent;	// Find previous sibling and bypass removed element	// This leaves orphan positions in m_aPos array	int iPosLook = m_aPos[iPosParent].iElemChild;	int iPosPrev = 0;	while ( iPosLook != iPos )	{		iPosPrev = iPosLook;		iPosLook = m_aPos[iPosLook].iElemNext;	}	if ( iPosPrev )		m_aPos[iPosPrev].iElemNext = m_aPos[iPos].iElemNext;	else		m_aPos[iPosParent].iElemChild = m_aPos[iPos].iElemNext;	// Remove from document	// Links have been changed to go around removed element	// But element position and links are still valid	int nAfterEnd = m_aPos[iPos].nEndR + 1;	TokenPos token( m_strDoc.c_str() );	token.nNext = nAfterEnd;	if ( ! x_FindToken(token) || token.szDoc[token.nL] == '<' )		nAfterEnd = token.nL;	int nLen = nAfterEnd - m_aPos[iPos].nStartL;	x_DocChange( m_aPos[iPos].nStartL, nLen, string() );	x_Adjust( iPos, - nLen, true );	return iPosPrev;}

⌨️ 快捷键说明

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