mmappcomponents/harvester/filehandler/src/mpxfolderscanner.cpp
changeset 58 c76ea6caa649
parent 27 cbb1bfb7ebfb
equal deleted inserted replaced
54:fa0adf088850 58:c76ea6caa649
    22 #include "mpxfilescanstateobserver.h"
    22 #include "mpxfilescanstateobserver.h"
    23 #include "mpxfhcommon.h"
    23 #include "mpxfhcommon.h"
    24 
    24 
    25 // CONSTANTS
    25 // CONSTANTS
    26 const TInt KFileNumBreakCount = 5;
    26 const TInt KFileNumBreakCount = 5;
       
    27 _LIT( KTxtBackSlash, "\\" );
    27 
    28 
    28 // ======== LOCAL FUNCTIONS ========
    29 // ======== LOCAL FUNCTIONS ========
    29 
    30 
    30 // ---------------------------------------------------------------------------
    31 // ---------------------------------------------------------------------------
    31 // RArray compare function to compare strings
    32 // RArray compare function to compare strings
    58 // 2nd Phase Constructor
    59 // 2nd Phase Constructor
    59 // ---------------------------------------------------------------------------
    60 // ---------------------------------------------------------------------------
    60 //
    61 //
    61 void CMPXFolderScanner::ConstructL()
    62 void CMPXFolderScanner::ConstructL()
    62     {
    63     {
    63     iDirScan = CDirScan::NewL(iFs);
    64 
    64     }
    65     }
    65 
    66 
    66 // ---------------------------------------------------------------------------
    67 // ---------------------------------------------------------------------------
    67 // Two Phased Constructor
    68 // Two Phased Constructor
    68 // ---------------------------------------------------------------------------
    69 // ---------------------------------------------------------------------------
    86 // ---------------------------------------------------------------------------
    87 // ---------------------------------------------------------------------------
    87 //
    88 //
    88 CMPXFolderScanner::~CMPXFolderScanner()
    89 CMPXFolderScanner::~CMPXFolderScanner()
    89     {
    90     {
    90     Cancel();
    91     Cancel();
    91     
    92     iDirQueue.ResetAndDestroy();
    92     delete iDirScan;
       
    93     delete iDir;
       
    94     
       
    95     iDrivesToScan.Close();
    93     iDrivesToScan.Close();
    96     }
    94     }
    97     
    95     
    98 // ---------------------------------------------------------------------------
    96 // ---------------------------------------------------------------------------
    99 // Scans a list of drives for files
    97 // Scans a list of drives for files
   104     MPX_DEBUG1("CMPXFolderScanner::ScanL <---");
   102     MPX_DEBUG1("CMPXFolderScanner::ScanL <---");
   105     
   103     
   106     // Copy all the other drives we want to scan
   104     // Copy all the other drives we want to scan
   107     //
   105     //
   108     TInt count( aDrives.Count() );
   106     TInt count( aDrives.Count() );
       
   107     MPX_DEBUG2("CMPXFolderScanner::ScanL aDrives %d",count);
   109     for( TInt i=0; i<count; ++i )
   108     for( TInt i=0; i<count; ++i )
   110         {
   109         {
   111         // Check if we are already scanning this drive
   110         // Check if we are already scanning this drive
   112         TInt found( iDrivesToScan.FindInOrder( aDrives[i], CompareString ) ); 
   111         TInt found( iDrivesToScan.FindInOrder( aDrives[i], CompareString ) ); 
   113         if( found == KErrNotFound )
   112         if( found == KErrNotFound )
   123         // Setup the next drive to scan
   122         // Setup the next drive to scan
   124         //
   123         //
   125         if( !SetupNextDriveToScanL() )
   124         if( !SetupNextDriveToScanL() )
   126             {
   125             {
   127             // Kick off the scanning
   126             // Kick off the scanning
   128             iStatus = KRequestPending;
   127             iCurDirQueueEntry = iDirQueue[ 0 ];
   129             SetActive();
   128             iCurFullPath = iCurDirQueueEntry->iFullPath;
   130             TRequestStatus* status = &iStatus;
   129             ReadDirEntry();
   131             User::RequestComplete( status, KErrNone );
   130 
   132             
       
   133             // We've started scanning
   131             // We've started scanning
   134             iScanning = ETrue;
   132             iScanning = ETrue;
   135             }
   133             }
   136         else
   134         else
   137             {
   135             {
   141         }
   139         }
   142     MPX_DEBUG1("CMPXFolderScanner::ScanL --->");
   140     MPX_DEBUG1("CMPXFolderScanner::ScanL --->");
   143     }
   141     }
   144 
   142 
   145 // ---------------------------------------------------------------------------
   143 // ---------------------------------------------------------------------------
       
   144 // Reads dir entries asynchronously
       
   145 // ---------------------------------------------------------------------------
       
   146 //
       
   147 void CMPXFolderScanner::ReadDirEntry()
       
   148     {
       
   149     ASSERT( !IsActive() );
       
   150     iCurDirQueueEntry->iDir.Read( iCurDirQueueEntry->iEntryArray, iStatus );
       
   151     SetActive();
       
   152     }
       
   153 
       
   154 // ---------------------------------------------------------------------------
   146 // Continue Scanning for more files
   155 // Continue Scanning for more files
   147 // ---------------------------------------------------------------------------
   156 // ---------------------------------------------------------------------------
   148 //
   157 //
   149 TBool CMPXFolderScanner::DoScanL()
   158 TBool CMPXFolderScanner::DoScanL()
   150     {
   159     {
   151     MPX_DEBUG1("CMPXFolderScanner::DoScanL <---");
   160     MPX_DEBUG1("CMPXFolderScanner::DoScanL <---");
   152     TBool done (EFalse);
   161     TBool done (EFalse);
   153     
   162     TBool blocked ( EFalse );
   154     // Check each file in each directory
   163 
   155     TInt numFiles( iDir->Count() );
   164     // read successfully
   156     while( iCount < numFiles )
   165     if ( iStatus == KErrNone || iStatus == KErrEof )
   157         {
   166         {
   158         TEntry entry = (*iDir)[iCount];
   167         TBuf<KMaxFileName> buffer;
   159 
   168         const TEntry* entry = NULL;
   160         // Construct the full path and file name
   169         TInt numEntries( iCurDirQueueEntry->iEntryArray.Count() );
   161         TParse fullEntry;
   170 
   162         TPtrC dirPath(iDirScan->FullPath());
   171         // process the entry one by one
   163         fullEntry.Set(entry.iName, &dirPath, NULL);
   172         while ( iCurDirQueueEntry->iPos < numEntries )
   164         
   173             {
   165         TPtrC fullname = fullEntry.FullName();
   174             entry = iCurDirQueueEntry->NextEntry();
   166         TInt index = iObserver.IsMediaFileL( fullname );
   175             buffer.Zero();
   167         if( KErrNotFound != index )
   176 
   168             {
   177             // Generates the full name of the entry
   169             iObserver.HandleFileAdditionL( fullname, index );
   178             buffer.Append( *iCurFullPath );
   170             }
   179             buffer.Append( entry->iName );
   171         
   180 
   172         // Break if we have scanned enough files
   181             if ( entry->IsDir() ) // entry is a directory
   173         //
       
   174         ++iCount;
       
   175         if( iCount%KFileNumBreakCount == 0 )
       
   176             {
       
   177             return EFalse;
       
   178             }
       
   179         }
       
   180     
       
   181     // All files from this directory scanned, so move onto next
       
   182     //
       
   183     TInt err( KErrNone );
       
   184     TBool blocked (EFalse);
       
   185     if( iCount == numFiles )
       
   186         {
       
   187         // Get next Folder
       
   188         //
       
   189         iCount = 0;          
       
   190         delete iDir;
       
   191         iDir = NULL;
       
   192         do
       
   193             {
       
   194             TRAP(err, iDirScan->NextL(iDir));
       
   195             blocked = iObserver.IsPathBlockedL( iDirScan->FullPath() );
       
   196             if( blocked )
       
   197                 {
   182                 {
   198                 delete iDir;
   183                 buffer.Append( KTxtBackSlash );
   199                 iDir = NULL;
   184 
       
   185                 blocked = iObserver.IsPathBlockedL( buffer );
       
   186 
       
   187                 if ( !blocked )
       
   188                     {
       
   189                     CDirQueueEntry* newEntry = CDirQueueEntry::NewL( buffer );
       
   190                     TInt err = newEntry->iDir.Open( iFs,
       
   191                                                     buffer,
       
   192                                              KEntryAttNormal | KEntryAttDir );
       
   193                     if ( err == KErrNone )
       
   194                         {
       
   195                         CDirQueueEntry::PushL( iDirQueue, newEntry );
       
   196                         }
       
   197                     else
       
   198                         {
       
   199                         delete newEntry;
       
   200                         }
       
   201                     }
   200                 }
   202                 }
   201             if( err == KErrNotReady )
   203             else // entry is a file
   202                 {
   204                 {
   203                 delete iDir;
   205                 TInt index = iObserver.IsMediaFileL( buffer );
   204                 iDir = NULL;
   206                 if( KErrNotFound != index )
   205                 break;
   207                     {
       
   208                     iObserver.HandleFileAdditionL( buffer, index );
       
   209                     }
   206                 }
   210                 }
   207             }
   211             if ( iCurDirQueueEntry->iPos % KFileNumBreakCount == 0 )
   208         while ( err == KErrPathNotFound || blocked );  
   212                 {
   209         
   213                 return done;
   210         // No more directories to scan on this drive
   214                 }
   211         //
   215             }
   212         if( !iDir )
   216         }
   213             {
   217 
   214             done = SetupNextDriveToScanL();  
   218     // this dir has other entries to read
       
   219     if ( iStatus == KErrNone )
       
   220         {
       
   221         iCurDirQueueEntry->ResetPosition();
       
   222         ReadDirEntry();
       
   223         }
       
   224 
       
   225     // there is nothing to read or some error has occured during reading,
       
   226     // try to move to next dir
       
   227     else
       
   228         {
       
   229         CDirQueueEntry::PopAndDestroy( iDirQueue );
       
   230         if ( iDirQueue.Count() || !SetupNextDriveToScanL() )
       
   231             {
       
   232             iCurDirQueueEntry = iDirQueue[ 0 ];
       
   233             iCurFullPath = iCurDirQueueEntry->iFullPath;
       
   234             ReadDirEntry();
       
   235             }
       
   236         else // there is nothing to scan
       
   237             {
       
   238             done = ETrue;
   215             }
   239             }
   216         }
   240         }
   217         
   241         
   218     MPX_DEBUG1("CMPXFolderScanner::DoScanL --->");
   242     MPX_DEBUG1("CMPXFolderScanner::DoScanL --->");
   219     return done;
   243     return done;
   228     MPX_DEBUG1("CMPXFolderScanner::SetupNextDriveToScanL <---");
   252     MPX_DEBUG1("CMPXFolderScanner::SetupNextDriveToScanL <---");
   229     
   253     
   230     TBool done(EFalse);
   254     TBool done(EFalse);
   231     TBool blocked(EFalse);
   255     TBool blocked(EFalse);
   232     // Scan next drive
   256     // Scan next drive
   233     while( iDir == NULL && !done )
   257     while( iDrivesToScan.Count() && !iDirQueue.Count() )
   234         {
   258         {
   235         if( !iDrivesToScan.Count() )
   259         TPath path = iDrivesToScan[0];
   236             {
   260 
   237             // No more drives or folders that we are interested in
   261         MPX_DEBUG1( "CMPXFolderScanner::SetupNextDriveToScanL path blocked?" );
   238             done = ETrue;
   262         blocked = iObserver.IsPathBlockedL( path );
   239             }
   263         MPX_DEBUG2( "CMPXFolderScanner::SetupNextDriveToScanL path blocked %i",
   240         else
   264                     blocked );
   241             {
   265 
   242             iDirScan->SetScanDataL(iDrivesToScan[0], KEntryAttNormal, ESortNone);
   266         // If there was something to scan
   243             iCount = 0;
   267         if( !blocked )
   244             TInt err(KErrNone);
   268             {
   245             do
   269             CDirQueueEntry* newEntry = CDirQueueEntry::NewL( path );
       
   270             TInt err = newEntry->iDir.Open( iFs,
       
   271                                             path,
       
   272                                             KEntryAttNormal | KEntryAttDir );
       
   273             if ( err == KErrNone )
   246                 {
   274                 {
   247                 MPX_DEBUG1("CMPXFolderScanner::SetupNextDriveToScanL iDirScan->NextL()");
   275                 CDirQueueEntry::PushL( iDirQueue, newEntry );
   248                 TRAP(err, iDirScan->NextL(iDir));
       
   249                 MPX_DEBUG2("CMPXFolderScanner::SetupNextDriveToScanL path %S", &iDirScan->FullPath());
       
   250                 blocked = iObserver.IsPathBlockedL( iDirScan->FullPath() );
       
   251                 MPX_DEBUG2("CMPXFolderScanner::SetupNextDriveToScanL path blocked %i", blocked);
       
   252                 if( blocked )
       
   253                     {
       
   254                     delete iDir;
       
   255                     iDir = NULL;
       
   256                     }
       
   257                 }
       
   258             while (err == KErrPathNotFound || blocked );  
       
   259             
       
   260             // If there was something to scan
       
   261             //
       
   262             if( iDir != NULL )
       
   263                 {
       
   264                 // Inform Observer of the new drive that we are scanning
   276                 // Inform Observer of the new drive that we are scanning
   265                 iObserver.HandleOpenDriveL( ::ExtractDrive(iDrivesToScan[0]), 
   277                 iObserver.HandleOpenDriveL( ::ExtractDrive(iDrivesToScan[0]),
   266                                             iDrivesToScan[0] );
   278                                             iDrivesToScan[0] );
   267                 }
   279                 }
   268                 
   280             else
   269             // Remove the 0th element
   281                 {
   270             iDrivesToScan.Remove(0); 
   282                 delete newEntry;
   271             iDrivesToScan.Compress();
   283                 }
   272             }
   284             }
       
   285 
       
   286         // Remove the 0th element
       
   287         iDrivesToScan.Remove(0);
       
   288         iDrivesToScan.Compress();
       
   289 
       
   290         }
       
   291 
       
   292     if ( !iDirQueue.Count() )
       
   293         {
       
   294         done = ETrue;
   273         }
   295         }
   274     
   296     
   275     
   297     
   276     MPX_DEBUG1("CMPXFolderScanner::SetupNextDriveToScanL --->");
   298     MPX_DEBUG1("CMPXFolderScanner::SetupNextDriveToScanL --->");
   277     return done;
   299     return done;
   285     {
   307     {
   286     MPX_DEBUG1("CMPXFolderScanner::DoScanCompleteL <---");
   308     MPX_DEBUG1("CMPXFolderScanner::DoScanCompleteL <---");
   287     
   309     
   288     // Reset all arrays and data
   310     // Reset all arrays and data
   289     iDrivesToScan.Reset();
   311     iDrivesToScan.Reset();
   290     
   312     iDirQueue.ResetAndDestroy();
       
   313 
   291     // All done!
   314     // All done!
   292     iScanning = EFalse;
   315     iScanning = EFalse;
   293     
   316 
   294     delete iDir;
       
   295     iDir = NULL;
       
   296     
       
   297     // Callback to observer
   317     // Callback to observer
   298     iStateObserver.HandleScanStateCompleteL( MMPXFileScanStateObserver::EScanFiles, 
   318     iStateObserver.HandleScanStateCompleteL( MMPXFileScanStateObserver::EScanFiles, 
   299                                               aErr );
   319                                               aErr );
   300     
   320     
   301     MPX_DEBUG1("CMPXFolderScanner::DoScanCompleteL --->");
   321     MPX_DEBUG1("CMPXFolderScanner::DoScanCompleteL --->");
   317     //
   337     //
   318     if( KErrNone != err || done )
   338     if( KErrNone != err || done )
   319         {
   339         {
   320         DoScanCompleteL( err );
   340         DoScanCompleteL( err );
   321         }
   341         }
   322     else // if( !done )
   342     else if ( iCurDirQueueEntry->iPos ) // if( !done )
   323         {
   343         {
   324         MPX_DEBUG1("CMPXFolderScanner::RunL -- Run again");
   344         MPX_DEBUG1("CMPXFolderScanner::RunL -- Run again");
   325         iStatus = KRequestPending;
   345         iStatus = KRequestPending;
   326         SetActive();
   346         SetActive();
   327         TRequestStatus* status = &iStatus;
   347         TRequestStatus* status = &iStatus;
   351     MPX_DEBUG2("CMPXFolderScanner::RunError(%d)", aError );
   371     MPX_DEBUG2("CMPXFolderScanner::RunError(%d)", aError );
   352     
   372     
   353     TRAP_IGNORE( DoScanCompleteL( aError ) );
   373     TRAP_IGNORE( DoScanCompleteL( aError ) );
   354     
   374     
   355     return KErrNone;
   375     return KErrNone;
   356     }        
   376     }
       
   377 
       
   378 // ---------------------------------------------------------------------------
       
   379 // Two Phased Constructor
       
   380 // ---------------------------------------------------------------------------
       
   381 //
       
   382 CMPXFolderScanner::CDirQueueEntry* CMPXFolderScanner::CDirQueueEntry::NewL(
       
   383                                                     const TDesC& aFullPath )
       
   384     {
       
   385     CDirQueueEntry* self = new ( ELeave ) CDirQueueEntry;
       
   386     CleanupStack::PushL( self );
       
   387     self->ConstructL( aFullPath );
       
   388     CleanupStack::Pop( self );
       
   389     return self;
       
   390     }
       
   391 
       
   392 // ---------------------------------------------------------------------------
       
   393 // Destructor
       
   394 // ---------------------------------------------------------------------------
       
   395 //
       
   396 CMPXFolderScanner::CDirQueueEntry::~CDirQueueEntry()
       
   397     {
       
   398     iDir.Close();
       
   399     delete iFullPath;
       
   400     }
       
   401 
       
   402 // ---------------------------------------------------------------------------
       
   403 // Push a dir entry into a dir entry queue
       
   404 // ---------------------------------------------------------------------------
       
   405 //
       
   406 void CMPXFolderScanner::CDirQueueEntry::PushL(
       
   407                                      RPointerArray<CDirQueueEntry>& aDirQueue,
       
   408                                      CDirQueueEntry* aDirEntry )
       
   409     {
       
   410     aDirQueue.AppendL( aDirEntry );
       
   411     }
       
   412 
       
   413 // ---------------------------------------------------------------------------
       
   414 // Pop and destroy a dir entry from a dir entry queue
       
   415 // ---------------------------------------------------------------------------
       
   416 //
       
   417 void CMPXFolderScanner::CDirQueueEntry::PopAndDestroy(
       
   418                                   RPointerArray< CDirQueueEntry >& aDirQueue )
       
   419     {
       
   420     CDirQueueEntry* entry = aDirQueue[ 0 ];
       
   421     delete entry;
       
   422     aDirQueue.Remove( 0 );
       
   423     }
       
   424 
       
   425 // ---------------------------------------------------------------------------
       
   426 // CMPXFolderScanner::CDirQueueEntry::NextEntry
       
   427 // ---------------------------------------------------------------------------
       
   428 //
       
   429 const TEntry* CMPXFolderScanner::CDirQueueEntry::NextEntry()
       
   430     {
       
   431     const TEntry* entry = NULL;
       
   432     if ( iPos >= 0 && iPos < iEntryArray.Count() )
       
   433         {
       
   434         entry = &iEntryArray[ iPos++ ];
       
   435         }
       
   436     return entry;
       
   437     }
       
   438 
       
   439 // ---------------------------------------------------------------------------
       
   440 // Reset the current position of entry array
       
   441 // ---------------------------------------------------------------------------
       
   442 //
       
   443 void CMPXFolderScanner::CDirQueueEntry::ResetPosition()
       
   444     {
       
   445     iPos = 0;
       
   446     }
       
   447 
       
   448 // ---------------------------------------------------------------------------
       
   449 // Constructor
       
   450 // ---------------------------------------------------------------------------
       
   451 //
       
   452 CMPXFolderScanner::CDirQueueEntry::CDirQueueEntry()
       
   453     {
       
   454     // Do nothing
       
   455     }
       
   456 
       
   457 // ---------------------------------------------------------------------------
       
   458 // 2nd Phase Contructor
       
   459 // ---------------------------------------------------------------------------
       
   460 //
       
   461 void CMPXFolderScanner::CDirQueueEntry::ConstructL( const TDesC& aFullPath )
       
   462     {
       
   463     iFullPath = aFullPath.AllocL();
       
   464     }