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

📄 matchobjects.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			UpdateRange( nCount, nCount );
			(*pLoop)->m_bSelected = FALSE;
			bChanged = TRUE;
		}
		
		for ( CQueryHit* pHit = (*pLoop)->m_pHits ; pHit ; pHit = pHit->m_pNext )
		{
			if ( pHit->m_bSelected )
			{
				UpdateRange( nCount, nCount );
				pHit->m_bSelected = FALSE;
				bChanged = TRUE;
			}
		}
	}
	
	m_pSelectedFiles.RemoveAll();
	m_pSelectedHits.RemoveAll();
	
	return bChanged;
}

//////////////////////////////////////////////////////////////////////
// CMatchList filter

void CMatchList::Filter()
{
	CSingleLock pLock( &m_pSection, TRUE );
	
	Settings.Search.FilterMask = 0;
	
	if ( m_bFilterBusy )		Settings.Search.FilterMask |= ( 1 << 0 );
	if ( m_bFilterPush )		Settings.Search.FilterMask |= ( 1 << 1 );
	if ( m_bFilterUnstable )	Settings.Search.FilterMask |= ( 1 << 2 );
	if ( m_bFilterReject )		Settings.Search.FilterMask |= ( 1 << 3 );
	if ( m_bFilterLocal )		Settings.Search.FilterMask |= ( 1 << 4 );
	if ( m_bFilterBogus	)		Settings.Search.FilterMask |= ( 1 << 5 );
	
	if ( m_pszFilter ) delete [] m_pszFilter;
	m_pszFilter = NULL;
	
	if ( m_sFilter.GetLength() )
	{
		LPCTSTR pszPtr = m_sFilter;
		BOOL bQuote = FALSE;
		BOOL bNot = FALSE;
		int nWordLen = 3;

		CStringList pWords;
		
		for ( int nStart = 0, nPos = 0 ; *pszPtr ; nPos++, pszPtr++ )
		{
			if ( *pszPtr == '\"' || ( ! bQuote && ( *pszPtr == ' ' || *pszPtr == '\t' || *pszPtr == '-' ) ) )
			{
				if ( nStart < nPos )
				{
					pWords.AddTail( ( bNot ? '-' : '+' ) + m_sFilter.Mid( nStart, nPos - nStart ) );
					nWordLen += ( nPos - nStart ) + 2;
				}
				
				nStart = nPos + 1;
				
				if ( *pszPtr == '\"' )
				{
					bQuote = ! bQuote;
				}
				else if ( *pszPtr == '-' && ! bQuote )
				{
					bNot = TRUE;
				}

				if ( bNot && ! bQuote && *pszPtr != '-' ) bNot = FALSE;
			}
		}
		
		if ( nStart < nPos )
		{
			pWords.AddTail( ( bNot ? '-' : '+' ) + m_sFilter.Mid( nStart, nPos - nStart ) );
			nWordLen += ( nPos - nStart ) + 2;
		}
		
		m_pszFilter = new TCHAR[ nWordLen ];
		LPTSTR pszFilter = m_pszFilter;
		
		for ( POSITION pos = pWords.GetHeadPosition() ; pos ; )
		{
			CString strWord = pWords.GetNext( pos );
			CopyMemory( pszFilter, (LPCTSTR)strWord, sizeof(TCHAR) * ( strWord.GetLength() + 1 ) );
			pszFilter += strWord.GetLength() + 1;
		}
		
		*pszFilter++ = 0;
		*pszFilter++ = 0;
	}
	
	CMatchFile** pLoop = m_pFiles;
	
	m_nItems			= 0;
	m_nFilteredFiles	= 0;
	m_nFilteredHits		= 0;
	
	for ( DWORD nCount = m_nFiles, nItems = 0 ; nCount ; nCount--, pLoop++ )
	{
		if ( nItems = (*pLoop)->Filter() )
		{
			m_nItems += nItems;
			m_nFilteredFiles ++;
			m_nFilteredHits += (*pLoop)->m_nFiltered;
		}
		else
		{
			if ( (*pLoop)->m_bSelected ) Select( *pLoop, NULL, FALSE );
		}
	}
	
	SetSortColumn( m_nSortColumn, m_bSortDir < 0 );
	UpdateRange();
}

//////////////////////////////////////////////////////////////////////
// CMatchList hit filtering

