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

📄 querysearch.cpp

📁 p2p软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				pPacket->Read( &m_pSHA1, sizeof(SHA1) );
			}
			else if ( nLength >= 44 && ( strURN == _T("bp") || strURN == _T("bitprint") ) )
			{
				m_bSHA1 = TRUE;
				pPacket->Read( &m_pSHA1, sizeof(SHA1) );
				m_bTiger = TRUE;
				pPacket->Read( &m_pTiger, sizeof(TIGEROOT) );
			}
			else if ( nLength >= 24 && ( strURN == _T("ttr") || strURN == _T("tree:tiger/") ) )
			{
				m_bTiger = TRUE;
				pPacket->Read( &m_pTiger, sizeof(TIGEROOT) );
			}
			else if ( nLength >= 16 && strURN == _T("ed2k") )
			{
				m_bED2K = TRUE;
				pPacket->Read( &m_pED2K, sizeof(MD4) );
			}
			else if ( nLength >= 20 && strURN == _T("btih") )
			{
				m_bBTH = TRUE;
				pPacket->Read( &m_pBTH, sizeof(SHA1) );
			}
		}
		else if ( strcmp( szType, "DN" ) == 0 )
		{
			m_sSearch = pPacket->ReadString( nLength );
		}
		else if ( strcmp( szType, "MD" ) == 0 )
		{
			CString strXML = pPacket->ReadString( nLength );
			
			m_pXML->Delete();
			m_pXML = CXMLElement::FromString( strXML );
			m_pSchema = NULL;
			
			if ( m_pXML != NULL )
			{
				if ( CXMLAttribute *pURI = m_pXML->GetAttribute( CXMLAttribute::schemaName ) )
				{
					m_pSchema = SchemaCache.Get( pURI->GetValue() );
				}
				else if ( m_pSchema = SchemaCache.Guess( m_pXML->GetName() ) )
				{
					CXMLElement* pRoot = m_pSchema->Instantiate( TRUE );
					pRoot->AddElement( m_pXML );
					m_pXML = pRoot;
				}
			}
		}
		else if ( strcmp( szType, "SZR" ) == 0 )
		{
			if ( nLength == 8 )
			{
				m_nMinSize = pPacket->ReadLongBE();
				m_nMaxSize = pPacket->ReadLongBE();
				if ( m_nMaxSize == 0xFFFFFFFF ) m_nMaxSize = SIZE_UNKNOWN;
			}
			else if ( nLength == 16 )
			{
				m_nMinSize = pPacket->ReadInt64();
				m_nMaxSize = pPacket->ReadInt64();
			}
		}
		else if ( strcmp( szType, "G1" ) == 0 )
		{
			m_bAndG1 = TRUE;
		}
		
		pPacket->m_nPosition = nOffset;
	}
	
	if ( pPacket->GetRemaining() < 16 ) return FALSE;
	
	pPacket->Read( &m_pGUID, sizeof(GGUID) );
	
	return CheckValid();
}

//////////////////////////////////////////////////////////////////////
// CQuerySearch validity check

BOOL CQuerySearch::CheckValid()
{
	BuildWordList();
	
	if ( m_nWords == 1 )
	{
		if ( _tcsicmp( *m_pWordPtr, _T("mp3") ) == 0 ||
			 _tcsicmp( *m_pWordPtr, _T("mpg") ) == 0 ||
			 _tcsicmp( *m_pWordPtr, _T("avi") ) == 0 ||
			 _tcsicmp( *m_pWordPtr, _T("ogg") ) == 0 ||
			 _tcsicmp( *m_pWordPtr, _T("mpg") ) == 0 ||
			 _tcsicmp( *m_pWordPtr, _T("sex") ) == 0 ||
			 _tcsicmp( *m_pWordPtr, _T("fuck") ) == 0 )
		{
			return FALSE;
		}
	}
	
	return m_nWords || m_bSHA1 || m_bTiger || m_bED2K || m_bBTH;
}

//////////////////////////////////////////////////////////////////////
// CQuerySearch schema SHA1 to raw SHA1

BOOL CQuerySearch::GetHashFromXML()
{
	if ( ! m_pXML || m_bSHA1 ) return FALSE;
	
	if ( CXMLElement* pBody = m_pXML->GetFirstElement() )
	{
		CString strHash	= pBody->GetAttributeValue( _T("SHA1"), NULL );
		m_bSHA1			= CSHA::HashFromString( strHash, &m_pSHA1 );
		
		if ( m_bSHA1 )
		{
			CXMLAttribute* pAttribute = pBody->GetAttribute( _T("SHA1") );
			if ( pAttribute ) pAttribute->Delete();
		}
	}
	
	return m_bSHA1;
}

