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

📄 xml.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{
#endif
		if ( ParseMatch( pszXML, _T("<?xml version=\"") ) )
		{
			pszElement = _tcsstr( pszXML, _T("?>") );
			if ( ! pszElement ) return FALSE;
			pszXML = pszElement + 2;
		}
		else if ( bHeader ) return NULL;
		
		while ( ParseMatch( pszXML, _T("<!--") ) )
		{
			pszElement = _tcsstr( pszXML, _T("-->") );
			if ( ! pszElement || *pszElement != '-' ) return FALSE;
			pszXML = pszElement + 3;
		}
		
		if ( ParseMatch( pszXML, _T("<!DOCTYPE") ) )
		{
			pszElement = _tcsstr( pszXML, _T(">") );
			if ( ! pszElement ) return FALSE;
			pszXML = pszElement + 1;
		}
		
		while ( ParseMatch( pszXML, _T("<!--") ) )
		{
			pszElement = _tcsstr( pszXML, _T("-->") );
			if ( ! pszElement || *pszElement != '-' ) return FALSE;
			pszXML = pszElement + 3;
		}
		
		pElement = new CXMLElement();
		
		if ( ! pElement->ParseString( pszXML ) )
		{
			delete pElement;
			pElement = NULL;
		}
#ifdef _AFX
	}
	catch ( CException* pException )
	{
		pException->Delete();
		delete pElement;
		pElement = NULL;
	}
#endif
	
	return pElement;
}

BOOL CXMLElement::ParseString(LPCTSTR& strXML)
{
	if ( ! ParseMatch( strXML, _T("<") ) ) return FALSE;
	
	if ( ! ParseIdentifier( strXML, m_sName ) ) return FALSE;
	
	LPCTSTR pszEnd = strXML + _tcslen( strXML );
	
	while ( ! ParseMatch( strXML, _T(">") ) )
	{
		if ( ParseMatch( strXML, _T("/") ) )
		{
			return ParseMatch( strXML, _T(">") );
		}
		
		if ( ! *strXML || strXML >= pszEnd ) return FALSE;
		
		CXMLAttribute* pAttribute = new CXMLAttribute( this );
		
		if ( pAttribute->ParseString( strXML ) )
		{
			CString strName( pAttribute->m_sName );
			CXMLAttribute* pExisting;
			strName.MakeLower();
			if ( m_pAttributes.Lookup( strName, XMLVOID(pExisting) ) ) delete pExisting;
			m_pAttributes.SetAt( strName, pAttribute );
		}
		else
		{
			delete pAttribute;
			return FALSE;
		}
	}
	
	CString strClose = _T("</");
	strClose += m_sName + '>';
	
	while ( TRUE )
	{
		if ( ! *strXML || strXML >= pszEnd ) return FALSE;

		LPCTSTR pszElement = _tcschr( strXML, '<' );
		if ( ! pszElement || *pszElement != '<' ) return FALSE;
		
		if ( pszElement > strXML )
		{
			if ( m_sValue.GetLength() && m_sValue.Right( 1 ) != ' ' ) m_sValue += ' ';
			m_sValue += StringToValue( strXML, (int)( pszElement - strXML ) );
			ASSERT( strXML == pszElement );
			if ( strXML != pszElement ) return FALSE;
		}

		if ( ParseMatch( strXML, strClose ) )
		{
			break;
		}
		else if ( ParseMatch( strXML, _T("<!--") ) )
		{
			pszElement = _tcsstr( strXML, _T("-->") );
			if ( ! pszElement || *pszElement != '-' ) return FALSE;
			strXML = pszElement + 3;
		}
		else
		{
			CXMLElement* pElement = new CXMLElement( this );

			if ( pElement->ParseString( strXML ) )
			{
				m_pElements.AddTail( pElement );
			}
			else
			{
				delete pElement;
				return FALSE;
			}
		}
	}

	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CXMLElement from bytes

CXMLElement* CXMLElement::FromBytes(BYTE* pByte, DWORD nByte, BOOL bHeader)
{
	CString strXML;
	
	if ( nByte >= 2 && ( ( pByte[0] == 0xFE && pByte[1] == 0xFF ) || ( pByte[0] == 0xFF && pByte[1] == 0xFE ) ) )
	{
		nByte = nByte / 2 - 1;
		
		if ( pByte[0] == 0xFE && pByte[1] == 0xFF )
		{
			pByte += 2;
			
			for ( DWORD nSwap = 0 ; nSwap < nByte ; nSwap ++ )
			{
				register CHAR nTemp = pByte[ ( nSwap << 1 ) + 0 ];
				pByte[ ( nSwap << 1 ) + 0 ] = pByte[ ( nSwap << 1 ) + 1 ];
				pByte[ ( nSwap << 1 ) + 1 ] = nTemp;
			}
		}
		else
		{
			pByte += 2; 
		}
		
#ifdef _UNICODE
		CopyMemory( strXML.GetBuffer( nByte ), pByte, nByte * sizeof(TCHAR) );
		strXML.ReleaseBuffer( nByte );
#else
		int nChars = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)pByte, nByte, NULL, 0, NULL, NULL );
		WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)pByte, nByte, strXML.GetBuffer( nChars ), nChars, NULL, NULL );
		strXML.ReleaseBuffer( nChars );