BOOL CMatchList::FilterHit(CQueryHit* pHit)
{
	pHit->m_bFiltered = FALSE;
	
	if ( m_bFilterBusy && pHit->m_bBusy == TS_TRUE ) return FALSE;
	if ( m_bFilterPush && pHit->m_bPush == TS_TRUE && pHit->m_nProtocol != PROTOCOL_ED2K ) return FALSE;
	if ( m_bFilterUnstable && pHit->m_bStable == TS_FALSE ) return FALSE;
	if ( m_bFilterReject && pHit->m_bMatched == FALSE ) return FALSE;
	if ( m_bFilterBogus && pHit->m_bBogus ) return FALSE;
	
	if ( m_nFilterMinSize > 0 && pHit->m_nSize < m_nFilterMinSize ) return FALSE;
	if ( m_nFilterMaxSize > 0 && pHit->m_nSize > m_nFilterMaxSize ) return FALSE;
	
	if ( m_pszFilter )
	{
		LPCTSTR pszName = pHit->m_sName;
		
		for ( LPCTSTR pszFilter = m_pszFilter ; *pszFilter ; )
		{
			if ( *pszFilter == '-' )
			{
				if ( _tcsistr( pszName, pszFilter + 1 ) != NULL ) return FALSE;
			}
			else
			{
				if ( _tcsistr( pszName, pszFilter + 1 ) == NULL ) return FALSE;
			}

			pszFilter += _tcslen( pszFilter + 1 ) + 2;
		}
	}
	
	if ( pHit->m_nSpeed )
		pHit->m_sSpeed = Settings.SmartVolume( pHit->m_nSpeed, TRUE, TRUE );
	else
		pHit->m_sSpeed.Empty();
	
	return ( pHit->m_bFiltered = TRUE );
}

//////////////////////////////////////////////////////////////////////
// CMatchList schema selection

void CMatchList::SelectSchema(CSchema* pSchema, CPtrList* pColumns)
{
	CSingleLock pLock( &m_pSection, TRUE );

	CMatchFile** pLoop = m_pFiles;

	for ( DWORD nCount = m_nFiles ; nCount ; nCount--, pLoop++ )
	{
		if ( (*pLoop)->m_pColumns )
		{
			delete [] (*pLoop)->m_pColumns;
			(*pLoop)->m_pColumns = NULL;
			(*pLoop)->m_nColumns = 0;
		}
	}
	
	if ( m_pColumns ) delete [] m_pColumns;
	m_pColumns	= NULL;
	m_nColumns	= 0;
	m_pSchema	= pSchema;

	if ( ! pSchema || ! pColumns ) return;

	m_pColumns = new CSchemaMember*[ pColumns->GetCount() ];

	for ( POSITION pos = pColumns->GetHeadPosition() ; pos ; )
	{
		m_pColumns[ m_nColumns++ ] = (CSchemaMember*)pColumns->GetNext( pos );
	}

	Filter();
}

//////////////////////////////////////////////////////////////////////
// CMatchList sort column selection