//////////////////////////////////////////////////////////////////////
// CQuerySearch matching

BOOL CQuerySearch::Match(LPCTSTR pszFilename, QWORD nSize, LPCTSTR pszSchemaURI, CXMLElement* pXML, SHA1* pSHA1, TIGEROOT* pTiger, MD4* pED2K)
{
	if ( nSize < m_nMinSize || nSize > m_nMaxSize ) return FALSE;
	
	if ( m_bSHA1 )
	{
		return pSHA1 != NULL && ( m_pSHA1 == *pSHA1 );
	}
	else if ( m_bTiger )
	{
		return pTiger != NULL && ( m_pTiger == *pTiger );
	}
	else if ( m_bED2K )
	{
		return pED2K != NULL && ( memcmp( &m_pED2K, pED2K, sizeof(MD4) ) == 0 );
	}
	
	if ( pszSchemaURI && *pszSchemaURI && pXML )
	{
		TRISTATE bResult = MatchMetadata( pszSchemaURI, pXML );
		if ( bResult != TS_UNKNOWN ) return ( bResult == TS_TRUE );
		
		if ( m_sSearch.GetLength() > 0 )
		{
			if ( MatchMetadataShallow( pszSchemaURI, pXML ) ) return TRUE;
		}
	}
	
	return m_sSearch.GetLength() && WordMatch( pszFilename, m_sSearch );
}

TRISTATE CQuerySearch::MatchMetadata(LPCTSTR pszSchemaURI, CXMLElement* pXML)
{
	if ( ! m_pSchema || ! m_pXML ) return TS_UNKNOWN;
	if ( ! pszSchemaURI || ! *pszSchemaURI || ! pXML ) return TS_UNKNOWN;
	if ( ! m_pSchema->CheckURI( pszSchemaURI ) ) return TS_FALSE;
	
	CXMLElement* pRoot = m_pXML->GetFirstElement();
	int nCount = 0;
	
	for ( POSITION pos = m_pSchema->GetMemberIterator() ; pos ; )
	{
		CSchemaMember* pMember = m_pSchema->GetNextMember( pos );
		
		CString strSearch = pMember->GetValueFrom( pRoot );
		CString strTarget = pMember->GetValueFrom( pXML );
		
		if ( strSearch.GetLength() )
		{
			if ( strTarget.GetLength() )
			{
				if ( pMember->m_bNumeric )
				{
					if ( ! NumberMatch( strTarget, strSearch ) ) return TS_FALSE;
				}
				else
				{
					if ( ! WordMatch( strTarget, strSearch ) ) return TS_FALSE;
				}
				
				nCount++;
			}
			else
			{
				return TS_FALSE;
			}
		}
	}
	
	return ( nCount > 0 ) ? TS_TRUE : TS_UNKNOWN;
}

BOOL CQuerySearch::MatchMetadataShallow(LPCTSTR pszSchemaURI, CXMLElement* pXML)
{
	if ( ! pXML || m_sSearch.IsEmpty() ) return FALSE;
	
	if ( CSchema* pSchema = SchemaCache.Get( pszSchemaURI ) )
	{
		for ( POSITION pos = pSchema->GetMemberIterator() ; pos ; )
		{
			CSchemaMember* pMember = pSchema->GetNextMember( pos );
			
			if ( pMember->m_bSearched )
			{
				CString strTarget = pMember->GetValueFrom( pXML, _T(""), FALSE );
				if ( WordMatch( strTarget, m_sSearch ) ) return TRUE;
			}
		}
	}
	else
	{
		for ( POSITION pos = pXML->GetAttributeIterator() ; pos ; )
		{
			CXMLAttribute* pAttribute = pXML->GetNextAttribute( pos );

			CString strTarget = pAttribute->GetValue();

			if ( WordMatch( strTarget, m_sSearch ) ) return TRUE;
		}
	}
	
	return FALSE;
}

