Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

CollectionFile.cpp

Go to the documentation of this file.
00001 //
00002 // ColletionFile.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "CollectionFile.h"
00025 
00026 #include "ZIPFile.h"
00027 #include "Buffer.h"
00028 #include "XML.h"
00029 #include "Schema.h"
00030 #include "SchemaCache.h"
00031 
00032 #include "Library.h"
00033 #include "Downloads.h"
00034 #include "ShareazaURL.h"
00035 #include "SharedFile.h"
00036 
00037 #include "SHA.h"
00038 #include "MD5.h"
00039 #include "ED2K.h"
00040 #include "TigerTree.h"
00041 
00042 #ifdef _DEBUG
00043 #undef THIS_FILE
00044 static char THIS_FILE[]=__FILE__;
00045 #define new DEBUG_NEW
00046 #endif
00047 
00048 IMPLEMENT_DYNAMIC(CCollectionFile, CComObject)
00049 
00050 
00051 
00052 // CCollectionFile construction
00053 
00054 CCollectionFile::CCollectionFile()
00055 {
00056         m_pMetadata = NULL;
00057 }
00058 
00059 CCollectionFile::~CCollectionFile()
00060 {
00061         Close();
00062 }
00063 
00065 // CCollectionFile open a collection file
00066 
00067 BOOL CCollectionFile::Open(LPCTSTR pszFile)
00068 {
00069         Close();
00070         CZIPFile pZIP;
00071         return pZIP.Open( pszFile ) && LoadManifest( pZIP );
00072 }
00073 
00074 BOOL CCollectionFile::Attach(HANDLE hFile)
00075 {
00076         Close();
00077         CZIPFile pZIP;
00078         return pZIP.Attach( hFile ) && LoadManifest( pZIP );
00079 }
00080 
00082 // CCollectionFile close a collection file
00083 
00084 void CCollectionFile::Close()
00085 {
00086         for ( POSITION pos = GetFileIterator() ; pos ; ) delete GetNextFile( pos );
00087         m_pFiles.RemoveAll();
00088 
00089         if ( m_pMetadata != NULL ) delete m_pMetadata;
00090         m_pMetadata = NULL;
00091 
00092         m_sTitle.Empty();
00093         m_sThisURI.Empty();
00094         m_sParentURI.Empty();
00095 }
00096 
00098 // CCollectionFile find a file by URN
00099 
00100 CCollectionFile::File* CCollectionFile::FindByURN(LPCTSTR pszURN)
00101 {
00102         SHA1 pSHA1; MD5 pMD5; TIGEROOT pTiger; MD4 pED2K;
00103 
00104         BOOL bSHA1      = CSHA::HashFromURN( pszURN, &pSHA1 );
00105         BOOL bMD5       = CMD5::HashFromURN( pszURN, &pMD5 );
00106         BOOL bTiger     = CTigerNode::HashFromURN( pszURN, &pTiger );
00107         BOOL bED2K      = CED2K::HashFromURN( pszURN, &pED2K );
00108 
00109         for ( POSITION pos = GetFileIterator() ; pos ; )
00110         {
00111                 File* pFile = GetNextFile( pos );
00112 
00113                 if ( bSHA1 && pFile->m_bSHA1 && pSHA1 == pFile->m_pSHA1 ) return pFile;
00114                 if ( bMD5 && pFile->m_bMD5 && pMD5 == pFile->m_pMD5 ) return pFile;
00115                 if ( bTiger && pFile->m_bTiger && pTiger == pFile->m_pTiger ) return pFile;
00116                 if ( bED2K && pFile->m_bED2K && pED2K == pFile->m_pED2K ) return pFile;
00117         }
00118 
00119         return NULL;
00120 }
00121 
00123 // CCollectionFile find a shared file
00124 
00125 CCollectionFile::File* CCollectionFile::FindFile(CLibraryFile* pShared, BOOL bApply)
00126 {
00127         File* pFile = NULL;
00128 
00129         for ( POSITION pos = GetFileIterator() ; pos ; )
00130         {
00131                 pFile = GetNextFile( pos );
00132                 if ( pShared->m_bSHA1 && pFile->m_bSHA1 && pShared->m_pSHA1 == pFile->m_pSHA1 ) break;
00133                 if ( pShared->m_bMD5 && pFile->m_bMD5 && pShared->m_pMD5 == pFile->m_pMD5 ) break;
00134                 if ( pShared->m_bTiger && pFile->m_bTiger && pShared->m_pTiger == pFile->m_pTiger ) break;
00135                 if ( pShared->m_bED2K && pFile->m_bED2K && pShared->m_pED2K == pFile->m_pED2K ) break;
00136                 pFile = NULL;
00137         }
00138 
00139         if ( bApply && pFile != NULL ) pFile->ApplyMetadata( pShared );
00140 
00141         return pFile;
00142 }
00143 
00145 // CCollectionFile get count
00146 
00147 int CCollectionFile::GetMissingCount()
00148 {
00149         int nCount =0;
00150 
00151         for ( POSITION pos = GetFileIterator() ; pos ; )
00152         {
00153                 File* pFile = GetNextFile( pos );
00154                 if ( ! pFile->IsComplete() && ! pFile->IsDownloading() ) nCount++;
00155         }
00156 
00157         return nCount;
00158 }
00159 
00161 // CCollectionFile load the manifest
00162 
00163 BOOL CCollectionFile::LoadManifest(CZIPFile& pZIP)
00164 {
00165         CZIPFile::File* pFile = pZIP.GetFile( _T("Collection.xml"), TRUE );
00166         if ( pFile == NULL ) return FALSE;
00167 
00168         CBuffer* pBuffer = pFile->Decompress();
00169         if ( pBuffer == NULL ) return FALSE;
00170 
00171         CXMLElement* pXML = CXMLElement::FromString( pBuffer->ReadString( pBuffer->m_nLength, CP_UTF8 ), TRUE );
00172         delete pBuffer;
00173 
00174         if ( pXML == NULL ) return FALSE;
00175         if ( ! pXML->IsNamed( _T("collection") ) ) return FALSE;
00176 
00177         CXMLElement* pProperties = pXML->GetElementByName( _T("properties") );
00178         if ( pProperties == NULL ) return FALSE;
00179         CXMLElement* pContents = pXML->GetElementByName( _T("contents") );
00180         if ( pContents == NULL ) return FALSE;
00181 
00182         for ( POSITION pos = pContents->GetElementIterator() ; pos ; )
00183         {
00184                 File* pFile = new File( this );
00185 
00186                 if ( pFile->Parse( pContents->GetNextElement( pos ) ) )
00187                 {
00188                         m_pFiles.AddTail( pFile );
00189                 }
00190                 else
00191                 {
00192                         delete pFile;
00193                         Close();
00194                         return FALSE;
00195                 }
00196         }
00197 
00198         if ( CXMLElement* pMetadata = pProperties->GetElementByName( _T("metadata") ) )
00199         {
00200                 m_pMetadata = CloneMetadata( pMetadata );
00201                 if ( m_pMetadata != NULL ) m_sThisURI = m_pMetadata->GetAttributeValue( CXMLAttribute::schemaName );
00202         }
00203 
00204         if ( CXMLElement* pTitle = pProperties->GetElementByName( _T("title") ) )
00205         {
00206                 m_sTitle = pTitle->GetValue();
00207         }
00208 
00209         if ( CXMLElement* pMounting = pProperties->GetElementByName( _T("mounting") ) )
00210         {
00211                 if ( CXMLElement* pParent = pMounting->GetElementByName( _T("parent") ) )
00212                 {
00213                         m_sParentURI = pParent->GetAttributeValue( _T("uri") );
00214                 }
00215                 if ( CXMLElement* pThis = pMounting->GetElementByName( _T("this") ) )
00216                 {
00217                         m_sThisURI = pThis->GetAttributeValue( _T("uri") );
00218                 }
00219         }
00220 
00221         delete pXML;
00222         return TRUE;
00223 }
00224 
00226 // CCollectionFile clone metadata
00227 
00228 CXMLElement* CCollectionFile::CloneMetadata(CXMLElement* pMetadata)
00229 {
00230         CString strURI = pMetadata->GetAttributeValue( _T("xmlns:s") );
00231         if ( strURI.IsEmpty() ) return NULL;
00232 
00233         CXMLElement* pCore = pMetadata->GetFirstElement();
00234         if ( pCore == NULL ) return NULL;
00235 
00236         if ( CSchema* pSchema = SchemaCache.Get( strURI ) )
00237         {
00238                 pMetadata = pSchema->Instantiate();
00239         }
00240         else
00241         {
00242                 pMetadata = new CXMLElement( NULL, pCore->GetName() + 's' );
00243                 pMetadata->AddAttribute( CXMLAttribute::schemaName, strURI );
00244         }
00245 
00246         pCore = pCore->Clone();
00247         pMetadata->AddElement( pCore );
00248 
00249         CString strName = pMetadata->GetName();
00250         if ( _tcsnicmp( strName, _T("s:"), 2 ) == 0 ) pMetadata->SetName( strName.Mid( 2 ) );
00251 
00252         strName = pCore->GetName();
00253         if ( _tcsnicmp( strName, _T("s:"), 2 ) == 0 ) pCore->SetName( strName.Mid( 2 ) );
00254 
00255         for ( POSITION pos = pCore->GetElementIterator() ; pos ; )
00256         {
00257                 CXMLNode* pNode = pCore->GetNextElement( pos );
00258                 CString strName = pNode->GetName();
00259                 if ( _tcsnicmp( strName, _T("s:"), 2 ) == 0 ) pNode->SetName( strName.Mid( 2 ) );
00260         }
00261 
00262         for ( POSITION pos = pCore->GetAttributeIterator() ; pos ; )
00263         {
00264                 CXMLNode* pNode = pCore->GetNextAttribute( pos );
00265                 CString strName = pNode->GetName();
00266                 if ( _tcsnicmp( strName, _T("s:"), 2 ) == 0 ) pNode->SetName( strName.Mid( 2 ) );
00267         }
00268 
00269         return pMetadata;
00270 }
00271 
00272 
00274 // CCollectionFile::File construction
00275 
00276 CCollectionFile::File::File(CCollectionFile* pParent)
00277 {
00278         m_pParent       = pParent;
00279         m_bSHA1         = FALSE;
00280         m_bMD5          = FALSE;
00281         m_bTiger        = FALSE;
00282         m_bED2K         = FALSE;
00283         m_nSize         = SIZE_UNKNOWN;
00284         m_pMetadata     = NULL;
00285 }
00286 
00287 CCollectionFile::File::~File()
00288 {
00289         if ( m_pMetadata != NULL ) delete m_pMetadata;
00290 }
00291 
00293 // CCollectionFile::File parse
00294 
00295 BOOL CCollectionFile::File::Parse(CXMLElement* pRoot)
00296 {
00297         if ( ! pRoot->IsNamed( _T("file") ) ) return FALSE;
00298 
00299         for ( POSITION pos = pRoot->GetElementIterator() ; pos ; )
00300         {
00301                 CXMLElement* pXML = pRoot->GetNextElement( pos );
00302 
00303                 if ( pXML->IsNamed( _T("id") ) )
00304                 {
00305                         m_bSHA1         |= CSHA::HashFromURN( pXML->GetValue(), &m_pSHA1 );
00306                         m_bMD5          |= CMD5::HashFromURN( pXML->GetValue(), &m_pMD5 );
00307                         m_bTiger        |= CTigerNode::HashFromURN( pXML->GetValue(), &m_pTiger );
00308                         m_bED2K         |= CED2K::HashFromURN( pXML->GetValue(), &m_pED2K );
00309                 }
00310                 else if ( pXML->IsNamed( _T("description") ) )
00311                 {
00312                         if ( CXMLElement* pName = pXML->GetElementByName( _T("name") ) )
00313                         {
00314                                 m_sName = pName->GetValue();
00315                         }
00316                         if ( CXMLElement* pSize = pXML->GetElementByName( _T("size") ) )
00317                         {
00318                                 _stscanf( pSize->GetValue(), _T("%I64i"), &m_nSize );
00319                         }
00320                 }
00321                 else if ( pXML->IsNamed( _T("metadata") ) )
00322                 {
00323                         if ( m_pMetadata != NULL ) delete m_pMetadata;
00324                         m_pMetadata = CCollectionFile::CloneMetadata( pXML );
00325                 }
00326                 else if ( pXML->IsNamed( _T("packaged") ) )
00327                 {
00328                         if ( CXMLElement* pSource = pXML->GetElementByName( _T("source") ) )
00329                         {
00330                                 m_sSource = pSource->GetValue();
00331                         }
00332                 }
00333         }
00334 
00335         return m_bSHA1 || m_bMD5 || m_bTiger || m_bED2K;
00336 }
00337 
00339 // CCollectionFile::File state
00340 
00341 BOOL CCollectionFile::File::IsComplete() const
00342 {
00343         if ( m_bSHA1 && LibraryMaps.LookupFileBySHA1( &m_pSHA1, FALSE, TRUE ) )
00344                 return TRUE;
00345         if ( m_bTiger && LibraryMaps.LookupFileByTiger( &m_pTiger, FALSE, TRUE ) )
00346                 return TRUE;
00347         if ( m_bED2K && LibraryMaps.LookupFileByED2K( &m_pED2K, FALSE, TRUE ) )
00348                 return TRUE;
00349         return FALSE;
00350 }
00351 
00352 BOOL CCollectionFile::File::IsDownloading() const
00353 {
00354         if ( m_bSHA1 && Downloads.FindBySHA1( &m_pSHA1 ) )
00355                 return TRUE;
00356         if ( m_bTiger && Downloads.FindByTiger( &m_pTiger ) )
00357                 return TRUE;
00358         if ( m_bED2K && Downloads.FindByED2K( &m_pED2K ) )
00359                 return TRUE;
00360         return FALSE;
00361 }
00362 
00364 // CCollectionFile::File download
00365 
00366 BOOL CCollectionFile::File::Download()
00367 {
00368         CShareazaURL pURL;
00369 
00370         if ( IsComplete() || IsDownloading() ) return FALSE;
00371 
00372         pURL.m_nAction  = CShareazaURL::uriDownload;
00373         pURL.m_bSHA1    = m_bSHA1;
00374         pURL.m_pSHA1    = m_pSHA1;
00375         pURL.m_bMD5             = m_bMD5;
00376         pURL.m_pMD5             = m_pMD5;
00377         pURL.m_bTiger   = m_bTiger;
00378         pURL.m_pTiger   = m_pTiger;
00379         pURL.m_bED2K    = m_bED2K;
00380         pURL.m_pED2K    = m_pED2K;
00381         pURL.m_sName    = m_sName;
00382         pURL.m_bSize    = ( m_nSize != SIZE_UNKNOWN );
00383         pURL.m_nSize    = m_nSize;
00384 
00385         return Downloads.Add( &pURL ) != NULL;
00386 }
00387 
00389 // CCollectionFile::File apply metadata to a shared file
00390 
00391 BOOL CCollectionFile::File::ApplyMetadata(CLibraryFile* pShared)
00392 {
00393         ASSERT( pShared != NULL );
00394         if ( m_pMetadata == NULL ) return FALSE;
00395 
00396         CXMLElement* pXML = m_pMetadata->Clone();
00397         BOOL bResult = pShared->SetMetadata( pXML );
00398         delete pXML;
00399 
00400         return bResult;
00401 }

Generated on Thu Dec 15 10:39:34 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2