#endif
	}
	else
	{
		if ( nByte >= 3 && pByte[0] == 0xEF && pByte[1] == 0xBB && pByte[2] == 0xBF )
		{
			pByte += 3; nByte -= 3;
		}
		
		DWORD nWide = MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)pByte, nByte, NULL, 0 );
		
#ifdef _UNICODE
		MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)pByte, nByte, strXML.GetBuffer( nWide ), nWide );
		strXML.ReleaseBuffer( nWide );
#else
		WCHAR* pWide = new WCHAR[ nWide + 1 ];
		MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)pByte, nByte, pWide, nWide );
		pWide[ nWide ] = 0;
		strXML = pWide;
		delete [] pWide;
#endif
	}
	
	return FromString( strXML, bHeader );
}

//////////////////////////////////////////////////////////////////////
// CXMLElement from file

CXMLElement* CXMLElement::FromFile(LPCTSTR pszPath, BOOL bHeader)
{
	HANDLE hFile = CreateFile(	pszPath, GENERIC_READ, FILE_SHARE_READ, NULL,
								OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
	
	if ( hFile == INVALID_HANDLE_VALUE ) return NULL;
	
	CXMLElement* pXML = FromFile( hFile, bHeader );
	
	CloseHandle( hFile );
	
	return pXML;
}

CXMLElement* CXMLElement::FromFile(HANDLE hFile, BOOL bHeader)
{
	DWORD nByte = GetFileSize( hFile, NULL );
	if ( nByte > 4096*1024 ) return FALSE;
	
	BYTE* pByte = new BYTE[ nByte ];
	ReadFile( hFile, pByte, nByte, &nByte, NULL );
	
	CXMLElement* pXML = FromBytes( pByte, nByte, bHeader );
	
	delete [] pByte;
	
	return pXML;
}

//////////////////////////////////////////////////////////////////////
// CXMLElement equality

BOOL CXMLElement::Equals(CXMLElement* pXML) const
{
	if ( this == NULL || pXML == NULL ) return FALSE;
	if ( pXML == this ) return TRUE;
	
	if ( m_sName != pXML->m_sName ) return FALSE;
	if ( m_sValue != pXML->m_sValue ) return FALSE;
	
	if ( GetAttributeCount() != pXML->GetAttributeCount() ) return FALSE;
	if ( GetElementCount() != pXML->GetElementCount() ) return FALSE;
	
	for ( POSITION pos = GetAttributeIterator() ; pos ; )
	{
		CXMLAttribute* pAttribute1 = GetNextAttribute( pos );
		CXMLAttribute* pAttribute2 = pXML->GetAttribute( pAttribute1->m_sName );
		if ( pAttribute2 == NULL ) return FALSE;
		if ( ! pAttribute1->Equals( pAttribute2 ) ) return FALSE;
	}
	
	POSITION pos1 = GetElementIterator();
	POSITION pos2 = pXML->GetElementIterator();
	
	for ( ; pos1 && pos2 ; )
	{
		CXMLElement* pElement1 = GetNextElement( pos1 );
		CXMLElement* pElement2 = pXML->GetNextElement( pos2 );
		if ( pElement1 == NULL || pElement2 == NULL ) return FALSE;
		if ( ! pElement1->Equals( pElement2 ) ) return FALSE;
	}
	
	if ( pos1 != NULL || pos2 != NULL ) return FALSE;
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CXMLElement recursive word accumulation

CString CXMLElement::GetRecursiveWords()
{
	CString strWords;
	
	AddRecursiveWords( strWords );
	strWords.TrimLeft();
	strWords.TrimRight();

	return strWords;
}

void CXMLElement::AddRecursiveWords(CString& strWords)
{
	for ( POSITION pos = GetAttributeIterator() ; pos ; )
	{
		CXMLAttribute* pAttribute = GetNextAttribute( pos );
		CString strText = pAttribute->GetName();

		if ( strText.Find( ':' ) >= 0 ) continue;
		if ( strText.CompareNoCase( _T("SHA1") ) == 0 ) continue;	// NOTE: Shareaza Specific

		if ( strWords.GetLength() ) strWords += ' ';
		strWords += pAttribute->GetValue();
	}

	for ( pos = GetElementIterator() ; pos ; )
	{
		GetNextElement( pos )->AddRecursiveWords( strWords );
	}
	
	if ( m_sValue.GetLength() )
	{
		if ( strWords.GetLength() ) strWords += ' ';
		strWords += m_sValue;
	}
}

//////////////////////////////////////////////////////////////////////
// CXMLElement serialize

#ifdef _AFX

void CXMLElement::Serialize(CArchive& ar)
{
	CXMLNode::Serialize( ar );

	if ( ar.IsStoring() )
	{
		ar.WriteCount( GetAttributeCount() );
		
		for ( POSITION pos = GetAttributeIterator() ; pos ; )
		{
			GetNextAttribute( pos )->Serialize( ar );
		}

		ar.WriteCount( GetElementCount() );

		for ( pos = GetElementIterator() ; pos ; )
		{
			GetNextElement( pos )->Serialize( ar );
		}
	}
	else
	{
		for ( int nCount = (int)ar.ReadCount() ; nCount > 0 ; nCount-- )
		{
			CXMLAttribute* pAttribute = new CXMLAttribute( this );
			pAttribute->Serialize( ar );

			CString strName( pAttribute->m_sName );
			strName.MakeLower();
			m_pAttributes.SetAt( strName, pAttribute );
		}

		for ( nCount = (int)ar.ReadCount() ; nCount > 0 ; nCount-- )
		{
			CXMLElement* pElement = new CXMLElement( this );
			pElement->Serialize( ar );
			m_pElements.AddTail( pElement );
		}
	}
}

#endif


//////////////////////////////////////////////////////////////////////
// CXMLAttribute construction

LPCTSTR CXMLAttribute::xmlnsSchema		= _T("http://www.w3.org/2001/XMLSchema");
LPCTSTR CXMLAttribute::xmlnsInstance	= _T("http://www.w3.org/2001/XMLSchema-instance");
LPCTSTR CXMLAttribute::schemaName		= _T("xsi:noNamespaceSchemaLocation");

CXMLAttribute::CXMLAttribute(CXMLElement* pParent, LPCTSTR pszName) : CXMLNode( pParent, pszName )
{
	m_nNode = xmlAttribute;
}

CXMLAttribute::~CXMLAttribute()
{
}

//////////////////////////////////////////////////////////////////////
// CXMLAttribute clone

CXMLAttribute* CXMLAttribute::Clone(CXMLElement* pParent)
{
	CXMLAttribute* pClone = new CXMLAttribute( pParent, m_sName );
	pClone->m_sValue = m_sValue;
	return pClone;
}

//////////////////////////////////////////////////////////////////////
// CXMLAttribute to string

void CXMLAttribute::ToString(CString& strXML)
{
	strXML += m_sName + _T("=\"");
	ValueToString( m_sValue, strXML );
	strXML += '\"';
}

//////////////////////////////////////////////////////////////////////
// CXMLAttribute from string

BOOL CXMLAttribute::ParseString(LPCTSTR& strXML)
{
	if ( ! ParseIdentifier( strXML, m_sName ) ) return FALSE;
	if ( ! ParseMatch( strXML, _T("=") ) ) return FALSE;
	
	if ( ParseMatch( strXML, _T("\"") ) )
	{
		LPCTSTR pszQuote = _tcschr( strXML,  '\"' );
		if ( ! pszQuote || *pszQuote != '\"' ) return FALSE;
		
		m_sValue = StringToValue( strXML, (int)( pszQuote - strXML ) );
		
		return ParseMatch( strXML, _T("\"") );
	}
	else if ( ParseMatch( strXML, _T("'") ) )
	{
		LPCTSTR pszQuote = _tcschr( strXML,  '\'' );
		if ( ! pszQuote || *pszQuote != '\'' ) return FALSE;
		
		m_sValue = StringToValue( strXML, (int)( pszQuote - strXML ) );
		
		return ParseMatch( strXML, _T("\'") );
	}
	else
	{
		return FALSE;
	}
}

//////////////////////////////////////////////////////////////////////
// CXMLAttribute equality

BOOL CXMLAttribute::Equals(CXMLAttribute* pXML) const
{
	if ( this == NULL || pXML == NULL ) return FALSE;
	if ( pXML == this ) return TRUE;
	
	if ( m_sName != pXML->m_sName ) return FALSE;
	if ( m_sValue != pXML->m_sValue ) return FALSE;
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CXMLAttribute serialize

#ifdef _AFX

void CXMLAttribute::Serialize(CArchive& ar)
{
	CXMLNode::Serialize( ar );
}

#endif

⌨️ 快捷键说明

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