BOOL CQuerySearch::WordMatch(LPCTSTR pszString, LPCTSTR pszFind)
{
	LPCTSTR pszWord	= pszFind;
	LPCTSTR pszPtr	= pszFind;
	BOOL bQuote		= FALSE;
	BOOL bNegate	= FALSE;
	BOOL bSpace		= TRUE;
	int nCount		= 0;
	
	for ( ; *pszPtr ; pszPtr++ )
	{
		if ( ( bQuote && *pszPtr == '\"' ) || ( ! bQuote && ( *pszPtr <= ' ' || *pszPtr == '\t' || *pszPtr == '-' || *pszPtr == '\"' ) ) )
		{
			if ( pszWord < pszPtr )
			{
				if ( bNegate )
				{
					if ( _tcsnistr( pszString, pszWord, pszPtr - pszWord ) ) return FALSE;
				}
				else
				{
					if ( ! _tcsnistr( pszString, pszWord, pszPtr - pszWord ) ) return FALSE;
				}
				
				nCount++;
			}
			
			pszWord	= pszPtr + 1;
			
			if ( *pszPtr == '\"' )
			{
				bQuote = ! bQuote;
				bSpace = TRUE;
			}
			else if ( *pszPtr == '-' && bSpace && ! bQuote )
			{
				bNegate = TRUE;
				bSpace = FALSE;
			}
			else
			{
				bSpace = ( *pszPtr == ' ' );
			}
			
			if ( bNegate && ! bQuote && *pszPtr != '-' ) bNegate = FALSE;
		}
		else
		{
			bSpace = FALSE;
		}
	}
	
	if ( pszWord < pszPtr )
	{
		if ( bNegate )
		{
			if ( _tcsnistr( pszString, pszWord, pszPtr - pszWord ) ) return FALSE;
		}
		else
		{
			if ( ! _tcsnistr( pszString, pszWord, pszPtr - pszWord ) ) return FALSE;
		}
		
		nCount++;
	}
	
	return nCount > 0;
}

BOOL CQuerySearch::NumberMatch(const CString& strValue, const CString& strRange)
{
	double nValue, nMinimum, nMaximum;

	if ( _stscanf( strValue, _T("%lf"), &nValue ) != 1 ) return FALSE;

	int nPos = strRange.Find( '-' );

	if ( nPos < 0 )
	{
		return _stscanf( strRange, _T("%lf"), &nMinimum ) == 1 && nValue == nMinimum;
	}
	else if ( nPos == 0 )
	{
		return _stscanf( (LPCTSTR)strRange + 1, _T("%lf"), &nMaximum ) && nValue <= nMaximum;
	}
	else if ( nPos == strRange.GetLength() - 1 )
	{
		return _stscanf( strRange, _T("%lf"), &nMinimum ) && nValue >= nMinimum;
	}
	else
	{
		if ( _stscanf( strRange.Left( nPos ), _T("%lf"), &nMinimum ) != 1 ||
			 _stscanf( strRange.Mid( nPos + 1 ), _T("%lf"), &nMaximum ) != 1 ) return FALSE;
		return nValue >= nMinimum && nValue <= nMaximum;
	}
}

//////////////////////////////////////////////////////////////////////
// CQuerySearch word list builder

void CQuerySearch::BuildWordList()
{
	m_nWords = 0;
	
	m_sSearch.MakeLower();
	AddStringToWordList( m_sSearch );
	
	if ( m_pXML == NULL ) return;
	
	if ( CXMLElement* pXML = m_pXML->GetFirstElement() )
	{
		if ( m_pSchema != NULL )
		{
			for ( POSITION pos = m_pSchema->GetMemberIterator() ; pos ; )
			{
				CSchemaMember* pMember = m_pSchema->GetNextMember( pos );
				
				if ( pMember->m_bIndexed )
				{
					if ( CXMLAttribute* pAttribute = pXML->GetAttribute( pMember->m_sName ) )
					{
						pAttribute->m_sValue.MakeLower();
						AddStringToWordList( pAttribute->m_sValue );
					}
				}
			}
		}
		else
		{
			for ( POSITION pos = pXML->GetAttributeIterator() ; pos ; )
			{
				CXMLAttribute* pAttribute = pXML->GetNextAttribute( pos );
				pAttribute->m_sValue.MakeLower();
				AddStringToWordList( pAttribute->m_sValue );
			}
		}
	}
}