void CMatchList::SetSortColumn(int nColumn, BOOL bDirection)
{
	m_nSortColumn	= nColumn;
	m_bSortDir		= bDirection ? -1 : 1;

	if ( m_nSortColumn < 0 || ! m_nFiles ) return;

	int nFirst		= 0;
	int nLast		= m_nFiles - 1;
	DWORD nStack	= 0;

	int nStackFirst[128];
	int nStackLast[128];

	for ( ; ; )
	{
		if ( nLast - nFirst <= 16 )
		{
			int nIndex;
			CMatchFile* pPrevious = m_pFiles[ nFirst ];
			CMatchFile* pCurrent;

			for ( nIndex = nFirst + 1 ; nIndex <= nLast ; ++nIndex )
			{
				pCurrent = m_pFiles[ nIndex ];

				if ( pPrevious->Compare( pCurrent ) == m_bSortDir )
				{
					int nIndex2;
					m_pFiles[ nIndex ] = pPrevious;

					for ( nIndex2 = nIndex - 1 ; nIndex2 > nFirst ; )
					{
						CMatchFile* pTemp = m_pFiles[ nIndex2 - 1 ];

						if ( pTemp->Compare( pCurrent ) == m_bSortDir )
						{
							m_pFiles[ nIndex2-- ] = pTemp;
						}
						else break;
					}
					m_pFiles[ nIndex2 ] = pCurrent;
				}
				else
				{
					pPrevious = pCurrent;
				}
			}
		}
		else
		{
			CMatchFile* pPivot;
			{
				CMatchFile* pTemp;
				DWORD nMiddle = ( nFirst + nLast ) >> 1;

				pTemp = m_pFiles[ nFirst ];
				if ( pTemp->Compare( m_pFiles[ nLast ] ) == m_bSortDir )
				{
					m_pFiles[ nFirst ] = m_pFiles[ nLast ]; m_pFiles[ nLast ] = pTemp;
				}

				pTemp = m_pFiles[ nMiddle ];
				if ( m_pFiles[ nFirst ]->Compare( pTemp ) == m_bSortDir )
				{
					m_pFiles[ nMiddle ] = m_pFiles[ nFirst ]; m_pFiles[ nFirst ] = pTemp;
				}

				pTemp = m_pFiles[ nLast ];
				if ( m_pFiles[ nMiddle ]->Compare( pTemp ) == m_bSortDir )
				{
					m_pFiles[ nLast ] = m_pFiles[ nMiddle ]; m_pFiles[ nMiddle ] = pTemp;
				}
				pPivot = m_pFiles[ nMiddle ];
			}
			{
				DWORD nUp;
				{
					DWORD nDown = nFirst;
					nUp = nLast;

					for ( ; ; )
					{
						do
						{
							++nDown;
						} while ( pPivot->Compare( m_pFiles[ nDown ] ) == m_bSortDir );
						do
						{
							--nUp;
						} while ( m_pFiles[ nUp ]->Compare( pPivot ) == m_bSortDir );

						if ( nUp > nDown )
						{
							CMatchFile* pTemp = m_pFiles[ nDown ];
							m_pFiles[ nDown ] = m_pFiles[ nUp ];
							m_pFiles[ nUp ] = pTemp;
						}
						else
							break;
					}
				}
				{
					if ( ( nUp - nFirst + 1 ) >= ( nLast - nUp ) )
					{
						nStackFirst[ nStack ]	= nFirst;
						nStackLast[ nStack++ ]	= nUp;

						nFirst = nUp + 1;
					}
					else
					{
						nStackFirst[ nStack ]	= nUp + 1;
						nStackLast[ nStack++ ]	= nLast;

						nLast = nUp;
					}
				}
				continue;
			}
		}

		if ( nStack > 0 )
		{
			nFirst = nStackFirst[ --nStack ];
			nLast = nStackLast[ nStack ];
		}
		else
			break;
	}

	UpdateRange();
}

//////////////////////////////////////////////////////////////////////
// CMatchList updates

void CMatchList::UpdateRange(DWORD nMin, DWORD nMax)
{
	m_nUpdateMin = min( m_nUpdateMin, nMin );
	m_nUpdateMax = max( m_nUpdateMax, nMax );
	m_bUpdated = TRUE;
}

void CMatchList::ClearUpdated()
{
	m_bUpdated		= FALSE;
	m_nUpdateMin	= 0xFFFFFFFF;
	m_nUpdateMax	= 0;
}

//////////////////////////////////////////////////////////////////////
// CMatchList clear new

void CMatchList::ClearNew()
{
	CSingleLock pLock( &m_pSection, TRUE );
	
	for ( DWORD nFile = 0 ; nFile < m_nFiles ; nFile++ )
	{
		m_pFiles[ nFile ]->ClearNew();
	}
	
	m_bNew = TRUE;
}

//////////////////////////////////////////////////////////////////////
// CMatchList serialize

