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

📄 markupstl.cpp

📁 一个很好的vc底层代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		}		// Was a right angle bracket not found?		if ( ! token.szDoc[token.nL] || nTokenCount < 2 )			return x_ParseError( "End tag not completed for element %s", strName.c_str() );		m_aPos[iPos].nEndR = token.nL;	}	// Successfully parsed element (and contained elements)	return iPos;}bool CMarkupSTL::x_FindChar( const char* szDoc, int& nChar, char c ){	// static function	const char* pChar = &szDoc[nChar];	while ( *pChar && *pChar != c )		pChar += 1;	nChar = pChar - szDoc;	if ( ! *pChar )		return false;	/*	while ( szDoc[nChar] && szDoc[nChar] != c )		nChar += _tclen( &szDoc[nChar] );	if ( ! szDoc[nChar] )		return false;	*/	return true;}bool CMarkupSTL::x_FindToken( CMarkupSTL::TokenPos& token ){	// Starting at token.nNext, bypass whitespace and find the next token	// returns true on success, members of token point to token	// returns false on end of document, members point to end of document	const char* szDoc = token.szDoc;	int nChar = token.nNext;	token.bIsString = false;	// By-pass leading whitespace	while ( szDoc[nChar] && strchr(" \t\n\r",szDoc[nChar]) )		++nChar;	if ( ! szDoc[nChar] )	{		// No token was found before end of document		token.nL = nChar;		token.nR = nChar;		token.nNext = nChar;		return false;	}	// Is it an opening quote?	char cFirstChar = szDoc[nChar];	if ( cFirstChar == '\"' || cFirstChar == '\'' )	{		token.bIsString = true;		// Move past opening quote		++nChar;		token.nL = nChar;		// Look for closing quote		x_FindChar( token.szDoc, nChar, cFirstChar );		// Set right to before closing quote		token.nR = nChar - 1;		// Set nChar past closing quote unless at end of document		if ( szDoc[nChar] )			++nChar;	}	else	{		// Go until special char or whitespace		token.nL = nChar;		while ( szDoc[nChar] && ! strchr(" \t\n\r<>=\\/?!",szDoc[nChar]) )			nChar += 1;		// Adjust end position if it is one special char		if ( nChar == token.nL )			++nChar; // it is a special char		token.nR = nChar - 1;	}	// nNext points to one past last char of token	token.nNext = nChar;	return true;}string CMarkupSTL::x_GetToken( const CMarkupSTL::TokenPos& token ) const{	// The token contains indexes into the document identifying a small substring	// Build the substring from those indexes and return it	if ( token.nL > token.nR )		return "";	return m_strDoc.substr( token.nL,		token.nR - token.nL + ((token.nR<m_strDoc.size())? 1:0) );}int CMarkupSTL::x_FindElem( int iPosParent, int iPos, const char* szPath ){	// If szPath is NULL or empty, go to next sibling element	// Otherwise go to next sibling element with matching path	//	if ( iPos )		iPos = m_aPos[iPos].iElemNext;	else		iPos = m_aPos[iPosParent].iElemChild;	// Finished here if szPath not specified	if ( szPath == NULL || !szPath[0] )		return iPos;	// Search	TokenPos token( m_strDoc.c_str() );	while ( iPos )	{		// Compare tag name		token.nNext = m_aPos[iPos].nStartL + 1;		x_FindToken( token ); // Locate tag name		if ( token.Match(szPath) )			return iPos;		iPos = m_aPos[iPos].iElemNext;	}	return 0;}int CMarkupSTL::x_ParseNode( CMarkupSTL::TokenPos& token ){	// Call this with token.nNext set to the start of the node	// This returns the node type and token.nNext set to the char after the node	// If the node is not found or an element, token.nR is not determined	// White space between elements is a text node	int nTypeFound = 0;	const char* szDoc = token.szDoc;	token.nL = token.nNext;	if ( szDoc[token.nL] == '<' )	{		// Started with <, could be:		// <!--...--> comment		// <!DOCTYPE ...> dtd		// <?target ...?> processing instruction		// <![CDATA[...]]> cdata section		// <NAME ...> element		//		if ( ! szDoc[token.nL+1] || ! szDoc[token.nL+2] )			return 0;		char cFirstChar = szDoc[token.nL+1];		const char* szEndOfNode = NULL;		if ( cFirstChar == '?' )		{			nTypeFound = MNT_PROCESSING_INSTRUCTION; // processing instruction			szEndOfNode = "?>";		}		else if ( cFirstChar == '!' )		{			char cSecondChar = szDoc[token.nL+2];			if ( cSecondChar == '[' )			{				nTypeFound = MNT_CDATA_SECTION;				szEndOfNode = "]]>";			}			else if ( cSecondChar == '-' )			{				nTypeFound = MNT_COMMENT;				szEndOfNode = "-->";			}			else			{				// Document type requires tokenizing because of strings and brackets				nTypeFound = 0;				int nBrackets = 0;				while ( x_FindToken(token) )				{					if ( ! token.bIsString )					{						char cChar = szDoc[token.nL];						if ( cChar == '[' )							++nBrackets;						else if ( cChar == ']' )							--nBrackets;						else if ( nBrackets == 0 && cChar == '>' )						{							nTypeFound = MNT_DOCUMENT_TYPE;							break;						}					}				}				if ( ! nTypeFound )					return 0;			}		}		else if ( cFirstChar == '/' )		{			// End tag means no node found within parent element			return 0;		}		else		{			nTypeFound = MNT_ELEMENT;		}		// Search for end of node if not found yet		if ( szEndOfNode )		{			const char* pEnd = strstr( &szDoc[token.nNext], szEndOfNode );			if ( ! pEnd )				return 0; // not well-formed			token.nNext = (pEnd - szDoc) + strlen(szEndOfNode);		}	}	else if ( szDoc[token.nL] )	{		// It is text or whitespace because it did not start with <		nTypeFound = MNT_WHITESPACE;		if ( x_FindToken(token) )		{			if ( szDoc[token.nL] == '<' )				token.nNext = token.nL;			else			{				nTypeFound = MNT_TEXT;				x_FindChar( token.szDoc, token.nNext, '<' );			}		}	}	return nTypeFound;}string CMarkupSTL::x_GetTagName( int iPos ) const{	// Return the tag name at specified element	TokenPos token( m_strDoc.c_str() );	token.nNext = m_aPos[iPos].nStartL + 1;	if ( ! iPos || ! x_FindToken( token ) )		return "";	// Return substring of document	return x_GetToken( token );}bool CMarkupSTL::x_FindAttrib( CMarkupSTL::TokenPos& token, const char* szAttrib ) const{	// If szAttrib is NULL find next attrib, otherwise find named attrib	// Return true if found	int nAttrib = 0;	for ( int nCount = 0; x_FindToken(token); ++nCount )	{		if ( ! token.bIsString )		{			// Is it the right angle bracket?			if ( m_strDoc[token.nL] == '>' || m_strDoc[token.nL] == '/' )				break; // attrib not found			// Equal sign			if ( m_strDoc[token.nL] == '=' )				continue;			// Potential attribute			if ( ! nAttrib && nCount )			{				// Attribute name search?				if ( ! szAttrib || ! szAttrib[0] )					return true; // return with token at attrib name				// Compare szAttrib				if ( token.Match(szAttrib) )					nAttrib = nCount;			}		}		else if ( nAttrib && nCount == nAttrib + 2 )		{			return true;		}	}	// Not found	return false;}string CMarkupSTL::x_GetAttrib( int iPos, const char* szAttrib ) const{	// Return the value of the attrib at specified element	if ( ! iPos || m_nNodeType != MNT_ELEMENT )		return "";	TokenPos token( m_strDoc.c_str() );	token.nNext = m_aPos[iPos].nStartL + 1;	if ( szAttrib && x_FindAttrib( token, szAttrib ) )		return x_TextFromDoc( token.nL, token.nR - ((token.nR<m_strDoc.size())?0:1) );	return "";}bool CMarkupSTL::x_SetAttrib( int iPos, const char* szAttrib, int nValue ){	// Convert integer to string and call SetChildAttrib	char szVal[25];	sprintf( szVal, "%d", nValue );	return x_SetAttrib( iPos, szAttrib, szVal );}bool CMarkupSTL::x_SetAttrib( int iPos, const char* szAttrib, const char* szValue ){	// Set attribute in iPos element	if ( ! iPos || m_nNodeType != MNT_ELEMENT )		return false;	TokenPos token( m_strDoc.c_str() );	token.nNext = m_aPos[iPos].nStartL + 1;	int nInsertAt, nReplace = 0;	string strInsert;	if ( x_FindAttrib( token, szAttrib ) )	{		// Decision: for empty value leaving attrib="" instead of removing attrib		// Replace value only		strInsert = x_TextToDoc( szValue, true );		nInsertAt = token.nL;		nReplace = token.nR-token.nL+1;	}	else	{		// Insert string name value pair		string strFormat;		strFormat = " ";		strFormat += szAttrib;		strFormat += "=\"";		strFormat += x_TextToDoc( szValue, true );		strFormat += "\"";		strInsert = strFormat;		// take into account whether it is an empty element		nInsertAt = m_aPos[iPos].nStartR - (m_aPos[iPos].IsEmptyElement()?1:0);	}	x_DocChange( nInsertAt, nReplace, strInsert );	int nAdjust = strInsert.size() - nReplace;	m_aPos[iPos].nStartR += nAdjust;	m_aPos[iPos].AdjustEnd( nAdjust );	x_Adjust( iPos, nAdjust );	MARKUP_SETDEBUGSTATE;	return true;}bool CMarkupSTL::x_CreateNode( string& strNode, int nNodeType, const char* szText ){	// Set strNode based on nNodeType and szText	// Return false if szText would jeopardize well-formed document	//	switch ( nNodeType )	{	case MNT_CDATA_SECTION:		if ( strstr(szText,"]]>") != NULL )			return false;		strNode = "<![CDATA[";		strNode += szText;		strNode += "]]>";		break;	}	return true;}bool CMarkupSTL::x_SetData( int iPos, const char* szData, int nCDATA ){	// Set data at specified position	// if nCDATA==1, set content of element to a CDATA Section	string strInsert;	// Set data in iPos element	if ( ! iPos || m_aPos[iPos].iElemChild )		return false;	// Build strInsert from szData based on nCDATA	// If CDATA section not valid, use parsed text (PCDATA) instead	if ( nCDATA != 0 )		if ( ! x_CreateNode(strInsert, MNT_CDATA_SECTION, szData) )			nCDATA = 0;	if ( nCDATA == 0 )		strInsert = x_TextToDoc( szData );	// Decide where to insert	int nInsertAt, nReplace;	if ( m_aPos[iPos].IsEmptyElement() )	{		nInsertAt = m_aPos[iPos].nEndL;		nReplace = 1;		// Pre-adjust since <NAME/> becomes <NAME>data</NAME>		string strTagName = x_GetTagName( iPos );		m_aPos[iPos].nStartR -= 1;		m_aPos[iPos].nEndL -= (1 + strTagName.size());		string strFormat;		strFormat = ">";		strFormat += strInsert;		strFormat += "</";		strFormat += strTagName;		strInsert = strFormat;	}	else	{		nInsertAt = m_aPos[iPos].nStartR+1;		nReplace = m_aPos[iPos].nEndL - m_aPos[iPos].nStartR - 1;	}	x_DocChange( nInsertAt, nReplace, strInsert );	int nAdjust = strInsert.size() - nReplace;	x_Adjust( iPos, nAdjust );	m_aPos[iPos].AdjustEnd( nAdjust );	MARKUP_SETDEBUGSTATE;	return true;}string CMarkupSTL::x_GetData( int iPos ) const{	// Return a string representing data between start and end tag	// Return empty string if there are any children elements	if ( ! m_aPos[iPos].iElemChild && ! m_aPos[iPos].IsEmptyElement() )	{		// See if it is a CDATA section		TokenPos token( m_strDoc.c_str() );		token.nNext = m_aPos[iPos].nStartR+1;		if ( x_FindToken( token ) && m_strDoc[token.nL] == '<'				&& token.nL + 11 < m_aPos[iPos].nEndL				&& strncmp( &token.szDoc[token.nL+1], "![CDATA[", 8 ) == 0 )		{			int nEndCDATA = m_strDoc.find( "]]>", token.nNext );			if ( nEndCDATA != string::npos && nEndCDATA < m_aPos[iPos].nEndL )			{				return m_strDoc.substr( token.nL+9, nEndCDATA-token.nL-9 );			}		}		return x_TextFromDoc( m_aPos[iPos].nStartR+1, m_aPos[iPos].nEndL-1 );	}	return "";}string CMarkupSTL::x_TextToDoc( const char* szText, bool bAttrib ) const{	//	// &lt;   less than	// &amp;  ampersand	// &gt;   greater than	//	// and for attributes:	//	// &apos; apostrophe or single quote	// &quot; double quote	//	static char* szaReplace[] = { "&lt;","&amp;","&gt;","&apos;","&quot;" };	const char* pFind = bAttrib?"<&>\'\"":"<&>";	const char* pSource = szText;	string strResult;	int nLen = strlen( szText );	strResult.reserve( nLen + nLen / 10 );	char cSource = *pSource;	char* pFound;	while ( cSource )	{		if ( (pFound=strchr(pFind,cSource)) != NULL )		{			pFound = szaReplace[pFound-pFind];

⌨️ 快捷键说明

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