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

📄 downloadwithfile.cpp

📁 p2p软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		{
			nLength = (QWORD)( (double)nLargestLength * nNewSpeed / ( nNewSpeed + nOldSpeed ) );
			nLength = min( nLength, nLargestLength );
			
			if ( nLargestLength > 102400 )
			{
				nLength = max( nLength, 51200 );
				nLength = min( nLength, nLargestLength - 51200 );
			}
		}
		
		if ( pExisting->m_bRecvBackwards )
		{
			pTransfer->m_nOffset		= nLargestOffset;
			pTransfer->m_nLength		= nLength;
			pTransfer->m_bWantBackwards	= FALSE;
		}
		else
		{
			pTransfer->m_nOffset		= nLargestOffset + nLargestLength - nLength;
			pTransfer->m_nLength		= nLength;
			pTransfer->m_bWantBackwards	= TRUE;
		}
		
		return TRUE;
	}
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithFile check if a byte position is empty

BOOL CDownloadWithFile::IsPositionEmpty(QWORD nOffset)
{
	if ( m_pFile == NULL || ! m_pFile->IsValid() ) return FALSE;
	return m_pFile->IsPositionRemaining( nOffset );
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithFile check if a range would "help"

BOOL CDownloadWithFile::IsRangeUseful(QWORD nOffset, QWORD nLength)
{
	if ( m_pFile == NULL || ! m_pFile->IsValid() ) return 0;
	return m_pFile->DoesRangeOverlap( nOffset, nLength );
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithFile get a string of available ranges

CString CDownloadWithFile::GetAvailableRanges() const
{
	CString strRange, strRanges;
	QWORD nLast = 0;
	
	if ( m_pFile == NULL || ! m_pFile->IsValid() ) return strRanges;
	
	for ( CFileFragment* pFragment = m_pFile->GetFirstEmptyFragment() ; pFragment ; pFragment = pFragment->m_pNext )
	{
		if ( pFragment->m_nOffset > nLast )
		{
			if ( strRanges.IsEmpty() )
				strRanges = _T("bytes ");
			else
				strRanges += ',';
			
			strRange.Format( _T("%I64i-%I64i"), nLast, pFragment->m_nOffset - 1 );
			strRanges += strRange;
		}
		
		nLast = pFragment->m_nOffset + pFragment->m_nLength;
	}
	
	if ( m_nSize > nLast )
	{
		if ( strRanges.IsEmpty() )
			strRanges = _T("bytes ");
		else
			strRanges += ',';
		
		strRange.Format( _T("%I64i-%I64i"), nLast, m_nSize - 1 );
		strRanges += strRange;
	}
	
	return strRanges;
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithFile clip a range to valid portions

BOOL CDownloadWithFile::ClipUploadRange(QWORD nOffset, QWORD& nLength) const
{
	if ( m_pFile == NULL || ! m_pFile->IsValid() ) return FALSE;
	if ( nOffset >= m_nSize ) return FALSE;
	
	if ( m_pFile->IsPositionRemaining( nOffset ) ) return FALSE;
	
	for ( CFileFragment* pFragment = m_pFile->GetFirstEmptyFragment() ; pFragment ; pFragment = pFragment->m_pNext )
	{
		if ( pFragment->m_nOffset > nOffset )
		{
			if ( nOffset + nLength <= pFragment->m_nOffset ) return TRUE;
			nLength = pFragment->m_nOffset - nOffset;
			return ( nLength > 0 );
		}
	}
	
	if ( nLength > m_nSize - nOffset ) nLength = m_nSize - nOffset;
	
	return ( nLength > 0 );
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithFile select a random range of available data

BOOL CDownloadWithFile::GetRandomRange(QWORD& nOffset, QWORD& nLength) const
{
	if ( m_pFile == NULL || ! m_pFile->IsValid() ) return FALSE;
	
	CFileFragment* pFilled = m_pFile->CopyFilledFragments();
	
	if ( CFileFragment* pRandom = pFilled->GetRandom() )
	{
		nOffset = pRandom->m_nOffset;
		nLength = pRandom->m_nLength;
		pFilled->DeleteChain();
		return TRUE;
	}
	else
	{
		pFilled->DeleteChain();
		return FALSE;
	}
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithFile submit data

BOOL CDownloadWithFile::SubmitData(QWORD nOffset, LPBYTE pData, QWORD nLength)
{
	SetModified();
	m_tReceived = GetTickCount();
	
	if ( m_bBTH )	// Hack: Only do this for BitTorrent
	{
		for ( CDownloadTransfer* pTransfer = GetFirstTransfer() ; pTransfer ; pTransfer = pTransfer->m_pDlNext )
		{
			if ( pTransfer->m_nProtocol == PROTOCOL_BT ) pTransfer->UnrequestRange( nOffset, nLength );
		}
	}
	
	return m_pFile != NULL && m_pFile->WriteRange( nOffset, pData, nLength );
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithFile erase a range

QWORD CDownloadWithFile::EraseRange(QWORD nOffset, QWORD nLength)
{
	if ( m_pFile == NULL ) return 0;
	QWORD nCount = m_pFile->InvalidateRange( nOffset, nLength );
	if ( nCount > 0 ) SetModified();
	return nCount;
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithFile make the file appear complete

BOOL CDownloadWithFile::MakeComplete()
{
	if ( m_sLocalName.IsEmpty() ) return FALSE;
	if ( ! PrepareFile() ) return FALSE;
	return m_pFile->MakeComplete();
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithFile run the file

BOOL CDownloadWithFile::RunFile(DWORD tNow)
{
	if ( m_pFile->IsOpen() )
	{
		if ( m_pFile->GetRemaining() == 0 ) return TRUE;
	}
	
	return FALSE;
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithFile write the metadata

BOOL CDownloadWithFile::WriteMetadata(LPCTSTR pszPath)
{
	ASSERT( m_pXML != NULL );
	
	CString strXML = m_pXML->ToString( TRUE, TRUE );
	delete m_pXML;
	m_pXML = NULL;
	
	CString strMetadata;
	
	strMetadata.Format( _T("%s\\Metadata"), pszPath );
	CreateDirectory( strMetadata, NULL );
	SetFileAttributes( strMetadata, FILE_ATTRIBUTE_HIDDEN );
	
	strMetadata += m_sLocalName.Mid( m_sLocalName.ReverseFind( '\\' ) );
	strMetadata += _T(".xml");
	
	HANDLE hFile = CreateFile( strMetadata, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
								FILE_ATTRIBUTE_NORMAL, NULL );
	
	if ( hFile == INVALID_HANDLE_VALUE ) return FALSE;
	
	DWORD nWritten;
	
#ifdef _UNICODE
	int nASCII = WideCharToMultiByte( CP_UTF8, 0, strXML, strXML.GetLength(), NULL, 0, NULL, NULL );
	LPSTR pszASCII = new CHAR[ nASCII ];
	WideCharToMultiByte( CP_UTF8, 0, strXML, strXML.GetLength(), pszASCII, nASCII, NULL, NULL );
	WriteFile( hFile, pszASCII, nASCII, &nWritten, NULL );
	delete [] pszASCII;
#else
	WriteFile( hFile, (LPCSTR)strXML, strXML.GetLength(), &nWritten, NULL );
#endif
	
	CloseHandle( hFile );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithFile append intrinsic metadata

BOOL CDownloadWithFile::AppendMetadata()
{
	if ( ! Settings.Library.VirtualFiles ) return FALSE;
	
	if ( m_pXML == NULL ) return FALSE;
	CXMLElement* pXML = m_pXML->GetFirstElement();
	if ( pXML == NULL ) return FALSE;
	
	HANDLE hFile = CreateFile( m_sLocalName, GENERIC_READ|GENERIC_WRITE,
		FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
	if ( hFile == INVALID_HANDLE_VALUE ) return FALSE;
	
	CString strURI = m_pXML->GetAttributeValue( CXMLAttribute::schemaName );
	BOOL bSuccess = FALSE;
	
	if ( strURI == CSchema::uriAudio )
	{
		if ( _tcsistr( m_sLocalName, _T(".mp3") ) != NULL )
		{
			bSuccess |= AppendMetadataID3v1( hFile, pXML );
		}
	}
	
	CloseHandle( hFile );
	
	return bSuccess;
}

BOOL CDownloadWithFile::AppendMetadataID3v1(HANDLE hFile, CXMLElement* pXML)
{
	USES_CONVERSION;
	DWORD nBytes;
	CString str;
	ID3V1 pID3;
	
	ZeroMemory( &pID3, sizeof(pID3) );
	SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
	ReadFile( hFile, &pID3, 3, &nBytes, NULL );
	if ( memcmp( pID3.szTag, ID3V2_TAG, 3 ) == 0 ) return FALSE;
	
	ZeroMemory( &pID3, sizeof(pID3) );
	SetFilePointer( hFile, -(int)sizeof(pID3), NULL, FILE_END );
	ReadFile( hFile, &pID3, sizeof(pID3), &nBytes, NULL );
	if ( memcmp( pID3.szTag, ID3V1_TAG, 3 ) == 0 ) return FALSE;
	
	ZeroMemory( &pID3, sizeof(pID3) );
	memcpy( pID3.szTag, ID3V1_TAG, 3 );
	
	str = pXML->GetAttributeValue( _T("title") );
	if ( str.GetLength() > 0 ) strncpy( pID3.szSongname, T2CA( (LPCTSTR)str ), 30 );
	str = pXML->GetAttributeValue( _T("artist") );
	if ( str.GetLength() > 0 ) strncpy( pID3.szArtist, T2CA( (LPCTSTR)str ), 30 );
	str = pXML->GetAttributeValue( _T("album") );
	if ( str.GetLength() > 0 ) strncpy( pID3.szAlbum, T2CA( (LPCTSTR)str ), 30 );
	str = pXML->GetAttributeValue( _T("year") );
	if ( str.GetLength() > 0 ) strncpy( pID3.szYear, T2CA( (LPCTSTR)str ), 4 );
	
	str = pXML->GetAttributeValue( _T("genre") );
	
	for ( int nGenre = 0 ; nGenre < ID3_GENRES ; nGenre ++ )
	{
		if ( str.CompareNoCase( CLibraryBuilderInternals::pszID3Genre[ nGenre ] ) == 0 )
		{
			pID3.nGenre = nGenre;
			break;
		}
	}
	
	SetFilePointer( hFile, 0, NULL, FILE_END );
	WriteFile( hFile, &pID3, sizeof(pID3), &nBytes, NULL );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CDownloadWithFile serialize

void CDownloadWithFile::Serialize(CArchive& ar, int nVersion)
{
	CDownloadWithTransfers::Serialize( ar, nVersion );
	
	if ( ar.IsStoring() )
	{
		ar.WriteCount( m_pFile != NULL );
		if ( m_pFile != NULL ) m_pFile->Serialize( ar, nVersion );
	}
	else
	{
		if ( nVersion < 28 )
		{
			CString strLocalName;
			ar >> strLocalName;
			
			if ( strLocalName.GetLength() )
			{
				if ( m_sLocalName.GetLength() )
					MoveFile( m_sLocalName + _T(".sd"), strLocalName + _T(".sd") );
				m_sLocalName = strLocalName;
			}
			else
			{
				GenerateLocalName();
			}
		}
		
		if ( nVersion < 25 || ar.ReadCount() )
		{
			m_pFile->Serialize( ar, nVersion );
		}
		else
		{
			delete m_pFile;
			m_pFile = NULL;
		}
	}
}

⌨️ 快捷键说明

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