void CMatchList::Serialize(CArchive& ar)
{
	int nVersion = 11;
	
	if ( ar.IsStoring() )
	{
		ar << nVersion;
		
		ar << m_sFilter;
		ar << m_bFilterBusy;
		ar << m_bFilterPush;
		ar << m_bFilterUnstable;
		ar << m_bFilterReject;
		ar << m_bFilterLocal;
		ar << m_bFilterBogus;
		ar << m_nFilterMinSize;
		ar << m_nFilterMaxSize;
		ar << m_nFilterSources;
		ar << m_nSortColumn;
		ar << m_bSortDir;
		
		ar.WriteCount( m_nFiles );
		
		for ( DWORD nFile = 0 ; nFile < m_nFiles ; nFile++ )
		{
			CMatchFile* pFile = m_pFiles[ nFile ];
			pFile->Serialize( ar, nVersion );
		}
	}
	else
	{
		ar >> nVersion;
		if ( nVersion < 8 ) AfxThrowUserException();
		
		ar >> m_sFilter;
		ar >> m_bFilterBusy;
		ar >> m_bFilterPush;
		ar >> m_bFilterUnstable;
		ar >> m_bFilterReject;
		ar >> m_bFilterLocal;
		ar >> m_bFilterBogus;
		
		if ( nVersion >= 10 )
		{
			ar >> m_nFilterMinSize;
			ar >> m_nFilterMaxSize;
		}
		else
		{
			DWORD nInt32;
			ar >> nInt32; m_nFilterMinSize = nInt32;
			ar >> nInt32; m_nFilterMaxSize = nInt32;
		}
		
		ar >> m_nFilterSources;
		ar >> m_nSortColumn;
		ar >> m_bSortDir;
		
		m_nFiles = m_nBuffer = ar.ReadCount();
		m_pFiles = new CMatchFile*[ m_nFiles ];
		ZeroMemory( m_pFiles, sizeof(CMatchFile*) * m_nFiles );
		
		for ( DWORD nFile = 0 ; nFile < m_nFiles ; nFile++ )
		{
			CMatchFile* pFile = new CMatchFile( this );
			m_pFiles[ nFile ] = pFile;
			pFile->Serialize( ar, nVersion );
			
			CMatchFile** pMap = m_pSizeMap + (DWORD)( pFile->m_nSize & 0xFF );
			pFile->m_pNextSize = *pMap;
			*pMap = pFile;
			
			if ( pFile->m_bSHA1 )
			{
				pMap = m_pMapSHA1 + ( pFile->m_pSHA1.n[0] );
				pFile->m_pNextSHA1 = *pMap;
				*pMap = pFile;
			}
			if ( pFile->m_bTiger )
			{
				pMap = m_pMapTiger + ( pFile->m_pTiger.n[0] );
				pFile->m_pNextTiger = *pMap;
				*pMap = pFile;
			}
			if ( pFile->m_bED2K )
			{
				pMap = m_pMapED2K + ( pFile->m_pED2K.n[0] );
				pFile->m_pNextED2K = *pMap;
				*pMap = pFile;
			}
		}
		
		Filter();
	}
}


//////////////////////////////////////////////////////////////////////
// CMatchFile construction

CMatchFile::CMatchFile(CMatchList* pList, CQueryHit* pHit)
{
	m_pList		= pList;
	m_pHits		= NULL;
	m_pBest		= NULL;
	m_nTotal	= NULL;
	m_nFiltered	= 0;
	m_nSources	= 0;
	
	m_pNextSize		= NULL;
	m_pNextSHA1		= NULL;
	m_pNextTiger	= NULL;
	m_pNextED2K		= NULL;
	
	m_bSHA1		= FALSE;
	m_bTiger	= FALSE;
	m_bED2K		= FALSE;
	m_nSize		= pHit ? pHit->m_nSize : 0;
	m_sSize		= Settings.SmartVolume( m_nSize, FALSE );
	
	m_bBusy			= TS_UNKNOWN;
	m_bPush			= TS_UNKNOWN;
	m_bStable		= TS_UNKNOWN;
	m_bPreview		= FALSE;
	m_nSpeed		= 0;
	m_nRating		= 0;
	m_nRated		= 0;
	m_bDRM			= FALSE;
	m_bCollection	= FALSE;
	
	m_bExpanded		= Settings.Search.ExpandMatches;
	m_bSelected		= FALSE;
	m_bExisting		= FALSE;
	m_bDownload		= FALSE;
	m_bNew			= FALSE;
	m_bOneValid		= FALSE;
	m_nShellIndex	= -1;
	m_pColumns		= NULL;
	m_nColumns		= 0;
	m_pPreview		= NULL;
	m_nPreview		= 0;
	
	if ( pHit ) Add( pHit );
}

CMatchFile::~CMatchFile()
{
	while ( m_pHits )
	{
		CQueryHit* pNext = m_pHits->m_pNext;
		delete m_pHits;
		m_pHits = pNext;
	}
	
	if ( m_pColumns ) delete [] m_pColumns;
	if ( m_pPreview ) delete [] m_pPreview;
}

//////////////////////////////////////////////////////////////////////
// CMatchFile add

BOOL CMatchFile::Add(CQueryHit* pHit, BOOL bForce)

⌨️ 快捷键说明

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