diff -r f4fd77a452f2 -r 3b098142db83 mmappcomponents/harvester/filehandler/src/mpxfolderscanner.cpp --- a/mmappcomponents/harvester/filehandler/src/mpxfolderscanner.cpp Thu Sep 02 20:56:29 2010 +0300 +++ b/mmappcomponents/harvester/filehandler/src/mpxfolderscanner.cpp Fri Sep 17 08:33:08 2010 +0300 @@ -24,6 +24,7 @@ // CONSTANTS const TInt KFileNumBreakCount = 5; +_LIT( KTxtBackSlash, "\\" ); // ======== LOCAL FUNCTIONS ======== @@ -60,7 +61,7 @@ // void CMPXFolderScanner::ConstructL() { - iDirScan = CDirScan::NewL(iFs); + } // --------------------------------------------------------------------------- @@ -88,10 +89,7 @@ CMPXFolderScanner::~CMPXFolderScanner() { Cancel(); - - delete iDirScan; - delete iDir; - + iDirQueue.ResetAndDestroy(); iDrivesToScan.Close(); } @@ -106,6 +104,7 @@ // Copy all the other drives we want to scan // TInt count( aDrives.Count() ); + MPX_DEBUG2("CMPXFolderScanner::ScanL aDrives %d",count); for( TInt i=0; iiFullPath; + ReadDirEntry(); + // We've started scanning iScanning = ETrue; } @@ -143,6 +141,17 @@ } // --------------------------------------------------------------------------- +// Reads dir entries asynchronously +// --------------------------------------------------------------------------- +// +void CMPXFolderScanner::ReadDirEntry() + { + ASSERT( !IsActive() ); + iCurDirQueueEntry->iDir.Read( iCurDirQueueEntry->iEntryArray, iStatus ); + SetActive(); + } + +// --------------------------------------------------------------------------- // Continue Scanning for more files // --------------------------------------------------------------------------- // @@ -150,68 +159,83 @@ { MPX_DEBUG1("CMPXFolderScanner::DoScanL <---"); TBool done (EFalse); - - // Check each file in each directory - TInt numFiles( iDir->Count() ); - while( iCount < numFiles ) + TBool blocked ( EFalse ); + + // read successfully + if ( iStatus == KErrNone || iStatus == KErrEof ) { - TEntry entry = (*iDir)[iCount]; + TBuf buffer; + const TEntry* entry = NULL; + TInt numEntries( iCurDirQueueEntry->iEntryArray.Count() ); + + // process the entry one by one + while ( iCurDirQueueEntry->iPos < numEntries ) + { + entry = iCurDirQueueEntry->NextEntry(); + buffer.Zero(); + + // Generates the full name of the entry + buffer.Append( *iCurFullPath ); + buffer.Append( entry->iName ); + + if ( entry->IsDir() ) // entry is a directory + { + buffer.Append( KTxtBackSlash ); + + blocked = iObserver.IsPathBlockedL( buffer ); - // Construct the full path and file name - TParse fullEntry; - TPtrC dirPath(iDirScan->FullPath()); - fullEntry.Set(entry.iName, &dirPath, NULL); - - TPtrC fullname = fullEntry.FullName(); - TInt index = iObserver.IsMediaFileL( fullname ); - if( KErrNotFound != index ) - { - iObserver.HandleFileAdditionL( fullname, index ); - } - - // Break if we have scanned enough files - // - ++iCount; - if( iCount%KFileNumBreakCount == 0 ) - { - return EFalse; + if ( !blocked ) + { + CDirQueueEntry* newEntry = CDirQueueEntry::NewL( buffer ); + TInt err = newEntry->iDir.Open( iFs, + buffer, + KEntryAttNormal | KEntryAttDir ); + if ( err == KErrNone ) + { + CDirQueueEntry::PushL( iDirQueue, newEntry ); + } + else + { + delete newEntry; + } + } + } + else // entry is a file + { + TInt index = iObserver.IsMediaFileL( buffer ); + if( KErrNotFound != index ) + { + iObserver.HandleFileAdditionL( buffer, index ); + } + } + if ( iCurDirQueueEntry->iPos % KFileNumBreakCount == 0 ) + { + return done; + } } } - - // All files from this directory scanned, so move onto next - // - TInt err( KErrNone ); - TBool blocked (EFalse); - if( iCount == numFiles ) + + // this dir has other entries to read + if ( iStatus == KErrNone ) { - // Get next Folder - // - iCount = 0; - delete iDir; - iDir = NULL; - do + iCurDirQueueEntry->ResetPosition(); + ReadDirEntry(); + } + + // there is nothing to read or some error has occured during reading, + // try to move to next dir + else + { + CDirQueueEntry::PopAndDestroy( iDirQueue ); + if ( iDirQueue.Count() || !SetupNextDriveToScanL() ) { - TRAP(err, iDirScan->NextL(iDir)); - blocked = iObserver.IsPathBlockedL( iDirScan->FullPath() ); - if( blocked ) - { - delete iDir; - iDir = NULL; - } - if( err == KErrNotReady ) - { - delete iDir; - iDir = NULL; - break; - } + iCurDirQueueEntry = iDirQueue[ 0 ]; + iCurFullPath = iCurDirQueueEntry->iFullPath; + ReadDirEntry(); } - while ( err == KErrPathNotFound || blocked ); - - // No more directories to scan on this drive - // - if( !iDir ) + else // there is nothing to scan { - done = SetupNextDriveToScanL(); + done = ETrue; } } @@ -230,46 +254,44 @@ TBool done(EFalse); TBool blocked(EFalse); // Scan next drive - while( iDir == NULL && !done ) + while( iDrivesToScan.Count() && !iDirQueue.Count() ) { - if( !iDrivesToScan.Count() ) + TPath path = iDrivesToScan[0]; + + MPX_DEBUG1( "CMPXFolderScanner::SetupNextDriveToScanL path blocked?" ); + blocked = iObserver.IsPathBlockedL( path ); + MPX_DEBUG2( "CMPXFolderScanner::SetupNextDriveToScanL path blocked %i", + blocked ); + + // If there was something to scan + if( !blocked ) { - // No more drives or folders that we are interested in - done = ETrue; - } - else - { - iDirScan->SetScanDataL(iDrivesToScan[0], KEntryAttNormal, ESortNone); - iCount = 0; - TInt err(KErrNone); - do + CDirQueueEntry* newEntry = CDirQueueEntry::NewL( path ); + TInt err = newEntry->iDir.Open( iFs, + path, + KEntryAttNormal | KEntryAttDir ); + if ( err == KErrNone ) { - MPX_DEBUG1("CMPXFolderScanner::SetupNextDriveToScanL iDirScan->NextL()"); - TRAP(err, iDirScan->NextL(iDir)); - MPX_DEBUG2("CMPXFolderScanner::SetupNextDriveToScanL path %S", &iDirScan->FullPath()); - blocked = iObserver.IsPathBlockedL( iDirScan->FullPath() ); - MPX_DEBUG2("CMPXFolderScanner::SetupNextDriveToScanL path blocked %i", blocked); - if( blocked ) - { - delete iDir; - iDir = NULL; - } - } - while (err == KErrPathNotFound || blocked ); - - // If there was something to scan - // - if( iDir != NULL ) - { + CDirQueueEntry::PushL( iDirQueue, newEntry ); // Inform Observer of the new drive that we are scanning - iObserver.HandleOpenDriveL( ::ExtractDrive(iDrivesToScan[0]), + iObserver.HandleOpenDriveL( ::ExtractDrive(iDrivesToScan[0]), iDrivesToScan[0] ); } - - // Remove the 0th element - iDrivesToScan.Remove(0); - iDrivesToScan.Compress(); + else + { + delete newEntry; + } } + + // Remove the 0th element + iDrivesToScan.Remove(0); + iDrivesToScan.Compress(); + + } + + if ( !iDirQueue.Count() ) + { + done = ETrue; } @@ -287,13 +309,11 @@ // Reset all arrays and data iDrivesToScan.Reset(); - + iDirQueue.ResetAndDestroy(); + // All done! iScanning = EFalse; - - delete iDir; - iDir = NULL; - + // Callback to observer iStateObserver.HandleScanStateCompleteL( MMPXFileScanStateObserver::EScanFiles, aErr ); @@ -319,7 +339,7 @@ { DoScanCompleteL( err ); } - else // if( !done ) + else if ( iCurDirQueueEntry->iPos ) // if( !done ) { MPX_DEBUG1("CMPXFolderScanner::RunL -- Run again"); iStatus = KRequestPending; @@ -353,4 +373,92 @@ TRAP_IGNORE( DoScanCompleteL( aError ) ); return KErrNone; - } + } + +// --------------------------------------------------------------------------- +// Two Phased Constructor +// --------------------------------------------------------------------------- +// +CMPXFolderScanner::CDirQueueEntry* CMPXFolderScanner::CDirQueueEntry::NewL( + const TDesC& aFullPath ) + { + CDirQueueEntry* self = new ( ELeave ) CDirQueueEntry; + CleanupStack::PushL( self ); + self->ConstructL( aFullPath ); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CMPXFolderScanner::CDirQueueEntry::~CDirQueueEntry() + { + iDir.Close(); + delete iFullPath; + } + +// --------------------------------------------------------------------------- +// Push a dir entry into a dir entry queue +// --------------------------------------------------------------------------- +// +void CMPXFolderScanner::CDirQueueEntry::PushL( + RPointerArray& aDirQueue, + CDirQueueEntry* aDirEntry ) + { + aDirQueue.AppendL( aDirEntry ); + } + +// --------------------------------------------------------------------------- +// Pop and destroy a dir entry from a dir entry queue +// --------------------------------------------------------------------------- +// +void CMPXFolderScanner::CDirQueueEntry::PopAndDestroy( + RPointerArray< CDirQueueEntry >& aDirQueue ) + { + CDirQueueEntry* entry = aDirQueue[ 0 ]; + delete entry; + aDirQueue.Remove( 0 ); + } + +// --------------------------------------------------------------------------- +// CMPXFolderScanner::CDirQueueEntry::NextEntry +// --------------------------------------------------------------------------- +// +const TEntry* CMPXFolderScanner::CDirQueueEntry::NextEntry() + { + const TEntry* entry = NULL; + if ( iPos >= 0 && iPos < iEntryArray.Count() ) + { + entry = &iEntryArray[ iPos++ ]; + } + return entry; + } + +// --------------------------------------------------------------------------- +// Reset the current position of entry array +// --------------------------------------------------------------------------- +// +void CMPXFolderScanner::CDirQueueEntry::ResetPosition() + { + iPos = 0; + } + +// --------------------------------------------------------------------------- +// Constructor +// --------------------------------------------------------------------------- +// +CMPXFolderScanner::CDirQueueEntry::CDirQueueEntry() + { + // Do nothing + } + +// --------------------------------------------------------------------------- +// 2nd Phase Contructor +// --------------------------------------------------------------------------- +// +void CMPXFolderScanner::CDirQueueEntry::ConstructL( const TDesC& aFullPath ) + { + iFullPath = aFullPath.AllocL(); + }