|         |      1 /* | 
|         |      2 * Copyright (c) 2009 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:   | 
|         |     15 * | 
|         |     16 */ | 
|         |     17  | 
|         |     18  | 
|         |     19 // INCLUDE FILES | 
|         |     20 #include    "SamplerPluginLoader.h" | 
|         |     21 //#include	<piprofiler/EngineUIDs.h> | 
|         |     22 #include    <utf.h> // CnvUtfConverter | 
|         |     23 #include  	<basched.h> | 
|         |     24  | 
|         |     25 // CONSTANTS | 
|         |     26  | 
|         |     27 // ---------------------------------------------------------------------------- | 
|         |     28 // CSamplerPluginLoader::NewL | 
|         |     29 // | 
|         |     30 // EPOC two-phased constructor | 
|         |     31 // ---------------------------------------------------------------------------- | 
|         |     32 // | 
|         |     33 CSamplerPluginLoader* CSamplerPluginLoader::NewL() | 
|         |     34     { | 
|         |     35     CSamplerPluginLoader* self = new( ELeave ) CSamplerPluginLoader; | 
|         |     36     CleanupStack::PushL( self ); | 
|         |     37     self->ConstructL( ); | 
|         |     38     CleanupStack::Pop( self ); | 
|         |     39     return self; | 
|         |     40     } | 
|         |     41  | 
|         |     42  | 
|         |     43 // ---------------------------------------------------------------------------- | 
|         |     44 // CSamplerPluginLoader::CSamplerPluginLoader | 
|         |     45 // | 
|         |     46 // C++ default constructor can NOT contain any code, that | 
|         |     47 // might leave. | 
|         |     48 // ---------------------------------------------------------------------------- | 
|         |     49 // | 
|         |     50 CSamplerPluginLoader::CSamplerPluginLoader() : CActive( EPriorityStandard ) | 
|         |     51     { | 
|         |     52     LOGSTRING( "CSamplerPluginLoader()::CSamplerPluginLoader()" ); | 
|         |     53     } | 
|         |     54  | 
|         |     55  | 
|         |     56 // ---------------------------------------------------------------------------- | 
|         |     57 // CSamplerPluginLoader::ConstructL | 
|         |     58 // | 
|         |     59 // EPOC default constructor can leave. | 
|         |     60 // ---------------------------------------------------------------------------- | 
|         |     61 // | 
|         |     62 void CSamplerPluginLoader::ConstructL( ) | 
|         |     63     { | 
|         |     64     LOGSTRING( "CSamplerPluginLoader()::ConstructL()" ); | 
|         |     65  | 
|         |     66     // get list of implementations | 
|         |     67     CSamplerPluginInterface::ListAllImplementationsL( iImplInfoArray ); | 
|         |     68  | 
|         |     69     CActiveScheduler::Add( this ); | 
|         |     70     } | 
|         |     71  | 
|         |     72 // ---------------------------------------------------------------------------- | 
|         |     73 // CSamplerPluginLoader::~CSamplerPluginLoader | 
|         |     74 // | 
|         |     75 // Destructor | 
|         |     76 // ---------------------------------------------------------------------------- | 
|         |     77 // | 
|         |     78 CSamplerPluginLoader::~CSamplerPluginLoader() | 
|         |     79     { | 
|         |     80     LOGSTRING( "CSamplerPluginLoader()::~CSamplerPluginLoader()" ); | 
|         |     81  | 
|         |     82     AbortAsyncLoad(); | 
|         |     83  | 
|         |     84     Cancel(); | 
|         |     85      | 
|         |     86     // reset ECOM implementation info array | 
|         |     87     iImplInfoArray.ResetAndDestroy();   // This is needed | 
|         |     88     iImplInfoArray.Close(); | 
|         |     89     } | 
|         |     90  | 
|         |     91  | 
|         |     92 // ---------------------------------------------------------------------------- | 
|         |     93 // CSamplerPluginLoader::LoadAsync | 
|         |     94 // ---------------------------------------------------------------------------- | 
|         |     95 // | 
|         |     96 void CSamplerPluginLoader::LoadAsyncL(CArrayPtrFlat<CSamplerPluginInterface>* aPluginArray ) | 
|         |     97     { | 
|         |     98     iPluginArray = aPluginArray; | 
|         |     99  | 
|         |    100     // Reset iterator | 
|         |    101     iImplInfoArrayIterator = 0; | 
|         |    102  | 
|         |    103     LOGSTRING2( "CSamplerPluginLoader()::Implementation info count: %d", | 
|         |    104         iImplInfoArray.Count() ); | 
|         |    105  | 
|         |    106     NotifyProgress(); | 
|         |    107  | 
|         |    108     //Begin CActive asynchronous loop. | 
|         |    109     CompleteOwnRequest(); | 
|         |    110     } | 
|         |    111      | 
|         |    112  | 
|         |    113 // ---------------------------------------------------------------------------- | 
|         |    114 // CSamplerPluginLoader::LoadSyncL | 
|         |    115 // ---------------------------------------------------------------------------- | 
|         |    116 // | 
|         |    117 void CSamplerPluginLoader::LoadSyncL(CArrayPtrFlat<CSamplerPluginInterface>* aPluginArray) | 
|         |    118     { | 
|         |    119     // cancel first active object from loading samplers dynamically | 
|         |    120     Cancel(); | 
|         |    121     CSamplerPluginInterface* plugin = NULL; | 
|         |    122      | 
|         |    123     iPluginArray = aPluginArray; | 
|         |    124  | 
|         |    125     // Get a list of all implementations, even though we only want one specific | 
|         |    126     // one. There appears to be no way to otherwise extract a specific implementation | 
|         |    127     // info object :( | 
|         |    128     // Search for the implementation that matches aImplementationUid | 
|         |    129     const TInt impCount = iImplInfoArray.Count(); | 
|         |    130     for( TInt i=0; i<impCount; i++ ) | 
|         |    131         { | 
|         |    132         const CImplementationInformation* info = iImplInfoArray[ i ]; | 
|         |    133             { | 
|         |    134             TRAPD(ret, plugin = &CreatePluginInstanceL( *info ); ); | 
|         |    135             if( ret == KErrNone ) | 
|         |    136                 { | 
|         |    137                 // Plugin ownership is transfered to iPluginArray | 
|         |    138                 InsertPluginInOrderL( plugin, iPluginArray ); | 
|         |    139                 } | 
|         |    140             else | 
|         |    141                 { | 
|         |    142                 // Error note is displayed even if plugin is not loaded | 
|         |    143                 LOGSTRING2("CSamplerPluginLoader::LoadSyncL() - plugin load failed, error %d", ret); | 
|         |    144                 } | 
|         |    145             break; | 
|         |    146             } | 
|         |    147         } | 
|         |    148  | 
|         |    149     if  ( plugin == NULL ) | 
|         |    150         { | 
|         |    151         User::Leave( KErrNotFound ); | 
|         |    152         } | 
|         |    153     } | 
|         |    154  | 
|         |    155  | 
|         |    156 // ---------------------------------------------------------------------------- | 
|         |    157 // CSamplerPluginLoader::AbortAsyncLoad | 
|         |    158 // ---------------------------------------------------------------------------- | 
|         |    159 // | 
|         |    160 void CSamplerPluginLoader::AbortAsyncLoad() | 
|         |    161     { | 
|         |    162     LOGSTRING( "CSamplerPluginLoader()::AbortAsyncLoad()" ); | 
|         |    163     Cancel(); | 
|         |    164     } | 
|         |    165  | 
|         |    166  | 
|         |    167 // ---------------------------------------------------------------------------- | 
|         |    168 // CSamplerPluginLoader::RunL | 
|         |    169 // ---------------------------------------------------------------------------- | 
|         |    170 // | 
|         |    171 void CSamplerPluginLoader::RunL() | 
|         |    172     { | 
|         |    173     iRunLDebugCount++; | 
|         |    174     LoadNextPluginL(); | 
|         |    175  | 
|         |    176     // Check if there are still more plugins to be loaded: | 
|         |    177     if ( iImplInfoArrayIterator < iImplInfoArray.Count() ) | 
|         |    178         { | 
|         |    179         NotifyProgress(); | 
|         |    180         // Continue CActive asynchronous loop. | 
|         |    181         CompleteOwnRequest(); | 
|         |    182         } | 
|         |    183     else | 
|         |    184         { | 
|         |    185         // All plugins loaded: | 
|         |    186         LOGSTRING( "CSamplerPluginLoader()::Loading plugins finished." ); | 
|         |    187         NotifyFinished(); | 
|         |    188         } | 
|         |    189     } | 
|         |    190  | 
|         |    191  | 
|         |    192 // --------------------------------------------------------------------------- | 
|         |    193 // CScGenreItemConstructionConductor::CompleteOwnRequest | 
|         |    194 // | 
|         |    195 // Issue request complete notification. | 
|         |    196 // --------------------------------------------------------------------------- | 
|         |    197 void CSamplerPluginLoader::CompleteOwnRequest() | 
|         |    198     { | 
|         |    199     TRequestStatus* status = &iStatus; | 
|         |    200     User::RequestComplete( status, KErrNone ); | 
|         |    201     SetActive(); | 
|         |    202     } | 
|         |    203  | 
|         |    204  | 
|         |    205 // ---------------------------------------------------------------------------- | 
|         |    206 // CSamplerPluginLoader::RunError | 
|         |    207 // ---------------------------------------------------------------------------- | 
|         |    208 // | 
|         |    209 TInt CSamplerPluginLoader::RunError( TInt aError ) | 
|         |    210     { | 
|         |    211     // This method is called when a plugin loading fails. | 
|         |    212     // Always "fake" the return value so that ActiveSchedule | 
|         |    213     // keeps running and later plugins are continued to be loaded. | 
|         |    214     // Check if still plugins to be loaded: | 
|         |    215     LOGTEXT(_L("CSamplerPluginLoader::RunError() - error in loading plugin")); | 
|         |    216     if( iImplInfoArrayIterator < iImplInfoArray.Count() ) | 
|         |    217         { | 
|         |    218         NotifyProgress(); | 
|         |    219  | 
|         |    220         //Continue CActive asynchronous loop. | 
|         |    221         CompleteOwnRequest(); | 
|         |    222         } | 
|         |    223     else // All plugins loaded: | 
|         |    224         { | 
|         |    225         NotifyFinished(); | 
|         |    226         } | 
|         |    227  | 
|         |    228     if ( aError == KLeaveExit ) | 
|         |    229         { | 
|         |    230         return KLeaveExit; | 
|         |    231         } | 
|         |    232  | 
|         |    233     return KErrNone; | 
|         |    234     } | 
|         |    235  | 
|         |    236  | 
|         |    237 // ---------------------------------------------------------------------------- | 
|         |    238 // CSamplerPluginLoader::DoCancel | 
|         |    239 // ---------------------------------------------------------------------------- | 
|         |    240 // | 
|         |    241 void CSamplerPluginLoader::DoCancel() | 
|         |    242     { | 
|         |    243  | 
|         |    244     } | 
|         |    245  | 
|         |    246  | 
|         |    247 // ---------------------------------------------------------------------------- | 
|         |    248 // CSamplerPluginLoader::NotifyProgress | 
|         |    249 // ---------------------------------------------------------------------------- | 
|         |    250 // | 
|         |    251 void CSamplerPluginLoader::NotifyProgress() | 
|         |    252     { | 
|         |    253     if( iObserver ) | 
|         |    254         { | 
|         |    255         iObserver->HandlePluginLoaded( MSamplerPluginLoadObserver::ESamplerSuccess); | 
|         |    256         } | 
|         |    257     } | 
|         |    258  | 
|         |    259  | 
|         |    260 // ---------------------------------------------------------------------------- | 
|         |    261 // CSamplerPluginLoader::NotifyFinished | 
|         |    262 // ---------------------------------------------------------------------------- | 
|         |    263 // | 
|         |    264 void CSamplerPluginLoader::NotifyFinished() | 
|         |    265     { | 
|         |    266     if( iObserver ) | 
|         |    267         { | 
|         |    268         iObserver->HandlePluginLoaded( MSamplerPluginLoadObserver::ESamplerFinished ); | 
|         |    269         } | 
|         |    270     } | 
|         |    271  | 
|         |    272  | 
|         |    273 // ---------------------------------------------------------------------------- | 
|         |    274 // CSamplerPluginLoader::SetObserver | 
|         |    275 // ---------------------------------------------------------------------------- | 
|         |    276 // | 
|         |    277 void CSamplerPluginLoader::SetObserver(MSamplerPluginLoadObserver* aObserver) | 
|         |    278     { | 
|         |    279     LOGSTRING2("CSamplerPluginLoader()::Observer set:0x%X", aObserver); | 
|         |    280     iObserver = aObserver; | 
|         |    281     } | 
|         |    282  | 
|         |    283  | 
|         |    284 // ---------------------------------------------------------------------------- | 
|         |    285 // CSamplerPluginLoader::ParseToUid | 
|         |    286 // Parses a UID from descriptor of form '0xNNNNNNNN' where N is hexadecimal. | 
|         |    287 // | 
|         |    288 // ---------------------------------------------------------------------------- | 
|         |    289 // | 
|         |    290 TInt CSamplerPluginLoader::ParseToUid( const TDesC8& aSource, TUid& aTarget ) | 
|         |    291     { | 
|         |    292     // Remove "0x" from the descriptor if it exists | 
|         |    293     _LIT8(KHexPrefix, "0x"); | 
|         |    294  | 
|         |    295     TPtrC8 pSource( aSource ); | 
|         |    296     const TInt prefixPosition = pSource.Find( KHexPrefix ); | 
|         |    297     if  ( prefixPosition != KErrNotFound ) | 
|         |    298         { | 
|         |    299         pSource.Set( aSource.Mid( prefixPosition + KHexPrefix().Length() ) ); | 
|         |    300         } | 
|         |    301  | 
|         |    302     // Parse to integer | 
|         |    303     TLex8 lex( pSource ); | 
|         |    304     TUint integer = 0; | 
|         |    305  | 
|         |    306     // Parse using TRadix::EHex as radix: | 
|         |    307     const TInt err = lex.Val( integer, EHex ); | 
|         |    308     aTarget.iUid = integer; | 
|         |    309  | 
|         |    310     if( err != KErrNone ) | 
|         |    311         { | 
|         |    312         // If parsing parent UID failed, do not load plugin: | 
|         |    313         LOGSTRING2( | 
|         |    314             "CSamplerPluginLoader()::Parsing parent UID failed. Error code:%d", | 
|         |    315             err ); | 
|         |    316         } | 
|         |    317     return err; | 
|         |    318     } | 
|         |    319  | 
|         |    320  | 
|         |    321 // ---------------------------------------------------------------------------- | 
|         |    322 // CSamplerPluginLoader::ParseOrderNumber | 
|         |    323 // | 
|         |    324 // | 
|         |    325 // ---------------------------------------------------------------------------- | 
|         |    326 // | 
|         |    327 TInt CSamplerPluginLoader::ParseOrderNumber( const TDesC8& aSource, TInt& aOrderNumber ) | 
|         |    328     { | 
|         |    329     // Parse plugin's order number from opaque_data: | 
|         |    330     TLex8 lex( aSource ); | 
|         |    331     const TInt orderErr = lex.Val( aOrderNumber ); | 
|         |    332     return orderErr; | 
|         |    333     } | 
|         |    334  | 
|         |    335 // ---------------------------------------------------------------------------- | 
|         |    336 // CSamplerPluginLoader::LoadNextPluginL | 
|         |    337 // Iterate through iImplInfoArray. Load the plugin if it is eligible for | 
|         |    338 // loading. Loaded plugin is added to iPluginArray. Each time a plugin is | 
|         |    339 // loaded, iObserver is notified. | 
|         |    340 // | 
|         |    341 // ---------------------------------------------------------------------------- | 
|         |    342 // | 
|         |    343 void CSamplerPluginLoader::LoadNextPluginL() | 
|         |    344     { | 
|         |    345     // Iterate through iImplInfoArray. This loop continues between function | 
|         |    346     // calls. Therefore member variable iImplInfoArrayIterator is used as a | 
|         |    347     // counter. Loop will break when match is found and continues on next RunL. | 
|         |    348     for( ; iImplInfoArrayIterator < iImplInfoArray.Count();  ) | 
|         |    349         { | 
|         |    350         const CImplementationInformation* info = | 
|         |    351             iImplInfoArray[ iImplInfoArrayIterator ]; | 
|         |    352  | 
|         |    353         iImplInfoArrayIterator++; | 
|         |    354  | 
|         |    355 //        PrintInfoDebug( *info, iImplInfoArrayIterator, iImplInfoArray.Count() ); | 
|         |    356         LOGSTRING3("CSamplerPluginLoader() - iImplInfoArrayIterator %d, iImplInfoArray.Count() %d",  | 
|         |    357                 iImplInfoArrayIterator,  | 
|         |    358                 iImplInfoArray.Count() ); | 
|         |    359          | 
|         |    360         // If this plugin is OK -> load it: | 
|         |    361         LOGSTRING2( "CSamplerPluginLoader() %S eligible for parent", | 
|         |    362                 &info->DisplayName()); | 
|         |    363         CSamplerPluginInterface* plugin = NULL; | 
|         |    364         TInt error(KErrNone); | 
|         |    365         // Create plugin. Trap leave for debugging purposes. | 
|         |    366         TRAP( error, plugin = &CreatePluginInstanceL( *info ); ); | 
|         |    367  | 
|         |    368         if( error == KErrNone ) | 
|         |    369             { | 
|         |    370             // Plugin ownership is transfered to iPluginArray | 
|         |    371             InsertPluginInOrderL( plugin, iPluginArray ); | 
|         |    372             } | 
|         |    373         else | 
|         |    374             { | 
|         |    375             // Error note is displayed even if plugin is not loaded | 
|         |    376             LOGSTRING2("CSamplerPluginLoader::LoadNextPluginL() - plugin load failed, error %d", error); | 
|         |    377             } | 
|         |    378         // Wait for next round | 
|         |    379         break; | 
|         |    380         } | 
|         |    381     } | 
|         |    382   | 
|         |    383 // ---------------------------------------------------------------------------- | 
|         |    384 // CSamplerPluginLoader::CreatePluginInstanceL | 
|         |    385 // | 
|         |    386 // | 
|         |    387 // ---------------------------------------------------------------------------- | 
|         |    388 // | 
|         |    389  | 
|         |    390 CSamplerPluginInterface& CSamplerPluginLoader::CreatePluginInstanceL( | 
|         |    391     const CImplementationInformation& aImpInfo ) | 
|         |    392     { | 
|         |    393     // Now we can load the plugin | 
|         |    394     const TUid implUid = aImpInfo.ImplementationUid(); | 
|         |    395  | 
|         |    396     CSamplerPluginInterface* plugin = CSamplerPluginInterface::NewL( implUid , (TAny*)&aImpInfo.DisplayName() ); | 
|         |    397     CleanupStack::PushL ( plugin ); | 
|         |    398  | 
|         |    399     // Parse plugin's order number from opaque_data: | 
|         |    400     TInt orderNumber(0); | 
|         |    401     const TInt orderErr = ParseOrderNumber( aImpInfo.OpaqueData(), orderNumber ); | 
|         |    402  | 
|         |    403     if  ( orderErr == KErrNone && orderNumber >= 0 ) | 
|         |    404         { | 
|         |    405         	plugin->iOrder = orderNumber; | 
|         |    406         } | 
|         |    407     CleanupStack::Pop( plugin ); // CSamplerController is now responsible for this memory. | 
|         |    408  | 
|         |    409     return *plugin; | 
|         |    410     } | 
|         |    411  | 
|         |    412 // ---------------------------------------------------------------------------- | 
|         |    413 // CSamplerPluginLoader::SortPluginsL | 
|         |    414 // | 
|         |    415 // ---------------------------------------------------------------------------- | 
|         |    416 // | 
|         |    417 void CSamplerPluginLoader::SortPluginsL( | 
|         |    418         CArrayPtrFlat<CSamplerPluginInterface>* aPlugins ) | 
|         |    419     { | 
|         |    420     RPointerArray<CSamplerPluginInterface> plugins; | 
|         |    421     TLinearOrder<CSamplerPluginInterface> order( CSamplerPluginLoader::Compare ); | 
|         |    422  | 
|         |    423     // Insertion will also order | 
|         |    424     for( TInt i = 0; i < aPlugins->Count(); i++ ) | 
|         |    425         { | 
|         |    426         plugins.InsertInOrderL( (*aPlugins)[i], order ); | 
|         |    427         } | 
|         |    428  | 
|         |    429     // Replace original array content with sorted items | 
|         |    430     aPlugins->Reset(); | 
|         |    431     for( TInt i = 0; i < plugins.Count(); i++ ) | 
|         |    432         { | 
|         |    433         aPlugins->AppendL( plugins[i] ); | 
|         |    434         } | 
|         |    435     } | 
|         |    436  | 
|         |    437  | 
|         |    438 // ---------------------------------------------------------------------------- | 
|         |    439 // CSamplerPluginLoader::Compare | 
|         |    440 // | 
|         |    441 // Compare two plugins. | 
|         |    442 // Precedence: | 
|         |    443 // [1. plugin provider category] | 
|         |    444 // 2. plugin order number | 
|         |    445 // 3. plugin caption | 
|         |    446 // Plugin provider gategory is currently disabled (not supported yet). | 
|         |    447 // ---------------------------------------------------------------------------- | 
|         |    448 // | 
|         |    449 TInt CSamplerPluginLoader::Compare( const CSamplerPluginInterface& aFirst, | 
|         |    450                                const CSamplerPluginInterface& aSecond ) | 
|         |    451     { | 
|         |    452     // compare indexes and sort | 
|         |    453     return CompareIndex( aFirst, aSecond ); | 
|         |    454     } | 
|         |    455  | 
|         |    456  | 
|         |    457 // ---------------------------------------------------------------------------- | 
|         |    458 // CSamplerPluginLoader::InsertPluginInOrderL | 
|         |    459 // | 
|         |    460 // ---------------------------------------------------------------------------- | 
|         |    461 // | 
|         |    462 void CSamplerPluginLoader::InsertPluginInOrderL( | 
|         |    463     CSamplerPluginInterface* aPlugin, | 
|         |    464     CArrayPtrFlat<CSamplerPluginInterface>* aPlugins ) | 
|         |    465     { | 
|         |    466     CSamplerPluginInterface* comparedPlugin; | 
|         |    467     TInt comparison = 0; | 
|         |    468     TBool inserted = EFalse; | 
|         |    469  | 
|         |    470     for( TInt i = 0; i < aPlugins->Count(); i++ ) | 
|         |    471         { | 
|         |    472         comparedPlugin = (*aPlugins)[i]; | 
|         |    473         // Optimization: do not call time consuming Compare() multiple times! | 
|         |    474         comparison = Compare( *aPlugin, *comparedPlugin ); | 
|         |    475         if( comparison < 0 ) | 
|         |    476             { | 
|         |    477             aPlugins->InsertL( i, aPlugin ); | 
|         |    478             inserted = ETrue; | 
|         |    479             break; | 
|         |    480             } | 
|         |    481         else if( comparison == 0 ) | 
|         |    482             { | 
|         |    483             aPlugins->InsertL( i+1, aPlugin ); | 
|         |    484             inserted = ETrue; | 
|         |    485             break; | 
|         |    486             } | 
|         |    487         } | 
|         |    488     // Plugin was not before any other plugin - make sure it's appended | 
|         |    489     if( !inserted ) | 
|         |    490         { | 
|         |    491         aPlugins->AppendL( aPlugin ); | 
|         |    492         } | 
|         |    493  | 
|         |    494     #ifdef _GS_PLUGINLOADER_SORTING_TRACES | 
|         |    495         PrintOrderTraces( aPlugins ); | 
|         |    496     #endif // _GS_PLUGINLOADER_SORTING_TRACES | 
|         |    497  | 
|         |    498     } | 
|         |    499  | 
|         |    500 // ---------------------------------------------------------------------------- | 
|         |    501 // CSamplerPluginLoader::CompareIndex | 
|         |    502 // ---------------------------------------------------------------------------- | 
|         |    503 // | 
|         |    504 TInt CSamplerPluginLoader::CompareIndex( const CSamplerPluginInterface& aFirst, | 
|         |    505                                     const CSamplerPluginInterface& aSecond ) | 
|         |    506     { | 
|         |    507     TInt comparison = KSamplerComparisonEqual; | 
|         |    508     // The plugin having index is before the one not having one | 
|         |    509  | 
|         |    510     if( aFirst.iOrder  == KSamplerPluginNotIndexed && | 
|         |    511         aSecond.iOrder == KSamplerPluginNotIndexed ) | 
|         |    512         { | 
|         |    513         // Neither have index -> equal | 
|         |    514         comparison = KSamplerComparisonEqual; | 
|         |    515         } | 
|         |    516     else if( aFirst.iOrder == KSamplerPluginNotIndexed ) | 
|         |    517         { | 
|         |    518         // The plugin having index is before the one not having one | 
|         |    519         comparison = KSamplerComparisonAfter; | 
|         |    520         } | 
|         |    521     else if( aSecond.iOrder == KSamplerPluginNotIndexed ) | 
|         |    522         { | 
|         |    523         // The plugin having index is before the one not having one | 
|         |    524         comparison = KSamplerComparisonBefore; | 
|         |    525         } | 
|         |    526     else if( aFirst.iOrder < aSecond.iOrder ) | 
|         |    527         { | 
|         |    528         // Compare actual index values | 
|         |    529         comparison = KSamplerComparisonBefore; | 
|         |    530         } | 
|         |    531     else if( aFirst.iOrder > aSecond.iOrder ) | 
|         |    532         { | 
|         |    533         // Compare actual index values | 
|         |    534         comparison = KSamplerComparisonAfter; | 
|         |    535         } | 
|         |    536     return comparison; | 
|         |    537     } | 
|         |    538  | 
|         |    539 //  End of File |