void CQuerySearch::AddStringToWordList(LPCTSTR pszString)
{
	if ( ! *pszString ) return;

	LPCTSTR pszWord	= pszString;
	LPCTSTR pszPtr	= pszString;
	BOOL bQuote		= FALSE;
	BOOL bNegate	= FALSE;
	BOOL bSpace		= TRUE;
	
	for ( ; *pszPtr ; pszPtr++ )
	{
		if ( IsCharacter( *pszPtr ) )
		{
			bSpace = FALSE;
		}
		else
		{
			if ( ! bNegate && pszWord + 1 < pszPtr && IsWord( pszWord, 0, pszPtr - pszWord ) )
			{
				if ( ( m_nWords & 0x1F ) == 0 )
				{
					LPCTSTR* pWordPtr = new LPCTSTR[ ( m_nWords | 0x1F ) + 1 ];
					DWORD* pWordLen = new DWORD[ ( m_nWords | 0x1F ) + 1 ];
					if ( m_pWordPtr )
					{
						CopyMemory( pWordPtr, m_pWordPtr, 4 * m_nWords );
						CopyMemory( pWordLen, m_pWordLen, 4 * m_nWords );
						delete [] m_pWordPtr;
						delete [] m_pWordLen;
					}
					m_pWordPtr = pWordPtr;
					m_pWordLen = pWordLen;
				}
				
				m_pWordPtr[ m_nWords ] = pszWord;
				m_pWordLen[ m_nWords ] = pszPtr - pszWord;
				m_nWords++;
			}
			
			pszWord = pszPtr + 1;
			
			if ( *pszPtr == '\"' )
			{
				bQuote = ! bQuote;
				bSpace = TRUE;
			}
			else if ( *pszPtr == '-' && bSpace && ! bQuote )
			{
				bNegate = TRUE;
				bSpace = FALSE;
			}
			else
			{
				bSpace = ( *pszPtr == ' ' );
			}
			
			if ( bNegate && ! bQuote && *pszPtr != '-' ) bNegate = FALSE;
		}
	}
	
	if ( ! bNegate && pszWord + 1 < pszPtr && IsWord( pszWord, 0, pszPtr - pszWord ) )
	{
		if ( ( m_nWords & 0x1F ) == 0 )
		{
			LPCTSTR* pWordPtr = new LPCTSTR[ ( m_nWords | 0x1F ) + 1 ];
			DWORD* pWordLen = new DWORD[ ( m_nWords | 0x1F ) + 1 ];
			if ( m_pWordPtr )
			{
				CopyMemory( pWordPtr, m_pWordPtr, 4 * m_nWords );
				CopyMemory( pWordLen, m_pWordLen, 4 * m_nWords );
				delete [] m_pWordPtr;
				delete [] m_pWordLen;
			}
			m_pWordPtr = pWordPtr;
			m_pWordLen = pWordLen;
		}
		
		m_pWordPtr[ m_nWords ] = pszWord;
		m_pWordLen[ m_nWords ] = pszPtr - pszWord;
		m_nWords++;
	}
}

//////////////////////////////////////////////////////////////////////
// CQuerySearch serialization

void CQuerySearch::Serialize(CArchive& ar)
{
	int nVersion = 6;
	CString strURI;
	
	if ( ar.IsStoring() )
	{
		ar << nVersion;
		
		ar.Write( &m_pGUID, sizeof(GGUID) );
		
		ar << m_sSearch;
		
		ar << m_bSHA1;
		if ( m_bSHA1 ) ar.Write( &m_pSHA1, sizeof(SHA1) );
		ar << m_bTiger;
		if ( m_bTiger ) ar.Write( &m_pTiger, sizeof(TIGEROOT) );
		ar << m_bED2K;
		if ( m_bED2K ) ar.Write( &m_pED2K, sizeof(MD4) );
		ar << m_bBTH;
		if ( m_bBTH ) ar.Write( &m_pBTH, sizeof(SHA1) );
		
		if ( m_pSchema != NULL && m_pXML != NULL )
		{
			ar << m_pSchema->m_sURI;
			m_pXML->Serialize( ar );
		}
		else
		{
			ar << strURI;
		}

		ar << m_bWantURL;
		ar << m_bWantDN;
		ar << m_bWantXML;
		ar << m_bWantCOM;
		ar << m_bWantPFS;
	}
	else
	{
		ar >> nVersion;
		if ( nVersion < 4 ) AfxThrowUserException();
		
		ar.Read( &m_pGUID, sizeof(GGUID) );
		
		ar >> m_sSearch;
		
		ar >> m_bSHA1;
		if ( m_bSHA1 ) ar.Read( &m_pSHA1, sizeof(SHA1) );
		ar >> m_bTiger;
		if ( m_bTiger ) ar.Read( &m_pTiger, sizeof(TIGEROOT) );
		ar >> m_bED2K;
		if ( m_bED2K ) ar.Read( &m_pED2K, sizeof(MD4) );
		if ( nVersion >= 6 ) ar >> m_bBTH;
		if ( m_bBTH ) ar.Read( &m_pBTH, sizeof(SHA1) );
		
		ar >> strURI;
		
		if ( strURI.GetLength() )
		{
			m_pSchema = SchemaCache.Get( strURI );
			m_pXML = new CXMLElement();
			m_pXML->Serialize( ar );
		}
		
		if ( nVersion >= 5 )
		{
			ar >> m_bWantURL;
			ar >> m_bWantDN;
			ar >> m_bWantXML;
			ar >> m_bWantCOM;
			ar >> m_bWantPFS;
		}
		
		BuildWordList();
	}
}

//////////////////////////////////////////////////////////////////////
// CQuerySearch open window

CSearchWnd* CQuerySearch::OpenWindow()
{
	if ( this == NULL ) return NULL;
	BuildWordList();
	if ( ! CheckValid() ) return NULL;
	return new CSearchWnd( this );
}

⌨️ 快捷键说明

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