filemanager/GFLM/src/CGflmFileRecognizer.cpp
changeset 14 1957042d8c7e
parent 1 d1daf54a55b5
child 16 ada7962b4308
equal deleted inserted replaced
1:d1daf54a55b5 14:1957042d8c7e
     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     // read the pairs
       
   101     HBufC8* resData = aResFile.AllocReadLC( aResId );
       
   102     TResourceReader reader;
       
   103     reader.SetBuffer( resData );
       
   104     TInt count( reader.ReadInt16() );
       
   105     aPairs.ReserveL( count );
       
   106     for ( TInt i( 0 ); i < count; i++ )
       
   107         {
       
   108         TPtrC ext( reader.ReadTPtrC() );
       
   109         TPtrC mime( reader.ReadTPtrC() );
       
   110         CExtMimePair* pair = new (ELeave) CExtMimePair();
       
   111         CleanupStack::PushL( pair );
       
   112         pair->iExt = ext.AllocL();
       
   113         pair->iMime = mime.AllocL();
       
   114         aPairs.AppendL( pair );
       
   115         CleanupStack::Pop( pair );
       
   116         }
       
   117     CleanupStack::PopAndDestroy( resData );
       
   118     }
       
   119 
       
   120 // -----------------------------------------------------------------------------
       
   121 // CGflmFileRecognizer::FindMimeFromExt
       
   122 //
       
   123 // -----------------------------------------------------------------------------
       
   124 //
       
   125 TPtrC CGflmFileRecognizer::FindMimeFromExt(
       
   126         const TDesC& aExt,
       
   127         RPointerArray< CExtMimePair >& aPairs )
       
   128     {
       
   129     TInt count( aPairs.Count() );
       
   130 
       
   131     for( TInt i( 0 ); i < count; i++)
       
   132         {
       
   133         CExtMimePair* pair = aPairs[ i ];
       
   134         if( !aExt.CompareF( *pair->iExt ) )
       
   135             {
       
   136             return TPtrC( *pair->iMime );
       
   137             }
       
   138         }
       
   139     return TPtrC( KNullDesC );
       
   140     }
       
   141 
       
   142 // -----------------------------------------------------------------------------
       
   143 // CGflmFileRecognizer::NewL
       
   144 // Two-phased constructor.
       
   145 // -----------------------------------------------------------------------------
       
   146 //
       
   147 CGflmFileRecognizer* CGflmFileRecognizer::NewL(
       
   148         RFs& aFs,
       
   149         TInt aMemoryConsumption,
       
   150         CGflmDriveResolver* aDriveResolver )
       
   151     {
       
   152     CGflmFileRecognizer* self =
       
   153         new( ELeave ) CGflmFileRecognizer( aDriveResolver, aFs );
       
   154 
       
   155     CleanupStack::PushL( self );
       
   156     self->ConstructL( aMemoryConsumption );
       
   157     CleanupStack::Pop( self );
       
   158 
       
   159     return self;
       
   160     }
       
   161 
       
   162 // -----------------------------------------------------------------------------
       
   163 // CGflmFileRecognizer::~CGflmFileRecognizer
       
   164 //
       
   165 // -----------------------------------------------------------------------------
       
   166 //
       
   167 CGflmFileRecognizer::~CGflmFileRecognizer()
       
   168     {
       
   169     iApaSession.Close();
       
   170 
       
   171     FlushCache();
       
   172 
       
   173     delete iMimeTypes;
       
   174 
       
   175     iExtMimePairs.ResetAndDestroy();
       
   176     iExtMimePairs.Close();
       
   177 
       
   178     iRemoteExtMimePairs.ResetAndDestroy();
       
   179     iRemoteExtMimePairs.Close();
       
   180     }
       
   181 
       
   182 // -----------------------------------------------------------------------------
       
   183 // CGflmFileRecognizer::RecognizeL( const TDesC& aFilename )
       
   184 // (other items were commented in a header).
       
   185 // -----------------------------------------------------------------------------
       
   186 //
       
   187 TPtrC CGflmFileRecognizer::RecognizeL( const TDesC& aFilename )
       
   188     {
       
   189     TPtrC mimeType;
       
   190     TRAPD( err, mimeType.Set( DoRecognizeL( aFilename ) ) );
       
   191     if ( err == KErrNoMemory )
       
   192         {
       
   193         FlushCache();
       
   194         return DoRecognizeL( aFilename );
       
   195         }
       
   196     User::LeaveIfError( err );
       
   197     return mimeType;
       
   198     }
       
   199 
       
   200 // -----------------------------------------------------------------------------
       
   201 // CGflmFileRecognizer::DoRecognizeL( const TDesC& aFilename )
       
   202 // (other items were commented in a header).
       
   203 // -----------------------------------------------------------------------------
       
   204 //
       
   205 TPtrC CGflmFileRecognizer::DoRecognizeL( const TDesC& aFilename )
       
   206     {
       
   207     // Search the cache for a hit
       
   208     TInt cropPoint( aFilename.LocateReverse( KGFLMDot()[ 0 ] ) );
       
   209     TBool isRemoteDrive( EFalse );
       
   210 
       
   211     if ( iDriveResolver && iDriveResolver->IsRemoteDrive( aFilename ) )
       
   212         {
       
   213         isRemoteDrive = ETrue;
       
   214         }
       
   215 
       
   216     if( cropPoint != KErrNotFound )
       
   217         {        
       
   218         TPtrC ext( aFilename.Mid( cropPoint ) );
       
   219         TPtrC mime( FindMimeFromExt( ext, iExtMimePairs ) );
       
   220         if ( mime.Length() )
       
   221             {
       
   222             return mime;
       
   223             }
       
   224 
       
   225         // Use remote drive specific extension mime pairs and skip
       
   226         // content recognition because it is so slow for remote drives.
       
   227         // Mime types are resolved from extension by remote storage framework
       
   228         // anyway.
       
   229         if ( isRemoteDrive)
       
   230             {
       
   231             return FindMimeFromExt( ext, iRemoteExtMimePairs );
       
   232             }
       
   233         }
       
   234     else if ( isRemoteDrive)
       
   235         {
       
   236         // Skip content recognition for remote drives because it is so slow
       
   237         return TPtrC( KNullDesC );
       
   238         }
       
   239 
       
   240     TDblQueIter< CPathTypePair > pairIt( iCache );
       
   241     pairIt.SetToFirst();
       
   242     CPathTypePair* pair = NULL;
       
   243     while ( ( pair = pairIt++ ) != NULL )
       
   244         {
       
   245         TPtrC ptr( *( pair->iFilename ) );
       
   246         if( ptr.Length() == aFilename.Length() &&
       
   247            !aFilename.CompareF( ptr ) )
       
   248             {
       
   249             // Cache hit
       
   250             // Move item to the first position if not already.
       
   251             // When clearing cache, oldest items can be dropped easily.
       
   252             pair->iLink.Deque();
       
   253             iCache.AddFirst( *pair );
       
   254 
       
   255             if ( pair->iTypeIndex != KErrNotFound )
       
   256                 {
       
   257                 return iMimeTypes->MdcaPoint( pair->iTypeIndex );
       
   258                 }
       
   259             return TPtrC( KNullDesC );
       
   260             }
       
   261         }
       
   262 
       
   263         // Cache miss
       
   264         TUid uid( KNullUid );
       
   265         TDataType datatype;
       
   266 
       
   267         TIMESTAMP( "GFLM AppForDocument started: " )
       
   268 
       
   269         // Acquire the mime-type of the file
       
   270         TInt err( iApaSession.AppForDocument( aFilename, uid, datatype ) );
       
   271 
       
   272         TIMESTAMP( "GFLM AppForDocument ended: " )
       
   273 
       
   274         if ( err != KErrNone )
       
   275             {
       
   276             // If recognition returns error, handle as unrecognized file
       
   277             ERROR_LOG1(
       
   278                 "CGflmFileRecognizer::DoRecognizeL-AppForDocument=%d",
       
   279                 err )
       
   280             return TPtrC( KNullDesC );
       
   281             }
       
   282 
       
   283         CPathTypePair* newPair = CPathTypePair::NewLC( aFilename );
       
   284         TPtrC mimeType( datatype.Des() );
       
   285 
       
   286         INFO_LOG2( "GFLM AppForDocument:file=%S,mime=%S", &aFilename, &mimeType )
       
   287 
       
   288         // Run through the mime-type list to find the correct index
       
   289         if ( mimeType.Length() )
       
   290             {
       
   291             TBool isMimeFound( EFalse );
       
   292             TInt mimeCount( iMimeTypes->MdcaCount() );
       
   293             for ( TInt j( 0 ); j < mimeCount; j++ )
       
   294                 {
       
   295                 if( !mimeType.CompareF( iMimeTypes->MdcaPoint( j ) ) )
       
   296                     {
       
   297                     newPair->iTypeIndex = j;
       
   298                     isMimeFound = ETrue;
       
   299                     break;
       
   300                     }
       
   301                 }
       
   302             // Add mime type to list if not already added
       
   303             if ( !isMimeFound )
       
   304                 {
       
   305                 iMimeTypes->AppendL( mimeType );
       
   306                 newPair->iTypeIndex = mimeCount;
       
   307                 }
       
   308             }
       
   309 
       
   310         // Cleanup cache and add new pair
       
   311         CleanupStack::Pop( newPair );
       
   312         CleanupCache();
       
   313         iCacheMemoryUsage += newPair->Size();
       
   314         iCache.AddFirst( *newPair );
       
   315 
       
   316         if ( newPair->iTypeIndex != KErrNotFound )
       
   317             {
       
   318             return iMimeTypes->MdcaPoint( newPair->iTypeIndex );
       
   319             }
       
   320         return TPtrC( KNullDesC );
       
   321     }
       
   322 
       
   323 // -----------------------------------------------------------------------------
       
   324 // CGflmFileRecognizer::FlushCache( )
       
   325 //
       
   326 // -----------------------------------------------------------------------------
       
   327 //
       
   328 void CGflmFileRecognizer::FlushCache()
       
   329     {
       
   330     TDblQueIter< CPathTypePair > pairIt( iCache );
       
   331     pairIt.SetToFirst();
       
   332     CPathTypePair* pair = NULL;
       
   333     while ( ( pair = pairIt++ ) != NULL )
       
   334         {
       
   335         pair->iLink.Deque();
       
   336         delete pair;
       
   337         }
       
   338     iCacheMemoryUsage = 0;
       
   339     }
       
   340 
       
   341 // -----------------------------------------------------------------------------
       
   342 // CGflmFileRecognizer::CleanupCache( )
       
   343 //
       
   344 // -----------------------------------------------------------------------------
       
   345 //
       
   346 void CGflmFileRecognizer::CleanupCache( )
       
   347     {
       
   348     if( iCacheMemoryUsage > iCacheMaxMemoryUsage )
       
   349         {
       
   350         TInt dropThreshold = ( TInt ) ( ( ( ( TUint ) iCacheMaxMemoryUsage ) *
       
   351             KPerCentToDrop ) / KHundredPerCent );
       
   352         TInt droppedSize( 0 );
       
   353 
       
   354         TDblQueIter< CPathTypePair > pairIt( iCache );
       
   355         pairIt.SetToLast();
       
   356         CPathTypePair* pair = NULL;
       
   357         while ( ( pair = pairIt-- ) != NULL )
       
   358             {
       
   359             droppedSize += pair->Size();
       
   360             pair->iLink.Deque();
       
   361             delete pair;
       
   362             if ( droppedSize >= dropThreshold )
       
   363                 {
       
   364                 break;
       
   365                 }
       
   366             }
       
   367         iCacheMemoryUsage -= droppedSize;
       
   368         }
       
   369     }
       
   370 
       
   371 // -----------------------------------------------------------------------------
       
   372 // CGflmFileRecognizer::CPathTypePair::NewLC()
       
   373 // 
       
   374 // -----------------------------------------------------------------------------
       
   375 //
       
   376 CGflmFileRecognizer::CPathTypePair*
       
   377         CGflmFileRecognizer::CPathTypePair::NewLC( const TDesC& aFilename )
       
   378     {
       
   379     CPathTypePair* self = new ( ELeave ) CPathTypePair();
       
   380     CleanupStack::PushL( self );
       
   381     self->ConstructL( aFilename );
       
   382     return self;
       
   383     }
       
   384 
       
   385 // -----------------------------------------------------------------------------
       
   386 // CGflmFileRecognizer::CPathTypePair::ConstructL()
       
   387 // 
       
   388 // -----------------------------------------------------------------------------
       
   389 //
       
   390 void CGflmFileRecognizer::CPathTypePair::ConstructL( const TDesC& aFilename )
       
   391     {
       
   392     iFilename = aFilename.AllocL();
       
   393     }
       
   394 
       
   395 // -----------------------------------------------------------------------------
       
   396 // CGflmFileRecognizer::CPathTypePair::CPathTypePair()
       
   397 // 
       
   398 // -----------------------------------------------------------------------------
       
   399 //
       
   400 CGflmFileRecognizer::CPathTypePair::CPathTypePair() :
       
   401         iTypeIndex( KErrNotFound )
       
   402     {
       
   403     }
       
   404 
       
   405 // -----------------------------------------------------------------------------
       
   406 // CGflmFileRecognizer::CPathTypePair::~CPathTypePair()
       
   407 // 
       
   408 // -----------------------------------------------------------------------------
       
   409 //
       
   410 CGflmFileRecognizer::CPathTypePair::~CPathTypePair()
       
   411     {
       
   412     delete iFilename;
       
   413     }
       
   414 
       
   415 // -----------------------------------------------------------------------------
       
   416 // CGflmFileRecognizer::CPathTypePair::Size()
       
   417 // 
       
   418 // -----------------------------------------------------------------------------
       
   419 //
       
   420 TInt CGflmFileRecognizer::CPathTypePair::Size() const
       
   421     {
       
   422     return ( sizeof( TInt ) + iFilename->Size() + sizeof( TDblQueLink ) );
       
   423     }
       
   424 
       
   425 // -----------------------------------------------------------------------------
       
   426 // CGflmFileRecognizer::CExtMimePair::~CExtMimePair()
       
   427 // 
       
   428 // -----------------------------------------------------------------------------
       
   429 //
       
   430 CGflmFileRecognizer::CExtMimePair::~CExtMimePair()
       
   431     {
       
   432     delete iExt;
       
   433     delete iMime;
       
   434     }
       
   435 
       
   436 //  End of File