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

📄 librarybuilderinternals.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	{
		if ( nBuffer < nMinSize ) return NULL;
		
		BYTE* pBuffer = new BYTE[ nBuffer ];
		
		ReadFile( hFile, pBuffer, nBuffer, &nRead, NULL );
		
		if ( nRead == nBuffer ) return pBuffer;
		
		delete [] pBuffer;
	}
	else
	{
		SetFilePointer( hFile, nBuffer, NULL, FILE_CURRENT );
		nBuffer = nSample;
		return (BYTE*)TRUE;
	}
	
	return NULL;
}

BOOL CLibraryBuilderInternals::ReadOGGString(BYTE*& pOGG, DWORD& nOGG, CString& str)
{
	if ( nOGG < 4 ) return FALSE;
	
	DWORD nLen = *(DWORD*)pOGG;
	pOGG += 4; nOGG -= 4;
	
	if ( nOGG < nLen ) return FALSE;
	
	LPTSTR pszOut = str.GetBuffer( nLen + 1 );
	for ( ; nLen ; nLen--, nOGG-- ) *pszOut++ = (TCHAR)*pOGG++;
	*pszOut++ = 0;
	str.ReleaseBuffer();
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CLibraryBuilderInternals APE Monkey's Audio (threaded)

BOOL CLibraryBuilderInternals::ReadAPE( HANDLE hFile)
{
	if ( GetFileSize( hFile, NULL ) < sizeof(APE_HEADER) ) return SubmitCorrupted();
	SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
	
	APE_HEADER pAPE;
	DWORD nRead;
	
	ReadFile( hFile, &pAPE, sizeof(pAPE), &nRead, NULL );
	if ( nRead != sizeof(pAPE) ) return SubmitCorrupted();
	if ( pAPE.cID[0] != 'M' || pAPE.cID[1] != 'A' || pAPE.cID[2] != 'C' ) return SubmitCorrupted();
	if ( pAPE.nSampleRate == 0 ) return SubmitCorrupted();
	
	DWORD nBlocksPerFrame = ( pAPE.nVersion >= 3900 || ( pAPE.nVersion >= 3800 &&
		pAPE.nCompressionLevel == 4000 ) ) ? 73728 : 9216;
	
	DWORD nBlocks	= ( pAPE.nTotalFrames - 1 ) * nBlocksPerFrame + pAPE.nFinalFrameBlocks;
	DWORD nSamples	= nBlocks * pAPE.nChannels;
	
	if ( pAPE.nFormatFlags & 8 )
		nSamples *= 3;
	else if ( ( pAPE.nFormatFlags & 1 ) == 0 )
		nSamples *= 2;
	
	DWORD nDuration	= nSamples / pAPE.nSampleRate;
	
	CXMLElement* pXML = new CXMLElement( NULL, _T("audio") );
	CString strItem;
	
	strItem.Format( _T("%lu"), nDuration );
	pXML->AddAttribute( _T("seconds"), strItem );
	
	strItem.Format( _T("%lu"), pAPE.nSampleRate );
	pXML->AddAttribute( _T("sampleRate"), strItem );
	
	if ( ReadID3v1( hFile, pXML ) )
	{
		return SubmitMetadata( CSchema::uriAudio, pXML );
	}
	
	if ( GetFileSize( hFile, NULL ) < sizeof(APE_HEADER) + sizeof(APE_TAG_FOOTER) )
	{
		return SubmitMetadata( CSchema::uriAudio, pXML );
	}
	
	APE_TAG_FOOTER pFooter;
	
	SetFilePointer( hFile, -(LONG)sizeof(pFooter), NULL, FILE_END );
	ReadFile( hFile, &pFooter, sizeof(pFooter), &nRead, NULL );
	
	if ( nRead != sizeof(pFooter) || strncmp( pFooter.cID, "APETAGEX", 8 ) ||
		 (DWORD)pFooter.nFields > 16 ||
		 ( pFooter.nVersion != 1000 && pFooter.nVersion != 2000 ) )
	{
		return SubmitMetadata( CSchema::uriAudio, pXML );
	}
	
	SetFilePointer( hFile, -(LONG)pFooter.nSize, NULL, FILE_END );
	
	for ( int nTag = 0 ; nTag < pFooter.nFields ; nTag++ )
	{
		DWORD nLength, nFlags;
		
		ReadFile( hFile, &nLength, 4, &nRead, NULL );
		if ( nRead != 4 || nLength > 1024 ) break;
		ReadFile( hFile, &nFlags, 4, &nRead, NULL );
		if ( nRead != 4 ) break;
		
		CString strKey, strValue;
		
		while ( strKey.GetLength() < 64 )
		{
			BYTE nChar;
			ReadFile( hFile, &nChar, 1, &nRead, NULL );
			if ( nRead != 1 || nChar == 0 ) break;
			strKey += (TCHAR)nChar;
		}
		
		if ( nRead != 1 || strKey.GetLength() >= 64 ) break;
		
		LPSTR pszInput = new CHAR[ nLength ];
		ReadFile( hFile, pszInput, nLength, &nRead, NULL );
		if ( nLength != nRead ) break;
		
		int nWide = MultiByteToWideChar( CP_UTF8, 0, pszInput, nLength, NULL, 0 );
		LPWSTR pszWide = new WCHAR[ nWide + 1 ];
		MultiByteToWideChar( CP_UTF8, 0, pszInput, nLength, pszWide, nWide );
		pszWide[ nWide ] = 0;
		strValue = pszWide;
		
		delete [] pszWide;
		delete [] pszInput;
		
		strKey.TrimLeft(); strKey.TrimRight();
		strValue.TrimLeft(); strValue.TrimRight();
		
		if ( strKey.GetLength() && strValue.GetLength() )
		{
			strKey.MakeLower();
			
			if ( strKey == _T("title") )
			{
				pXML->AddAttribute( _T("title"), strValue );
			}
			else if ( strKey == _T("artist") )
			{
				pXML->AddAttribute( _T("artist"), strValue );
			}
			else if ( strKey == _T("album") )
			{
				pXML->AddAttribute( _T("album"), strValue );
			}
			else if ( strKey == _T("comment") )
			{
				pXML->AddAttribute( _T("description"), strValue );
			}
			else if ( strKey == _T("year") )
			{
				pXML->AddAttribute( _T("year"), strValue );
			}
			else if ( strKey == _T("track") )
			{
				pXML->AddAttribute( _T("track"), strValue );
			}
			else if ( strKey == _T("genre") )
			{
				pXML->AddAttribute( _T("genre"), strValue );
			}
			else if ( strKey.Find( _T(" url") ) > 0 )
			{
				pXML->AddAttribute( _T("link"), strValue );
			}
		}
	}
	
	return SubmitMetadata( CSchema::uriAudio, pXML );
}

//////////////////////////////////////////////////////////////////////
// CLibraryBuilderInternals AVI (threaded)

BOOL CLibraryBuilderInternals::ReadAVI( HANDLE hFile)
{
	if ( GetFileSize( hFile, NULL ) < sizeof(AVI_HEADER) + 16 ) return SubmitCorrupted();
	SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
	
	CHAR szID[5] = { 0, 0, 0, 0, 0 };
	DWORD nRead;
	
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 || strncmp( szID, "RIFF", 4 ) ) return SubmitCorrupted();
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 ) return FALSE;
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 || strncmp( szID, "AVI ", 4 ) ) return SubmitCorrupted();
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 || strncmp( szID, "LIST", 4 ) ) return FALSE;
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 ) return FALSE;
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 || strncmp( szID, "hdrl", 4 ) ) return FALSE;
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 || strncmp( szID, "avih", 4 ) ) return FALSE;
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 ) return FALSE;
	
	AVI_HEADER pHeader;
	ReadFile( hFile, &pHeader, sizeof(pHeader), &nRead, NULL );
	if ( nRead != sizeof(pHeader) ) return FALSE;
	
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 || strncmp( szID, "LIST", 4 ) ) return FALSE;
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 ) return FALSE;
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 || strncmp( szID, "strl", 4 ) ) return FALSE;
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 || strncmp( szID, "strh", 4 ) ) return FALSE;
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 ) return FALSE;
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 || strncmp( szID, "vids", 4 ) ) return FALSE;
	ReadFile( hFile, szID, 4, &nRead, NULL );
	if ( nRead != 4 ) return FALSE;
	
	CXMLElement* pXML = new CXMLElement( NULL, _T("video") );
	CString strItem;
	
	double nTime = (double)pHeader.dwMicroSecPerFrame / 1000000.0f;
	nTime *= (double)pHeader.dwTotalFrames;
	nTime /= 60.0f;
	
	double nRate = 1000000.0f / (double)pHeader.dwMicroSecPerFrame;
	
	strItem.Format( _T("%lu"), pHeader.dwWidth );
	pXML->AddAttribute( _T("width"), strItem );
	strItem.Format( _T("%lu"), pHeader.dwHeight );
	pXML->AddAttribute( _T("height"), strItem );
	strItem.Format( _T("%.3f"), nTime );
	pXML->AddAttribute( _T("minutes"), strItem );
	strItem.Format( _T("%.2f"), nRate );
	pXML->AddAttribute( _T("frameRate"), strItem );
	pXML->AddAttribute( _T("codec"), CString( szID ) );
	
	return SubmitMetadata( CSchema::uriVideo, pXML );
}

