filemanager/GFLM/src/CGflmFileRecognizer.cpp
branchRCL_3
changeset 38 491b3ed49290
parent 36 95243422089a
child 39 65326cf895ed
equal deleted inserted replaced
36:95243422089a 38:491b3ed49290
     1 /*
       
     2 * Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0""
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Recogniser wrapper
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "CGflmFileRecognizer.h"
       
    22 #include "CGflmDriveResolver.h"
       
    23 #include "CGflmDriveItem.h"
       
    24 #include "GflmUtils.h"
       
    25 #include "GFLMConsts.h"
       
    26 #include <e32svr.h>
       
    27 #include <barsread.h>
       
    28 #include <gflmfileextensionmimetypes.rsg>
       
    29 #include <data_caging_path_literals.hrh> 
       
    30 
       
    31 
       
    32 // CONSTANTS
       
    33 _LIT( KFileExtensionResourceFile, "gflmfileextensionmimetypes.rsc" );
       
    34 const TInt KMimeTypeGranularity = 10;
       
    35 const TUint KPerCentToDrop = 30;
       
    36 const TUint KHundredPerCent = 100;
       
    37 
       
    38 
       
    39 // ============================ MEMBER FUNCTIONS ===============================
       
    40 
       
    41 // -----------------------------------------------------------------------------
       
    42 // CGflmFileRecognizer::CGflmFileRecognizer
       
    43 // C++ default constructor can NOT contain any code, that
       
    44 // might leave.
       
    45 // -----------------------------------------------------------------------------
       
    46 //
       
    47 CGflmFileRecognizer::CGflmFileRecognizer(
       
    48         CGflmDriveResolver* aDriveResolver,
       
    49         RFs& aFs ) :
       
    50     iCache( _FOFF( CPathTypePair, iLink ) ),
       
    51     iDriveResolver( aDriveResolver ),
       
    52     iFs( aFs )
       
    53     {
       
    54     }
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 // CGflmFileRecognizer::ConstructL
       
    58 // Symbian 2nd phase constructor can leave.
       
    59 // -----------------------------------------------------------------------------
       
    60 //
       
    61 void CGflmFileRecognizer::ConstructL( TInt aMemoryConsumption )
       
    62     {
       
    63     User::LeaveIfError( iApaSession.Connect() );
       
    64     iMimeTypes = new( ELeave ) CDesCArraySeg( KMimeTypeGranularity );
       
    65     iCacheMaxMemoryUsage = aMemoryConsumption;
       
    66 
       
    67     // Get resource drive from dll location
       
    68     TFileName dllFileName;
       
    69     Dll::FileName( dllFileName );
       
    70     TParsePtrC dllParse( dllFileName );
       
    71 
       
    72     TFileName resFileName;
       
    73     resFileName.Copy( dllParse.Drive() );
       
    74     resFileName.Append( KDC_RESOURCE_FILES_DIR );
       
    75     GflmUtils::EnsureFinalBackslash( resFileName );
       
    76     resFileName.Append( KFileExtensionResourceFile );
       
    77 
       
    78     RResourceFile resFile;
       
    79     resFile.OpenL( iFs, resFileName );
       
    80     CleanupClosePushL( resFile );
       
    81     resFile.ConfirmSignatureL();
       
    82 
       
    83     ConstructExtMimePairsL( resFile, R_EXT_MIME_PAIRS, iExtMimePairs );
       
    84     ConstructExtMimePairsL(
       
    85         resFile, R_REMOTE_EXT_MIME_PAIRS, iRemoteExtMimePairs );
       
    86 
       
    87     CleanupStack::PopAndDestroy( &resFile );
       
    88     }
       
    89 
       
    90 // -----------------------------------------------------------------------------
       
    91 // CGflmFileRecognizer::ConstructExtMimePairsL
       
    92 //
       
    93 // -----------------------------------------------------------------------------
       
    94 //
       
    95 void CGflmFileRecognizer::ConstructExtMimePairsL(
       
    96         RResourceFile& aResFile,
       
    97         TInt aResId,
       
    98         RPointerArray< CExtMimePair >& aPairs )
       
    99     {   
       
   100     TCleanupItem cleanupItem( ResetAndDestroyExtMimePairs, &aPairs );
       
   101     CleanupStack::PushL( cleanupItem );
       
   102     // read the pairs
       
   103     HBufC8* resData = aResFile.AllocReadLC( aResId );
       
   104     TResourceReader reader;
       
   105     reader.SetBuffer( resData );
       
   106     TInt count( reader.ReadInt16() );
       
   107     aPairs.ReserveL( count );
       
   108     for ( TInt i( 0 ); i < count; i++ )
       
   109         {
       
   110         TPtrC ext( reader.ReadTPtrC() );
       
   111         TPtrC mime( reader.ReadTPtrC() );
       
   112         CExtMimePair* pair = new (ELeave) CExtMimePair();
       
   113         CleanupStack::PushL( pair );
       
   114         pair->iExt = ext.AllocL();
       
   115         pair->iMime = mime.AllocL();
       
   116         aPairs.AppendL( pair );
       
   117         CleanupStack::Pop( pair );
       
   118         }
       
   119     CleanupStack::PopAndDestroy( resData );
       
   120     CleanupStack::Pop( &aPairs );
       
   121     }
       
   122 
       
   123 // -----------------------------------------------------------------------------
       
   124 // CGflmFileRecognizer::FindMimeFromExt
       
   125 //
       
   126 // -----------------------------------------------------------------------------
       
   127 //
       
   128 TPtrC CGflmFileRecognizer::FindMimeFromExt(
       
   129         const TDesC& aExt,
       
   130         RPointerArray< CExtMimePair >& aPairs )
       
   131     {
       
   132     TInt count( aPairs.Count() );
       
   133 
       
   134     for( TInt i( 0 ); i < count; i++)
       
   135         {
       
   136         CExtMimePair* pair = aPairs[ i ];
       
   137         if( !aExt.CompareF( *pair->iExt ) )
       
   138             {
       
   139             return TPtrC( *pair->iMime );
       
   140             }
       
   141         }
       
   142     return TPtrC( KNullDesC );
       
   143     }
       
   144 
       
   145 // -----------------------------------------------------------------------------
       
   146 // CGflmFileRecognizer::NewL
       
   147 // Two-phased constructor.
       
   148 // -----------------------------------------------------------------------------
       
   149 //
       
   150 CGflmFileRecognizer* CGflmFileRecognizer::NewL(
       
   151         RFs& aFs,
       
   152         TInt aMemoryConsumption,
       
   153         CGflmDriveResolver* aDriveResolver )
       
   154     {
       
   155     CGflmFileRecognizer* self =
       
   156         new( ELeave ) CGflmFileRecognizer( aDriveResolver, aFs );
       
   157 
       
   158     CleanupStack::PushL( self );
       
   159     self->ConstructL( aMemoryConsumption );
       
   160     CleanupStack::Pop( self );
       
   161 
       
   162     return self;
       
   163     }
       
   164 
       
   165 // -----------------------------------------------------------------------------
       
   166 // CGflmFileRecognizer::~CGflmFileRecognizer
       
   167 //
       
   168 // -----------------------------------------------------------------------------
       
   169 //
       
   170 CGflmFileRecognizer::~CGflmFileRecognizer()
       
   171     {
       
   172     iApaSession.Close();
       
   173 
       
   174     FlushCache();
       
   175 
       
   176     delete iMimeTypes;
       
   177 
       
   178     iExtMimePairs.ResetAndDestroy();
       
   179     iExtMimePairs.Close();
       
   180 
       
   181     iRemoteExtMimePairs.ResetAndDestroy();
       
   182     iRemoteExtMimePairs.Close();
       
   183     }
       
   184 
       
   185 // -----------------------------------------------------------------------------
       
   186 // CGflmFileRecognizer::RecognizeL( const TDesC& aFilename )
       
   187 // (other items were commented in a header).
       
   188 // -----------------------------------------------------------------------------
       
   189 //
       
   190 TPtrC CGflmFileRecognizer::RecognizeL( const TDesC& aFilename )
       
   191     {
       
   192     TPtrC mimeType;
       
   193     TRAPD( err, mimeType.Set( DoRecognizeL( aFilename ) ) );
       
   194     if ( err == KErrNoMemory )
       
   195         {
       
   196         FlushCache();
       
   197         return DoRecognizeL( aFilename );
       
   198         }
       
   199     User::LeaveIfError( err );
       
   200     return mimeType;
       
   201     }
       
   202 
       
   203 // -----------------------------------------------------------------------------
       
   204 // CGflmFileRecognizer::DoRecognizeL( const TDesC& aFilename )
       
   205 // (other items were commented in a header).
       
   206 // -----------------------------------------------------------------------------
       
   207 //
       
   208 TPtrC CGflmFileRecognizer::DoRecognizeL( const TDesC& aFilename )
       
   209     {
       
   210     // Search the cache for a hit
       
   211     TInt cropPoint( aFilename.LocateReverse( KGFLMDot()[ 0 ] ) );
       
   212     TBool isRemoteDrive( EFalse );
       
   213 
       
   214     if ( iDriveResolver && iDriveResolver->IsRemoteDrive( aFilename ) )
       
   215         {
       
   216         isRemoteDrive = ETrue;
       
   217         }
       
   218 
       
   219     if( cropPoint != KErrNotFound )
       
   220         {        
       
   221         TPtrC ext( aFilename.Mid( cropPoint ) );
       
   222         TPtrC mime( FindMimeFromExt( ext, iExtMimePairs ) );
       
   223         if ( mime.Length() )
       
   224             {
       
   225             return mime;
       
   226             }
       
   227 
       
   228         // Use remote drive specific extension mime pairs and skip
       
   229         // content recognition because it is so slow for remote drives.
       
   230         // Mime types are resolved from extension by remote storage framework
       
   231         // anyway.
       
   232         if ( isRemoteDrive)
       
   233             {
       
   234             return FindMimeFromExt( ext, iRemoteExtMimePairs );
       
   235             }
       
   236         }
       
   237     else if ( isRemoteDrive)
       
   238         {
       
   239         // Skip content recognition for remote drives because it is so slow
       
   240         return TPtrC( KNullDesC );
       
   241         }
       
   242 
       
   243     TDblQueIter< CPathTypePair > pairIt( iCache );
       
   244     pairIt.SetToFirst();
       
   245     CPathTypePair* pair = NULL;
       
   246     while ( ( pair = pairIt++ ) != NULL )
       
   247         {
       
   248         TPtrC ptr( *( pair->iFilename ) );
       
   249         if( ptr.Length() == aFilename.Length() &&
       
   250            !aFilename.CompareF( ptr ) )
       
   251             {
       
   252             // Cache hit
       
   253             // Move item to the first position if not already.
       
   254             // When clearing cache, oldest items can be dropped easily.
       
   255             pair->iLink.Deque();
       
   256             iCache.AddFirst( *pair );
       
   257 
       
   258             if ( pair->iTypeIndex != KErrNotFound )
       
   259                 {
       
   260                 return iMimeTypes->MdcaPoint( pair->iTypeIndex );
       
   261                 }
       
   262             return TPtrC( KNullDesC );
       
   263             }
       
   264         }
       
   265 
       
   266         // Cache miss
       
   267         TUid uid( KNullUid );
       
   268         TDataType datatype;
       
   269 
       
   270         TIMESTAMP( "GFLM AppForDocument started: " )
       
   271 
       
   272         // Acquire the mime-type of the file
       
   273         TInt err( iApaSession.AppForDocument( aFilename, uid, datatype ) );
       
   274 
       
   275         TIMESTAMP( "GFLM AppForDocument ended: " )
       
   276 
       
   277         if ( err != KErrNone )
       
   278             {
       
   279             // If recognition returns error, handle as unrecognized file
       
   280             ERROR_LOG1(
       
   281                 "CGflmFileRecognizer::DoRecognizeL-AppForDocument=%d",
       
   282                 err )
       
   283             return TPtrC( KNullDesC );
       
   284             }
       
   285 
       
   286         CPathTypePair* newPair = CPathTypePair::NewLC( aFilename );
       
   287         TPtrC mimeType( datatype.Des() );
       
   288 
       
   289         INFO_LOG2( "GFLM AppForDocument:file=%S,mime=%S", &aFilename, &mimeType )
       
   290 
       
   291         // Run through the mime-type list to find the correct index
       
   292         if ( mimeType.Length() )
       
   293             {
       
   294             TBool isMimeFound( EFalse );
       
   295             TInt mimeCount( iMimeTypes->MdcaCount() );
       
   296             for ( TInt j( 0 ); j < mimeCount; j++ )
       
   297                 {
       
   298                 if( !mimeType.CompareF( iMimeTypes->MdcaPoint( j ) ) )
       
   299                     {
       
   300                     newPair->iTypeIndex = j;
       
   301                     isMimeFound = ETrue;
       
   302                     break;
       
   303                     }
       
   304                 }
       
   305             // Add mime type to list if not already added
       
   306             if ( !isMimeFound )
       
   307                 {
       
   308                 iMimeTypes->AppendL( mimeType );
       
   309                 newPair->iTypeIndex = mimeCount;
       
   310                 }
       
   311             }
       
   312 
       
   313         // Cleanup cache and add new pair
       
   314         CleanupStack::Pop( newPair );
       
   315         CleanupCache();
       
   316         iCacheMemoryUsage += newPair->Size();
       
   317         iCache.AddFirst( *newPair );
       
   318 
       
   319         if ( newPair->iTypeIndex != KErrNotFound )
       
   320             {
       
   321             return iMimeTypes->MdcaPoint( newPair->iTypeIndex );
       
   322             }
       
   323         return TPtrC( KNullDesC );
       
   324     }
       
   325 
       
   326 
       
   327 // -----------------------------------------------------------------------------
       
   328 //  CGflmFileRecognizer::ResetAndDestroyExtMimePairs( )
       
   329 // 
       
   330 // -----------------------------------------------------------------------------
       
   331 //
       
   332 void CGflmFileRecognizer::ResetAndDestroyExtMimePairs( TAny* aPtr )
       
   333     {
       
   334     RPointerArray< CExtMimePair >* extMimePairs = 
       
   335         static_cast< RPointerArray< CExtMimePair >* >( aPtr );
       
   336     extMimePairs->ResetAndDestroy();
       
   337     extMimePairs->Close();
       
   338     }
       
   339  
       
   340  
       
   341 // -----------------------------------------------------------------------------
       
   342 // CGflmFileRecognizer::FlushCache( )
       
   343 //
       
   344 // -----------------------------------------------------------------------------
       
   345 //
       
   346 void CGflmFileRecognizer::FlushCache()
       
   347     {
       
   348     TDblQueIter< CPathTypePair > pairIt( iCache );
       
   349     pairIt.SetToFirst();
       
   350     CPathTypePair* pair = NULL;
       
   351     while ( ( pair = pairIt++ ) != NULL )
       
   352         {
       
   353         pair->iLink.Deque();
       
   354         delete pair;
       
   355         }
       
   356     iCacheMemoryUsage = 0;
       
   357     }
       
   358 
       
   359 // -----------------------------------------------------------------------------
       
   360 // CGflmFileRecognizer::CleanupCache( )
       
   361 //
       
   362 // -----------------------------------------------------------------------------
       
   363 //
       
   364 void CGflmFileRecognizer::CleanupCache( )
       
   365     {
       
   366     if( iCacheMemoryUsage > iCacheMaxMemoryUsage )
       
   367         {
       
   368         TInt dropThreshold = ( TInt ) ( ( ( ( TUint ) iCacheMaxMemoryUsage ) *
       
   369             KPerCentToDrop ) / KHundredPerCent );
       
   370         TInt droppedSize( 0 );
       
   371 
       
   372         TDblQueIter< CPathTypePair > pairIt( iCache );
       
   373         pairIt.SetToLast();
       
   374         CPathTypePair* pair = NULL;
       
   375         while ( ( pair = pairIt-- ) != NULL )
       
   376             {
       
   377             droppedSize += pair->Size();
       
   378             pair->iLink.Deque();
       
   379             delete pair;
       
   380             if ( droppedSize >= dropThreshold )
       
   381                 {
       
   382                 break;
       
   383                 }
       
   384             }
       
   385         iCacheMemoryUsage -= droppedSize;
       
   386         }
       
   387     }
       
   388 
       
   389 // -----------------------------------------------------------------------------
       
   390 // CGflmFileRecognizer::CPathTypePair::NewLC()
       
   391 // 
       
   392 // -----------------------------------------------------------------------------
       
   393 //
       
   394 CGflmFileRecognizer::CPathTypePair*
       
   395         CGflmFileRecognizer::CPathTypePair::NewLC( const TDesC& aFilename )
       
   396     {
       
   397     CPathTypePair* self = new ( ELeave ) CPathTypePair();
       
   398     CleanupStack::PushL( self );
       
   399     self->ConstructL( aFilename );
       
   400     return self;
       
   401     }
       
   402 
       
   403 // -----------------------------------------------------------------------------
       
   404 // CGflmFileRecognizer::CPathTypePair::ConstructL()
       
   405 // 
       
   406 // -----------------------------------------------------------------------------
       
   407 //
       
   408 void CGflmFileRecognizer::CPathTypePair::ConstructL( const TDesC& aFilename )
       
   409     {
       
   410     iFilename = aFilename.AllocL();
       
   411     }
       
   412 
       
   413 // -----------------------------------------------------------------------------
       
   414 // CGflmFileRecognizer::CPathTypePair::CPathTypePair()
       
   415 // 
       
   416 // -----------------------------------------------------------------------------
       
   417 //
       
   418 CGflmFileRecognizer::CPathTypePair::CPathTypePair() :
       
   419         iTypeIndex( KErrNotFound )
       
   420     {
       
   421     }
       
   422 
       
   423 // -----------------------------------------------------------------------------
       
   424 // CGflmFileRecognizer::CPathTypePair::~CPathTypePair()
       
   425 // 
       
   426 // -----------------------------------------------------------------------------
       
   427 //
       
   428 CGflmFileRecognizer::CPathTypePair::~CPathTypePair()
       
   429     {
       
   430     delete iFilename;
       
   431     }
       
   432 
       
   433 // -----------------------------------------------------------------------------
       
   434 // CGflmFileRecognizer::CPathTypePair::Size()
       
   435 // 
       
   436 // -----------------------------------------------------------------------------
       
   437 //
       
   438 TInt CGflmFileRecognizer::CPathTypePair::Size() const
       
   439     {
       
   440     return ( sizeof( TInt ) + iFilename->Size() + sizeof( TDblQueLink ) );
       
   441     }
       
   442 
       
   443 // -----------------------------------------------------------------------------
       
   444 // CGflmFileRecognizer::CExtMimePair::~CExtMimePair()
       
   445 // 
       
   446 // -----------------------------------------------------------------------------
       
   447 //
       
   448 CGflmFileRecognizer::CExtMimePair::~CExtMimePair()
       
   449     {
       
   450     delete iExt;
       
   451     delete iMime;
       
   452     }
       
   453 
       
   454 //  End of File