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

📄 markupstl.cpp

📁 一个很好的vc底层代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// MarkupSTL.cpp: implementation of the CMarkupSTL class.//// Markup Release 6.3// Copyright (C) 1999-2002 First Objective Software, Inc. All rights reserved// Go to www.firstobject.com for the latest CMarkup and EDOM documentation// Use in commercial applications requires written permission// This software is provided "as is", with no warranty.#include "MarkupSTL.h"#include <stdio.h>using namespace std;#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endifvoid CMarkupSTL::operator=( const CMarkupSTL& markup ){	m_iPosParent = markup.m_iPosParent;	m_iPos = markup.m_iPos;	m_iPosChild = markup.m_iPosChild;	m_iPosFree = markup.m_iPosFree;	m_nNodeType = markup.m_nNodeType;	m_aPos = markup.m_aPos;	m_strDoc = markup.m_strDoc;	MARKUP_SETDEBUGSTATE;}bool CMarkupSTL::SetDoc( const char* szDoc ){	// Reset indexes	m_iPosFree = 1;	ResetPos();	m_mapSavedPos.clear();	// Set document text	if ( szDoc )		m_strDoc = szDoc;	else		m_strDoc.erase();	// Starting size of position array: 1 element per 64 bytes of document	// Tight fit when parsing small doc, only 0 to 2 reallocs when parsing large doc	// Start at 8 when creating new document	int nStartSize = m_strDoc.size() / 64 + 8;	if ( m_aPos.size() < nStartSize )		m_aPos.resize( nStartSize );	// Parse document	bool bWellFormed = false;	if ( m_strDoc.size() )	{		m_aPos[0].Clear();		int iPos = x_ParseElem( 0 );		if ( iPos > 0 )		{			m_aPos[0].iElemChild = iPos;			bWellFormed = true;		}	}	// Clear indexes if parse failed or empty document	if ( ! bWellFormed )	{		m_aPos[0].Clear();		m_iPosFree = 1;	}	ResetPos();	return bWellFormed;};bool CMarkupSTL::IsWellFormed(){	if ( m_aPos.size() && m_aPos[0].iElemChild )		return true;	return false;}bool CMarkupSTL::Load( const char* szFileName ){	// Load document from file	bool bResult = false;	FILE* fp = fopen( szFileName, "rb" );	if ( fp )	{		// Determine file length		fseek( fp, 0L, SEEK_END );		int nFileLen = ftell(fp);		fseek( fp, 0L, SEEK_SET );		// Load string		allocator<char> mem;		allocator<char>::pointer pBuffer = mem.allocate(nFileLen+1, NULL);		if ( fread( pBuffer, nFileLen, 1, fp ) == 1 )		{			pBuffer[nFileLen] = '\0';			bResult = SetDoc( pBuffer );		}		fclose(fp);		mem.deallocate(pBuffer,1);	}	if ( ! bResult )		SetDoc(NULL);	MARKUP_SETDEBUGSTATE;	return bResult;}bool CMarkupSTL::Save( const char* szFileName ){	// Save document to file	bool bResult = false;	FILE* fp = fopen( szFileName, "wb" );	if ( fp )	{		// Save string		int nFileLen = m_strDoc.size();		if ( ! nFileLen )			bResult = true;		else if ( fwrite( m_strDoc.c_str(), nFileLen, 1, fp ) == 1 )			bResult = true;		fclose(fp);	}	return bResult;}bool CMarkupSTL::FindElem( const char* szName ){	// Change current position only if found	//	if ( m_aPos.size() )	{		int iPos = x_FindElem( m_iPosParent, m_iPos, szName );		if ( iPos )		{			// Assign new position			x_SetPos( m_aPos[iPos].iElemParent, iPos, 0 );			return true;		}	}	return false;}bool CMarkupSTL::FindChildElem( const char* szName ){	// Change current child position only if found	//	// Shorthand: call this with no current main position	// means find child under root element	if ( ! m_iPos )		FindElem();	int iPosChild = x_FindElem( m_iPos, m_iPosChild, szName );	if ( iPosChild )	{		// Assign new position		int iPos = m_aPos[iPosChild].iElemParent;		x_SetPos( m_aPos[iPos].iElemParent, iPos, iPosChild );		return true;	}	return false;}string CMarkupSTL::GetTagName() const{	// Return the tag name at the current main position	string strTagName;	if ( m_iPos )		strTagName = x_GetTagName( m_iPos );	return strTagName;}bool CMarkupSTL::IntoElem(){	// If there is no child position and IntoElem is called it will succeed in release 6.3	// (A subsequent call to FindElem will find the first element)	// The following short-hand behavior was never part of EDOM and was misleading	// It would find a child element if there was no current child element position and go into it	// It is removed in release 6.3, this change is NOT backwards compatible!	// if ( ! m_iPosChild )	//	FindChildElem();	if ( m_iPos && m_nNodeType == MNT_ELEMENT )	{		x_SetPos( m_iPos, m_iPosChild, 0 );		return true;	}	return false;}bool CMarkupSTL::OutOfElem(){	// Go to parent element	if ( m_iPosParent )	{		x_SetPos( m_aPos[m_iPosParent].iElemParent, m_iPosParent, m_iPos );		return true;	}	return false;}string CMarkupSTL::GetAttribName( int n ) const{	// Return nth attribute name of main position	if ( ! m_iPos || m_nNodeType != MNT_ELEMENT )		return "";	TokenPos token( m_strDoc.c_str() );	token.nNext = m_aPos[m_iPos].nStartL + 1;	for ( int nAttrib=0; nAttrib<=n; ++nAttrib )		if ( ! x_FindAttrib(token) )			return "";	// Return substring of document	return x_GetToken( token );}bool CMarkupSTL::SavePos( const char* szPosName ){	// Save current element position in saved position map	if ( szPosName )	{		SavedPos savedpos;		savedpos.iPosParent = m_iPosParent;		savedpos.iPos = m_iPos;		savedpos.iPosChild = m_iPosChild;		string strPosName = szPosName;		m_mapSavedPos[strPosName] = savedpos;		return true;	}	return false;}bool CMarkupSTL::RestorePos( const char* szPosName ){	// Restore element position if found in saved position map	if ( szPosName )	{		string strPosName = szPosName;		mapSavedPosT::const_iterator iterSavePos = m_mapSavedPos.find( strPosName );		if ( iterSavePos != m_mapSavedPos.end() )		{			SavedPos savedpos = (*iterSavePos).second;			x_SetPos( savedpos.iPosParent, savedpos.iPos, savedpos.iPosChild );			return true;		}	}	return false;}bool CMarkupSTL::GetOffsets( int& nStart, int& nEnd ) const{	// Return document offsets of current main position element	// This is not part of EDOM but is used by the Markup project	if ( m_iPos )	{		nStart = m_aPos[m_iPos].nStartL;		nEnd = m_aPos[m_iPos].nEndR;		return true;	}	return false;}string CMarkupSTL::GetChildSubDoc() const{	if ( m_iPosChild )	{		int nL = m_aPos[m_iPosChild].nStartL;		int nR = m_aPos[m_iPosChild].nEndR + 1;		TokenPos token( m_strDoc.c_str() );		token.nNext = nR;		if ( ! x_FindToken(token) || m_strDoc[token.nL] == '<' )			nR = token.nL;		return m_strDoc.substr( nL, nR - nL );	}	return "";}bool CMarkupSTL::RemoveElem(){	// Remove current main position element	if ( m_iPos && m_nNodeType == MNT_ELEMENT )	{		int iPos = x_RemoveElem( m_iPos );		x_SetPos( m_iPosParent, iPos, 0 );		return true;	}	return false;}bool CMarkupSTL::RemoveChildElem(){	// Remove current child position element	if ( m_iPosChild )	{		int iPosChild = x_RemoveElem( m_iPosChild );		x_SetPos( m_iPosParent, m_iPos, iPosChild );		return true;	}	return false;}//////////////////////////////////////////////////////////////////////// Private Methods//////////////////////////////////////////////////////////////////////int CMarkupSTL::x_GetFreePos(){	//	// This returns the index of the next unused ElemPos in the array	//	if ( m_iPosFree == m_aPos.size() )		m_aPos.resize( m_iPosFree + m_iPosFree / 2 );	++m_iPosFree;	return m_iPosFree - 1;}int CMarkupSTL::x_ReleasePos(){	//	// This decrements the index of the next unused ElemPos in the array	// allowing the element index returned by GetFreePos() to be reused	//	--m_iPosFree;	return 0;}int CMarkupSTL::x_ParseError( const char* szError, const char* szName ){	if ( szName )	{		char szFormat[300];		sprintf( szFormat, szError, szName );		m_strError = szFormat;	}	else		m_strError = szError;	x_ReleasePos();	return -1;}int CMarkupSTL::x_ParseElem( int iPosParent ){	// This is either called by SetDoc, x_AddSubDoc, or itself recursively	// m_aPos[iPosParent].nEndL is where to start parsing for the child element	// This returns the new position if a tag is found, otherwise zero	// In all cases we need to get a new ElemPos, but release it if unused	//	int iPos = x_GetFreePos();	m_aPos[iPos].nStartL = m_aPos[iPosParent].nEndL;	m_aPos[iPos].iElemParent = iPosParent;	m_aPos[iPos].iElemChild = 0;	m_aPos[iPos].iElemNext = 0;	// Start Tag	// A loop is used to ignore all remarks tags and special tags	// i.e. <?xml version="1.0"?>, and <!-- comment here -->	// So any tag beginning with ? or ! is ignored	// Loop past ignored tags	TokenPos token( m_strDoc.c_str() );	token.nNext = m_aPos[iPosParent].nEndL;	string strName;	while ( strName.empty() )	{		// Look for left angle bracket of start tag		m_aPos[iPos].nStartL = token.nNext;		if ( ! x_FindChar( token.szDoc, m_aPos[iPos].nStartL, '<' ) )			return x_ParseError( "Element tag not found" );		// Set parent's End tag to start looking from here (or later)		m_aPos[iPosParent].nEndL = m_aPos[iPos].nStartL;		// Determine whether this is an element, or bypass other type of node		token.nNext = m_aPos[iPos].nStartL + 1;		if ( x_FindToken( token ) )		{			if ( token.bIsString )				return x_ParseError( "Tag starts with quote" );			char cFirstChar = m_strDoc[token.nL];			if ( cFirstChar == '?' || cFirstChar == '!' )			{				token.nNext = m_aPos[iPos].nStartL;				if ( ! x_ParseNode(token) )					return x_ParseError( "Invalid node" );			}			else if ( cFirstChar != '/' )			{				strName = x_GetToken( token );				// Look for end of tag				if ( ! x_FindChar(token.szDoc, token.nNext, '>') )					return x_ParseError( "End of tag not found" );			}			else				return x_ReleasePos(); // probably end tag of parent		}		else			return x_ParseError( "Abrupt end within tag" );	}	m_aPos[iPos].nStartR = token.nNext;	// Is ending mark within start tag, i.e. empty element?	if ( m_strDoc[m_aPos[iPos].nStartR-1] == '/' )	{		// Empty element		// Close tag left is set to ending mark, and right to open tag right		m_aPos[iPos].nEndL = m_aPos[iPos].nStartR-1;		m_aPos[iPos].nEndR = m_aPos[iPos].nStartR;	}	else // look for end tag	{		// Element probably has contents		// Determine where to start looking for left angle bracket of end tag		// This is done by recursively parsing the contents of this element		int iInner, iInnerPrev = 0;		m_aPos[iPos].nEndL = m_aPos[iPos].nStartR + 1;		while ( (iInner = x_ParseElem( iPos )) > 0 )		{			// Set links to iInner			if ( iInnerPrev )				m_aPos[iInnerPrev].iElemNext = iInner;			else				m_aPos[iPos].iElemChild = iInner;			iInnerPrev = iInner;			// Set offset to reflect child			m_aPos[iPos].nEndL = m_aPos[iInner].nEndR + 1;		}		if ( iInner == -1 )			return -1;		// Look for left angle bracket of end tag		if ( ! x_FindChar( token.szDoc, m_aPos[iPos].nEndL, '<' ) )			return x_ParseError( "End tag of %s element not found", strName.c_str() );		// Look through tokens of end tag		token.nNext = m_aPos[iPos].nEndL + 1;		int nTokenCount = 0;		while ( x_FindToken( token ) )		{			++nTokenCount;			if ( ! token.bIsString )			{				// Is first token not an end slash mark?				if ( nTokenCount == 1 && m_strDoc[token.nL] != '/' )					return x_ParseError( "Expecting end tag of element %s", strName.c_str() );				else if ( nTokenCount == 2 && ! token.Match(strName.c_str()) )					return x_ParseError( "End tag does not correspond to %s", strName.c_str() );				// Else is it a right angle bracket?				else if ( m_strDoc[token.nL] == '>' )					break;			}

⌨️ 快捷键说明

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