//////////////////////////////////////////////////////////////////////
// CLibraryBuilderInternals PDF (threaded)

BOOL CLibraryBuilderInternals::ReadPDF( HANDLE hFile, LPCTSTR pszPath)
{
	DWORD nOffset, nCount, nPages, nInfo;
	CString strLine, strSeek;
	
	SetFilePointer( hFile, 0, NULL, FILE_BEGIN );
	if ( ReadLine( hFile ).Find( _T("%PDF") ) != 0 ) return FALSE;
	
	SetFilePointer( hFile, -1, NULL, FILE_END );
	strLine = ReadLineReverse( hFile );
	if ( strLine.IsEmpty() ) strLine = ReadLineReverse( hFile );
	if ( strLine != _T("%%EOF") ) return FALSE;

	strLine = ReadLineReverse( hFile );
	if ( ReadLineReverse( hFile ) != _T("startxref") ) return FALSE;
	
	if ( _stscanf( strLine, _T("%lu"), &nOffset ) != 1 ) return FALSE;
	if ( SetFilePointer( hFile, nOffset, NULL, FILE_BEGIN ) != nOffset ) return FALSE;
	
	if ( ReadLine( hFile ) != _T("xref") ) return FALSE;
	strLine = ReadLine( hFile );
	if ( _stscanf( strLine, _T("%lu %lu"), &nOffset, &nCount ) != 2 ) return FALSE;
	if ( nCount > 4096 ) return FALSE;
	
	DWORD* pOffset = new DWORD[ nCount ];
	ZeroMemory( pOffset, sizeof(DWORD) * nCount );
	
	for ( nOffset = 0 ; nOffset < nCount ; nOffset++ )
	{
		strLine = ReadLine( hFile );
		strLine.TrimLeft();
		strLine.TrimRight();
		
		if ( strLine.GetLength() != 18 || strLine.GetAt( 10 ) != ' ' )
		{
			delete [] pOffset;
			return FALSE;
		}
		
		if ( strLine.GetAt( 17 ) == 'n' )
		{
			for ( LPCTSTR pszInt = strLine ; *pszInt == '0' ; pszInt++ );
			
			if ( *pszInt != 0 )
			{
				_stscanf( pszInt, _T("%lu"), &pOffset[ nOffset ] );
			}
		}
	}
	
	if ( ReadLine( hFile ) != _T("trailer") ) return FALSE;
	if ( ReadLine( hFile ) != _T("<<") ) return FALSE;
	
	for ( nOffset = 0 ; ; )
	{
		strLine = ReadLine( hFile );
		if ( strLine.IsEmpty() || strLine == _T(">>") ) break;
		
		if ( _tcsnicmp( strLine, _T("/Info "), 6 ) == 0 )
		{
			_stscanf( strLine.Mid( 6 ), _T("%lu"), &nOffset );
			break;
		}
	}
	
	if ( nOffset == 0 )
	{
		delete [] pOffset;
		return FALSE;
	}
	
	strSeek.Format( _T("%lu 0 obj"), nOffset );
	nPages = nInfo = 0;
	
	for ( nOffset = 0 ; nOffset < nCount ; nOffset++ )
	{
		if ( pOffset[ nOffset ] == 0 ) continue;
		SetFilePointer( hFile, pOffset[ nOffset ], NULL, FILE_BEGIN );
		
		strLine = ReadLine( hFile );
		if ( strLine.Find( _T("obj") ) < 0 ) break;
		
		if ( strLine == strSeek )
		{
			nInfo = SetFilePointer( hFile, 0, NULL, FILE_CURRENT );
		}
		else if ( ReadLine( hFile ) == _T("<<") )
		{
			if ( ReadLine( hFile ) == _T("/Type /Page") ) nPages++;
		}
	}
	
	delete [] pOffset;
	
	if ( nInfo == 0 ) return FALSE;
	SetFilePointer( hFile, nInfo, NULL, FILE_BEGIN );
	
	if ( ReadLine( hFile ) != _T("<<") ) return FALSE;
	
	BOOL bBook = ( _tcsistr( pszPath, _T("book") ) != NULL );
	if ( ! bBook ) return FALSE;
	
	CXMLElement* pXML = new CXMLElement( NULL, bBook ? _T("book") : _T("document") );
	
	if ( LPCTSTR pszName = _tcsrchr( pszPath, '\\' ) )
	{
		pszName++;
		
		if ( _tcsnicmp( pszName, _T("ebook - "), 8 ) == 0 )
		{
			strLine = pszName + 8;
			strLine = strLine.SpanExcluding( _T(".") );
			strLine.TrimLeft();
			strLine.TrimRight();
			pXML->AddAttribute( _T("title"), strLine );
		}
		else if ( _tcsnicmp( pszName, _T("(ebook"), 6 ) == 0 )
		{
			if ( pszName = _tcschr( pszName, ')' ) )
			{
				if ( _tcsncmp( pszName, _T(") - "), 4 ) == 0 )
					strLine = pszName + 4;
				else
					strLine = pszName + 1;
				strLine = strLine.SpanExcluding( _T(".") );
				strLine.TrimLeft();
				strLine.TrimRight();
				pXML->AddAttribute( _T("title"), strLine );
			}
		}
	}
	
	if ( nPages > 0 )
	{
		strLine.Format( _T("%lu"), nPages );
		pXML->AddAttribute( _T("pages"), strLine );
	}
	
	while ( TRUE )
	{
		strLine = ReadLine( hFile );
		if ( strLine.IsEmpty() || strLine.GetAt( 0 ) != '/' ) break;
		
		CString strKey = strLine.SpanExcluding( _T(" \t") );
		strLine = strLine.Mid( strKey.GetLength() );
		strLine.TrimLeft();
		strKey.MakeLower();
		
		if ( strLine.GetLength() >= 2 &&
			 strLine.GetAt( 0 ) == '(' &&
			 strLine.GetAt( strLine.GetLength() - 1 ) == ')' )
		{
			strLine = strLine.Mid( 1, strLine.GetLength() - 2 );
		}
		
		if ( strLine.IsEmpty() ) continue;
		
		if ( ( strLine.GetLength() & 1 ) == 0 && strLine.GetAt( 0 ) == '<' )
		{
			CString strTemp;
			
			for ( int nHex = 0 ; nHex < strLine.GetLength() / 2 - 1 ; nHex++ )
			{
				int nChar;
				if ( _stscanf( strLine.Mid( nHex + 1, 2 ), _T("%x"), &nChar ) == 1 )
				{
					strTemp += (TCHAR)nChar;
				}
			}
			
			strLine = strTemp;
			if ( strLine.IsEmpty() ) continue;
		}
		
		if ( strKey == _T("/title") )
		{
			pXML->AddAttribute( _T("title"), strLine );
		}
		else if ( strKey == _T("/author") )
		{
			pXML->AddAttribute( _T("author"), strLine );
		}
		else if ( strKey == _T("/subject") )
		{
			pXML->AddAttribute( _T("subject"), strLine );
		}
		else if ( strKey == _T("/keywords") )
		{
			pXML->AddAttribute( _T("keywords"), strLine );
		}
	}
	
	if ( bBook )
	{
		pXML->AddAttribute( _T("format"), _T("PDF") );
		pXML->AddAttribute( _T("back"), _T("Digital") );
	}
	
	// TODO: Check bBook, and do uriDocument
	return SubmitMetadata( CSchema::uriBook, pXML );
}

CString CLibraryBuilderInternals::ReadLine(HANDLE hFile)
{
	DWORD nRead, nLength;
	TCHAR cChar;
	CString str;
	
	for ( nLength = 0 ; ReadFile( hFile, &cChar, 1, &nRead, NULL ) && nRead == 1 && nLength++ < 4096 ; )
	{
		if ( cChar == '\r' ) break;
		if ( cChar != '\n' ) str += cChar;
	}
	
	str.TrimLeft();
	str.TrimRight();
	
	return str;
}

CString CLibraryBuilderInternals::ReadLineReverse(HANDLE hFile)
{
	DWORD nRead, nLength;
	TCHAR cChar;
	CString str;
	
	for ( nLength = 0 ; ReadFile( hFile, &cChar, 1, &nRead, NULL ) && nRead == 1 && nLength++ < 4096 ; )
	{
		if ( SetFilePointer( hFile, -2, NULL, FILE_CURRENT ) == 0 ) break;
		if ( cChar == '\r' ) break;
		if ( cChar != '\n' ) str = cChar + str;
	}
	
	str.TrimLeft();
	str.TrimRight();
	
	return str;
}

//////////////////////////////////////////////////////////////////////
// CLibraryBuilderInternals Collection (threaded)

BOOL CLibraryBuilderInternals::ReadCollection( HANDLE hFile, SHA1* pSHA1)
{
	CCollectionFile pCollection;
	if ( ! pCollection.Attach( hFile ) ) return FALSE;
	
	LibraryFolders.MountCollection( pSHA1, &pCollection );
	
	if ( CXMLElement* pMetadata = pCollection.GetMetadata() )
	{
		pMetadata = pMetadata->GetFirstElement()->Clone();
		return SubmitMetadata( pCollection.GetThisURI(), pMetadata );
	}
	
	return TRUE;
}

⌨️ 快捷键说明

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