mmappcomponents/playlistengine/src/mpxplaylistengine.cpp
changeset 0 a2952bb97e68
child 27 cbb1bfb7ebfb
equal deleted inserted replaced
-1:000000000000 0:a2952bb97e68
       
     1 /*
       
     2 * Copyright (c) 2006 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:  playlist engine
       
    15 *
       
    16 *  CMPXPlaylistEngine contains a CMPXPlaylistPluginHandler and a task queue.
       
    17 *  CMPXPlaylistEngine uses CMPXPlaylistPluginHandler to select an appropriate
       
    18 *  playlist plugin to handle the client's requests. It's also used for querying
       
    19 *  about the currently loaded playlist plugin.
       
    20 *
       
    21 *  The task queue is used to manage async requests submitted by the client.
       
    22 *  When an InternalizePlaylistL or ExternalizePlaylistL request is received,
       
    23 *  it's added to the task queue. When a task in the queue is ready for
       
    24 *  execution, ExecuteTask is called. To process the task, CMPXPlaylistEngine
       
    25 *  will select an appropriate plugin; once one is found, the request is
       
    26 *  handed over to the plugin and CMPXPlaylistEngine becomes active. Before
       
    27 *  the plugin completes the request, CMPXPlaylistEngine is notified of the
       
    28 *  results through MMPXPlaylistPluginObserver interface; CMPXPlaylistEngine
       
    29 *  passes the results to its client through MMPXPlaylistEngineObserver
       
    30 *  interface. Once CMPXPlaylistEngine's client completes the handling of the
       
    31 *  results, plugin completes the request and CMPXPlaylistEngine::RunL
       
    32 *  is called to complete one task processing cycle. CMPXPlaylistEngine is
       
    33 *  ready to process the next task if any at the completion of RunL.
       
    34 *
       
    35 *  DESIGN DECISION:
       
    36 *  Only one task queue is used instead of one per plugin because this is
       
    37 *  running on the client thread. No processing time gained for having
       
    38 *  separate task queues.
       
    39 *
       
    40 *
       
    41 */
       
    42 
       
    43 #include <s32mem.h>
       
    44 #include <bamdesca.h>
       
    45 #include <badesca.h>
       
    46 #include <bautils.h>
       
    47 #include <uri16.h>
       
    48 #include <apmrec.h>
       
    49 #include <syslangutil.h>
       
    50 #include <languages.hrh>
       
    51 #include <data_caging_path_literals.hrh>
       
    52 #include <mpxplaylisttopcharacterset.rsg>
       
    53 #include <mpxlog.h>
       
    54 #include <mpxtaskqueue.h>
       
    55 #include <mpxmedia.h>
       
    56 #include <mpxmediaarray.h>
       
    57 #include <mpxmediageneraldefs.h>
       
    58 #include <mpxmediacontainerdefs.h>
       
    59 #include "mpxplaylistenginedefs.hrh"
       
    60 #include "mpxplaylistplugin.h"
       
    61 #include "mpxplaylistengine.h"
       
    62 #include "mpxplaylistrecognizer.h"
       
    63 
       
    64 // ============================ CONSTANTS =====================================
       
    65 const TInt KMPXBufExpandSize = 0x40;
       
    66 const TInt KMPXArrayGranularity = 12;
       
    67 _LIT( KMPXPlaylistEnginePanic, "CMPXPlaylistEngine");
       
    68 _LIT(KMPXPlaylistCharacterSetRscFile, "mpxplaylisttopcharacterset.rsc");
       
    69 _LIT( KMPXPlaylistExtension, ".m3u" );
       
    70 
       
    71 // ============================ MEMBER FUNCTIONS ==============================
       
    72 // ----------------------------------------------------------------------------
       
    73 // Constructor.
       
    74 // ----------------------------------------------------------------------------
       
    75 //
       
    76 CMPXPlaylistEngine::CMPXPlaylistEngine(
       
    77     MMPXPlaylistEngineObserver& aObserver)
       
    78 :   CActive(EPriorityStandard),
       
    79     iObserver(aObserver)
       
    80     {
       
    81     CActiveScheduler::Add(this);
       
    82     }
       
    83 
       
    84 // ----------------------------------------------------------------------------
       
    85 // 2nd phase constructor.
       
    86 // ----------------------------------------------------------------------------
       
    87 //
       
    88 void CMPXPlaylistEngine::ConstructL()
       
    89     {
       
    90     User::LeaveIfError(iFs.Connect());
       
    91      iCharacterSet = CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL(iFs);
       
    92      iTopCharacterSet =
       
    93          new (ELeave)CArrayFixFlat<CCnvCharacterSetConverter::SCharacterSet>(KMPXArrayGranularity);
       
    94      GenerateTopCharacterSetsL();
       
    95 
       
    96     iTaskQueue = CMPXActiveTaskQueue::NewL();
       
    97     iPluginHandler = CMPXPlaylistPluginHandler::NewL(
       
    98                         *this, *this, iFs, *iTopCharacterSet, *iCharacterSet);
       
    99     }
       
   100 
       
   101 // ----------------------------------------------------------------------------
       
   102 // Two-phased constructor.
       
   103 // ----------------------------------------------------------------------------
       
   104 //
       
   105 EXPORT_C CMPXPlaylistEngine* CMPXPlaylistEngine::NewL(
       
   106     MMPXPlaylistEngineObserver& aObserver)
       
   107     {
       
   108     CMPXPlaylistEngine* self=new(ELeave)CMPXPlaylistEngine(aObserver);
       
   109     CleanupStack::PushL(self);
       
   110     self->ConstructL();
       
   111     CleanupStack::Pop(self);
       
   112     return self;
       
   113     }
       
   114 
       
   115 // ----------------------------------------------------------------------------
       
   116 // Destructor.
       
   117 // ----------------------------------------------------------------------------
       
   118 //
       
   119 EXPORT_C CMPXPlaylistEngine::~CMPXPlaylistEngine()
       
   120     {
       
   121     Cancel();
       
   122     Cleanup();
       
   123 
       
   124     iFs.Close();
       
   125     delete iTaskQueue;
       
   126     delete iPluginHandler;
       
   127     delete iCharacterSet;
       
   128      delete iTopCharacterSet;
       
   129      iRscFile.Close();
       
   130     }
       
   131 
       
   132 // =========================== EXTERNAL FUNCTIONS =============================
       
   133 // ----------------------------------------------------------------------------
       
   134 // Return a handle to playlist plugin handler
       
   135 // ----------------------------------------------------------------------------
       
   136 EXPORT_C CMPXPlaylistPluginHandler& CMPXPlaylistEngine::PlaylistPluginHandler()
       
   137     {
       
   138     ASSERT( iPluginHandler );
       
   139     return *iPluginHandler;
       
   140     }
       
   141 
       
   142 // ----------------------------------------------------------------------------
       
   143 // Determines whether the given media is a playlist
       
   144 // Currently, Music Player only supports m3u playlist.
       
   145 // ----------------------------------------------------------------------------
       
   146 //
       
   147 EXPORT_C TBool CMPXPlaylistEngine::IsPlaylistL( const TDesC& aUri )
       
   148     {
       
   149     // Check if the file extension is ".m3u".
       
   150     TBool isPlaylist = EFalse;
       
   151     TParsePtrC parse( aUri );
       
   152     if ( !parse.Ext().CompareF( KMPXPlaylistExtension ) )
       
   153         {
       
   154         isPlaylist = ETrue;
       
   155         }
       
   156 
       
   157     return isPlaylist;
       
   158     }
       
   159 
       
   160 // ----------------------------------------------------------------------------
       
   161 // Internalize a playlist (async)
       
   162 //
       
   163 // Add the request to the task queue
       
   164 // ----------------------------------------------------------------------------
       
   165 EXPORT_C void CMPXPlaylistEngine::InternalizePlaylistL(const TDesC& aPlaylistUri)
       
   166     {
       
   167     MPX_DEBUG1("CMPXPlaylistEngine::InternalizePlaylistL");
       
   168 
       
   169     //
       
   170     // leave if the given file does not exist
       
   171     //
       
   172     if (!BaflUtils::FileExists(iFs, aPlaylistUri))
       
   173         {
       
   174         User::Leave( KErrNotFound );
       
   175         }
       
   176 
       
   177     //
       
   178     // externalize parameters
       
   179     //
       
   180     CBufBase* taskParam = CBufFlat::NewL( KMPXBufExpandSize );
       
   181     CleanupStack::PushL( taskParam );
       
   182     taskParam->ResizeL( KMPXBufExpandSize );
       
   183 
       
   184     RBufWriteStream writeStream( *taskParam );
       
   185     CleanupClosePushL( writeStream );
       
   186 
       
   187     // externalize playlist URI
       
   188     writeStream.WriteInt32L( aPlaylistUri.Length() );
       
   189     writeStream << aPlaylistUri;
       
   190 
       
   191     writeStream.CommitL();
       
   192     taskParam->Compress();
       
   193 
       
   194     //
       
   195     // add request to the task queue
       
   196     //
       
   197     iTaskQueue->AddTaskL( EInternalizePlaylist,
       
   198                           NULL,        // callback when task completed
       
   199                           this,        // task queue observer
       
   200                           0,           // Integer parameter, not used
       
   201                           taskParam ); // task queue assumes ownership of taskParam
       
   202 
       
   203     CleanupStack::PopAndDestroy( &writeStream );
       
   204     CleanupStack::Pop( taskParam ); // taskParam
       
   205     }
       
   206 
       
   207 // ----------------------------------------------------------------------------
       
   208 // Internalize a playlist (async)
       
   209 // ----------------------------------------------------------------------------
       
   210 EXPORT_C void CMPXPlaylistEngine::InternalizePlaylistL(const RFile& aPlaylistFileHandle)
       
   211     {
       
   212     MPX_DEBUG1("CMPXPlaylistEngine::InternalizePlaylistL");
       
   213 
       
   214     if ( !aPlaylistFileHandle.SubSessionHandle() )
       
   215         {
       
   216         User::Leave(KErrArgument);
       
   217         }
       
   218 
       
   219     TFileName fullName;
       
   220     aPlaylistFileHandle.FullName( fullName );
       
   221 
       
   222     InternalizePlaylistL( fullName );
       
   223     }
       
   224 
       
   225 // ----------------------------------------------------------------------------
       
   226 // Externalize a playlist (async)
       
   227 //
       
   228 // Add the request to the task queue
       
   229 // ----------------------------------------------------------------------------
       
   230 EXPORT_C void CMPXPlaylistEngine::ExternalizePlaylistL(
       
   231     const CMPXMedia& aPlaylist,
       
   232     const TDesC& aFilePath)
       
   233     {
       
   234     MPX_DEBUG1("CMPXPlaylistEngine::ExternalizePlaylistL");
       
   235 
       
   236     //
       
   237     // leave if the given playlist doesn't contain the following attributes
       
   238     //
       
   239     if (!aPlaylist.IsSupported(KMPXMediaGeneralTitle) ||
       
   240         !aPlaylist.IsSupported(KMPXMediaGeneralType) ||
       
   241         !aPlaylist.IsSupported(KMPXMediaGeneralCategory) ||
       
   242         !aPlaylist.IsSupported(KMPXMediaArrayContents) ||
       
   243         !aPlaylist.IsSupported(KMPXMediaArrayCount))
       
   244         {
       
   245         User::Leave( KErrArgument );
       
   246         }
       
   247 
       
   248     //
       
   249     // leave if the given media isn't a playlist (i.e. type must be EMPXItem and category
       
   250     // must be EMPXPlaylist
       
   251     //
       
   252     TMPXGeneralType mediaType =
       
   253          aPlaylist.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
       
   254 
       
   255     TMPXGeneralCategory mediaCategory =
       
   256          aPlaylist.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
   257 
       
   258     if ( mediaType != EMPXItem ||
       
   259          mediaCategory != EMPXPlaylist )
       
   260         {
       
   261         User::Leave( KErrArgument );
       
   262         }
       
   263 
       
   264     //
       
   265     // leave if the given file path does not exist
       
   266     //
       
   267     if (!BaflUtils::PathExists(iFs, aFilePath))
       
   268         {
       
   269         User::Leave( KErrPathNotFound );
       
   270         }
       
   271 
       
   272     // check if a plugin has been selected. the client
       
   273     // is required to select a plugin before issuing
       
   274     // this request
       
   275     if ( !iPluginHandler->PluginFound() )
       
   276         {
       
   277         User::Leave( KErrNotFound );
       
   278         }
       
   279 
       
   280     //
       
   281     // externalize parameters
       
   282     //
       
   283     CBufBase* taskParam = CBufFlat::NewL( KMPXBufExpandSize );
       
   284     CleanupStack::PushL( taskParam );
       
   285     taskParam->ResizeL( KMPXBufExpandSize );
       
   286 
       
   287     RBufWriteStream writeStream( *taskParam );
       
   288     CleanupClosePushL( writeStream );
       
   289 
       
   290     // externalize playlist
       
   291     writeStream << aPlaylist;
       
   292 
       
   293     // externalize file path
       
   294     writeStream.WriteInt32L( aFilePath.Length() );
       
   295     writeStream << aFilePath;
       
   296 
       
   297     // externalize plugin Uid
       
   298     writeStream.WriteInt32L( iPluginHandler->PluginUid().iUid );
       
   299 
       
   300     writeStream.CommitL();
       
   301     taskParam->Compress();
       
   302 
       
   303     //
       
   304     // add request to the task queue
       
   305     //
       
   306     CMPXMedia* playlist = CMPXMedia::NewL(aPlaylist);
       
   307     CleanupStack::PushL(playlist);
       
   308 
       
   309     iTaskQueue->AddTaskL( EExternalizePlaylist,
       
   310                           NULL,        // callback when task completed
       
   311                           this,        // task queue observer
       
   312                           0,           // Integer parameter, not used
       
   313                           taskParam,   // task queue assumes ownership
       
   314                           NULL,
       
   315                           playlist );  // keep media alive. ownership transferred
       
   316 
       
   317     CleanupStack::Pop( playlist );
       
   318     CleanupStack::PopAndDestroy( &writeStream );
       
   319     CleanupStack::Pop( taskParam ); // taskParam
       
   320     }
       
   321 
       
   322 // ----------------------------------------------------------------------------
       
   323 // Cancel Requests
       
   324 // ----------------------------------------------------------------------------
       
   325 EXPORT_C void CMPXPlaylistEngine::CancelRequests()
       
   326     {
       
   327     MPX_DEBUG1("CMPXPlaylistEngine::CancelRequests");
       
   328     Cancel();
       
   329     iTaskQueue->CancelRequests();
       
   330     }
       
   331 
       
   332 // =========================== CALLBACK FUNCTIONS =============================
       
   333 // ----------------------------------------------------------------------------
       
   334 // Handles plugin callback for InternalizePlaylistL request
       
   335 // ----------------------------------------------------------------------------
       
   336 void CMPXPlaylistEngine::HandlePlaylistL(
       
   337     CMPXMedia* aPlaylist,
       
   338     const TInt aError,
       
   339     const TBool aCompleted)
       
   340     {
       
   341     MPX_DEBUG1("CMPXPlaylistEngine::HandlePlaylistL");
       
   342 
       
   343     // notify playlist engine observer
       
   344     iObserver.HandlePlaylistL( aPlaylist, aError, aCompleted );
       
   345     }
       
   346 
       
   347 // ----------------------------------------------------------------------------
       
   348 // Handle plugin callback for ExternalizePlaylistL request
       
   349 // ----------------------------------------------------------------------------
       
   350 void CMPXPlaylistEngine::HandlePlaylistL(
       
   351     const TDesC& aPlaylistUri,
       
   352     const TInt aError)
       
   353     {
       
   354     MPX_DEBUG1("CMPXPlaylistEngine::HandlePlaylistL");
       
   355 
       
   356     // notify playlist engine observer
       
   357     iObserver.HandlePlaylistL( aPlaylistUri, aError );
       
   358     }
       
   359 
       
   360 // =========================== INTERNAL FUNCTIONS =============================
       
   361 // ----------------------------------------------------------------------------
       
   362 // Handles request completion event
       
   363 // ----------------------------------------------------------------------------
       
   364 //
       
   365 void CMPXPlaylistEngine::RunL()
       
   366     {
       
   367     MPX_DEBUG2("CMPXPlaylistEngine::RunL - status %d", iStatus.Int());
       
   368 
       
   369     // clean up data set during processing of the current task
       
   370     Cleanup();
       
   371 
       
   372     // we are done with the current request and ready for the next one if there is
       
   373     // any
       
   374     iTaskQueue->CompleteTask();
       
   375     }
       
   376 
       
   377 // ----------------------------------------------------------------------------
       
   378 // Cancellation of an outstanding request.
       
   379 // ----------------------------------------------------------------------------
       
   380 //
       
   381 void CMPXPlaylistEngine::DoCancel()
       
   382     {
       
   383     if ( iPluginHandler->PluginFound() )
       
   384         {
       
   385         iPluginHandler->Plugin()->Cancel();
       
   386         }
       
   387     Cleanup();
       
   388     iTaskQueue->CompleteTask();
       
   389     }
       
   390 
       
   391 // ----------------------------------------------------------------------------
       
   392 // Execute an async task
       
   393 // ----------------------------------------------------------------------------
       
   394 //
       
   395 void CMPXPlaylistEngine::ExecuteTask(
       
   396     TInt      aTask,
       
   397     TInt      /*aParamData*/,
       
   398     TAny*     /*aPtrData*/,
       
   399     const CBufBase& aBuf,
       
   400     TAny*     /*aCallback*/,
       
   401     CBase* /*aCObject1*/,
       
   402     CBase* /*aCObject2*/)
       
   403     {
       
   404     TRAPD(err, ExecuteTaskL(aTask, aBuf));
       
   405     if (err != KErrNone)
       
   406         {
       
   407         HandleExecuteTaskError(aTask, err);
       
   408         }
       
   409     }
       
   410 
       
   411 // ----------------------------------------------------------------------------
       
   412 // CMPXPlaylistEngine::HandleTaskError
       
   413 // ----------------------------------------------------------------------------
       
   414 //
       
   415 void CMPXPlaylistEngine::HandleTaskError(
       
   416     TInt /* aTask */,
       
   417     TAny* /*aPtrData*/,
       
   418     TAny* /*aCallback*/,
       
   419     TInt /* aError */)
       
   420     {
       
   421     // do nothing
       
   422     }
       
   423 
       
   424 // ----------------------------------------------------------------------------
       
   425 // CMPXPlaylistEngine::HandlePluginHandlerEvent
       
   426 // ----------------------------------------------------------------------------
       
   427 //
       
   428 void CMPXPlaylistEngine::HandlePluginHandlerEvent(
       
   429     TPluginHandlerEvents /* aEvent */,
       
   430     const TUid& /* aPluginUid */,
       
   431     TBool /* aLoaded */,
       
   432     TInt /* aData */)
       
   433     {
       
   434     // Playlist plugins are stateless and they are resolved for every call.
       
   435     // There is no need to cancel the existing queued requests in case the
       
   436     // plugin is updated as the new version of the plugin is expected to handle
       
   437     // these calls the same as the previous version did.
       
   438     //
       
   439     // In case the plugin is removed it is expected that all queued ResolvePluginL
       
   440     // calls will leave with KErrNotSupported, which will be sent to the caller.
       
   441     }
       
   442 
       
   443 // ----------------------------------------------------------------------------
       
   444 // Execute an async task. Leaves when an error is encountered.
       
   445 // ----------------------------------------------------------------------------
       
   446 //
       
   447 void CMPXPlaylistEngine::ExecuteTaskL(TInt aTask, const CBufBase& aBuf)
       
   448     {
       
   449     __ASSERT_ALWAYS( !IsActive(), User::Panic(KMPXPlaylistEnginePanic, KErrInUse) );
       
   450 
       
   451     RBufReadStream readStream( aBuf );
       
   452     CleanupClosePushL( readStream );
       
   453 
       
   454     switch( aTask )
       
   455         {
       
   456         case EInternalizePlaylist:
       
   457             {
       
   458             // internalize playlist parameter
       
   459             iPlaylistUri = HBufC::NewL( readStream, readStream.ReadInt32L() );
       
   460 
       
   461             // automatically select a plugin that is capable of handling
       
   462             // the specified media file. SelectPlaylistPluginL leaves
       
   463             // with KErrNotSupported when an appropriate plugin cannot
       
   464             // be found
       
   465             iPluginHandler->SelectPlaylistPluginL( *iPlaylistUri, KNullDesC8 );
       
   466 
       
   467             // an appropriate plugin is found, issue the request to the
       
   468             // selected plugin
       
   469             iPluginHandler->Plugin()->InternalizePlaylistL( iStatus, *iPlaylistUri );
       
   470             }
       
   471             break;
       
   472 
       
   473         case EExternalizePlaylist:
       
   474             {
       
   475             // internalize playlist
       
   476             iPlaylist = CMPXMedia::NewL();
       
   477             readStream >> *iPlaylist;
       
   478 
       
   479             // internalize file path
       
   480             iFilePath = HBufC::NewL( readStream, readStream.ReadInt32L() );
       
   481 
       
   482             // internalize plugin Uid
       
   483             TUid pluginUid = TUid::Uid( readStream.ReadInt32L() );
       
   484 
       
   485             //
       
   486             // select the specified plugin. When the specified plugin
       
   487             // cannot be found, SelectPlaylistPluginL will leave with
       
   488             // KErrNotSupported error code.
       
   489             //
       
   490             // Possible scenario:
       
   491             // The specified plugin is available when the client made
       
   492             // the selection before issuing the request, but the plugin
       
   493             // has since been uninstalled when we are ready to process
       
   494             // this request.
       
   495             //
       
   496             iPluginHandler->SelectPlaylistPluginL( pluginUid );
       
   497 
       
   498             // found the specified plugin, issue the request
       
   499             iPluginHandler->Plugin()->ExternalizePlaylistL(
       
   500                     iStatus, *iPlaylist, *iFilePath );
       
   501             }
       
   502             break;
       
   503 
       
   504         //
       
   505         // command not supported
       
   506         //
       
   507         default:
       
   508             {
       
   509             ASSERT(0);
       
   510             break;
       
   511             }
       
   512         }
       
   513 
       
   514     CleanupStack::PopAndDestroy( &readStream ); // readStream
       
   515 
       
   516     SetActive();
       
   517     }
       
   518 
       
   519 // ----------------------------------------------------------------------------
       
   520 // Handles a leave occurring in the request completion event handler ExecuteTaskL
       
   521 // ----------------------------------------------------------------------------
       
   522 //
       
   523 void CMPXPlaylistEngine::HandleExecuteTaskError(TInt aTask, TInt aError)
       
   524     {
       
   525     TRAP_IGNORE(HandleExecuteTaskErrorL(aTask, aError));
       
   526 
       
   527     // clean up data set during processing of the current task
       
   528     Cleanup();
       
   529 
       
   530     // although an error has occured while processing the current task, we are
       
   531     // done with the current request and ready for the next one if there is
       
   532     // any
       
   533     iTaskQueue->CompleteTask();
       
   534     }
       
   535 
       
   536 // ----------------------------------------------------------------------------
       
   537 // Handles a leave occurring in the request completion event handler ExecuteTaskL
       
   538 // ----------------------------------------------------------------------------
       
   539 //
       
   540 void CMPXPlaylistEngine::HandleExecuteTaskErrorL(TInt aTask, TInt aError)
       
   541     {
       
   542     MPX_DEBUG3("CMPXPlaylistEngine::HandleExecuteTaskErrorL(task %d, error %d)", aTask, aError);
       
   543 
       
   544     //
       
   545     // notify client
       
   546     //
       
   547     switch (aTask)
       
   548         {
       
   549         case EInternalizePlaylist:
       
   550             {
       
   551             iObserver.HandlePlaylistL( NULL, aError, ETrue );
       
   552             }
       
   553             break;
       
   554 
       
   555         case EExternalizePlaylist:
       
   556             {
       
   557             const TDesC& playlist =
       
   558                 iPlaylist? iPlaylist->ValueText(KMPXMediaGeneralTitle) : KNullDesC;
       
   559 
       
   560             iObserver.HandlePlaylistL( playlist, aError );
       
   561             }
       
   562             break;
       
   563 
       
   564         default:
       
   565             {
       
   566             ASSERT(0);
       
   567             break;
       
   568             }
       
   569         }
       
   570     }
       
   571 
       
   572 // ----------------------------------------------------------------------------
       
   573 // cleanup
       
   574 // ----------------------------------------------------------------------------
       
   575 //
       
   576 void CMPXPlaylistEngine::Cleanup()
       
   577     {
       
   578     delete iPlaylistUri;
       
   579     iPlaylistUri = NULL;
       
   580 
       
   581     delete iFilePath;
       
   582     iFilePath = NULL;
       
   583 
       
   584     delete iPlaylist;
       
   585     iPlaylist = NULL;
       
   586     }
       
   587 
       
   588 // -----------------------------------------------------------------------------
       
   589 // CMPXPlaylistEngine::GenerateTopCharacterSets()
       
   590 // -----------------------------------------------------------------------------
       
   591 //
       
   592 void CMPXPlaylistEngine::GenerateTopCharacterSetsL()
       
   593      {
       
   594      CArrayFixFlat<TInt>* installedLanguages = NULL;
       
   595      SysLangUtil::GetInstalledLanguages(installedLanguages);
       
   596      CleanupStack::PushL(installedLanguages);
       
   597 
       
   598 
       
   599      TParse* fp = new(ELeave) TParse();
       
   600      fp->Set(KMPXPlaylistCharacterSetRscFile, &KDC_RESOURCE_FILES_DIR, NULL);
       
   601      CleanupStack::PushL(fp);
       
   602 
       
   603      TFileName resourceFile = fp->FullName();
       
   604      User::LeaveIfError( MPXUser::CompleteWithDllPath( resourceFile ) );
       
   605 
       
   606      // Open the resource file
       
   607      TRAPD(err, iRscFile.OpenL(iFs, resourceFile));
       
   608      // if there is no resource file, then there is no top character set list
       
   609      if (err)
       
   610          {
       
   611           CleanupStack::PopAndDestroy(2, installedLanguages);
       
   612           return;
       
   613          }
       
   614 
       
   615      for (TInt i=0; i < installedLanguages->Count(); i++)
       
   616           {
       
   617           SelectCharacterSetsForLanguageL(installedLanguages->At(i));
       
   618           }
       
   619      iTopCharacterSet->Compress();
       
   620      installedLanguages->Reset();
       
   621      CleanupStack::PopAndDestroy(2, installedLanguages);
       
   622      iRscFile.Close();
       
   623      }
       
   624 
       
   625 // -----------------------------------------------------------------------------
       
   626 // CMetaDataParser::SelectCharacterSetsForLanguage()
       
   627 // -----------------------------------------------------------------------------
       
   628 //
       
   629 void CMPXPlaylistEngine::SelectCharacterSetsForLanguageL(TInt aLanguage)
       
   630      {
       
   631      switch ( aLanguage )
       
   632           {
       
   633           case ELangEnglish:
       
   634                ReadCharacterSetResourceL(R_MPX_PLAYLIST_ENGLISH_CHAR_SET);
       
   635                break;
       
   636           case ELangFrench:
       
   637                ReadCharacterSetResourceL(R_MPX_PLAYLIST_FRENCH_CHAR_SET);
       
   638                break;
       
   639           case ELangGerman:
       
   640                ReadCharacterSetResourceL(R_MPX_PLAYLIST_GERMAN_CHAR_SET);
       
   641                break;
       
   642           case ELangTurkish:
       
   643                ReadCharacterSetResourceL(R_MPX_PLAYLIST_TURKISH_CHAR_SET);
       
   644                break;
       
   645           case ELangFinnish:
       
   646                ReadCharacterSetResourceL(R_MPX_PLAYLIST_FINNISH_CHAR_SET);
       
   647                break;
       
   648           case ELangSwedish:
       
   649                ReadCharacterSetResourceL(R_MPX_PLAYLIST_SWEDISH_CHAR_SET);
       
   650                break;
       
   651           case ELangRussian:
       
   652                ReadCharacterSetResourceL(R_MPX_PLAYLIST_RUSSIAN_CHAR_SET);
       
   653                break;
       
   654           case ELangArabic:
       
   655                ReadCharacterSetResourceL(R_MPX_PLAYLIST_ARABIC_CHAR_SET);
       
   656                break;
       
   657           case ELangHebrew:
       
   658                ReadCharacterSetResourceL(R_MPX_PLAYLIST_HEBREW_CHAR_SET);
       
   659                break;
       
   660           case ELangFarsi:
       
   661                ReadCharacterSetResourceL(R_MPX_PLAYLIST_FARSI_CHAR_SET);
       
   662                break;
       
   663           case ELangItalian:
       
   664                ReadCharacterSetResourceL(R_MPX_PLAYLIST_ITALIAN_CHAR_SET);
       
   665                break;
       
   666           case ELangPolish:
       
   667                ReadCharacterSetResourceL(R_MPX_PLAYLIST_POLISH_CHAR_SET);
       
   668                break;
       
   669           case ELangHungarian:
       
   670                ReadCharacterSetResourceL(R_MPX_PLAYLIST_HUNGARIAN_CHAR_SET);
       
   671                break;
       
   672           case ELangSpanish:
       
   673                ReadCharacterSetResourceL(R_MPX_PLAYLIST_SPANISH_CHAR_SET);
       
   674                break;
       
   675           case ELangDutch:
       
   676                ReadCharacterSetResourceL(R_MPX_PLAYLIST_DUTCH_CHAR_SET);
       
   677                break;
       
   678           case ELangPortuguese:
       
   679                ReadCharacterSetResourceL(R_MPX_PLAYLIST_PORTUGUESE_CHAR_SET);
       
   680                break;
       
   681           case ELangAmerican:
       
   682                ReadCharacterSetResourceL(R_MPX_PLAYLIST_ENGLISH_CHAR_SET);
       
   683                break;
       
   684           case ELangCanadianFrench:
       
   685                ReadCharacterSetResourceL(R_MPX_PLAYLIST_FRENCH_CHAR_SET);
       
   686                break;
       
   687           case ELangBrazilianPortuguese:
       
   688                ReadCharacterSetResourceL(R_MPX_PLAYLIST_PORTUGUESE_CHAR_SET);
       
   689                break;
       
   690           case ELangLatinAmericanSpanish:
       
   691                ReadCharacterSetResourceL(R_MPX_PLAYLIST_SPANISH_CHAR_SET);
       
   692                break;
       
   693           case ELangLatvian:
       
   694                ReadCharacterSetResourceL(R_MPX_PLAYLIST_LATVIAN_CHAR_SET);
       
   695                break;
       
   696           case ELangGreek:
       
   697                ReadCharacterSetResourceL(R_MPX_PLAYLIST_GREEK_CHAR_SET);
       
   698                break;
       
   699           case ELangEstonian:
       
   700                ReadCharacterSetResourceL(R_MPX_PLAYLIST_ESTONIAN_CHAR_SET);
       
   701                break;
       
   702           case ELangLithuanian:
       
   703                ReadCharacterSetResourceL(R_MPX_PLAYLIST_LITHUANIAN_CHAR_SET);
       
   704                break;
       
   705           case ELangRomanian:
       
   706                ReadCharacterSetResourceL(R_MPX_PLAYLIST_ROMANIAN_CHAR_SET);
       
   707                break;
       
   708           case ELangUkrainian:
       
   709                ReadCharacterSetResourceL(R_MPX_PLAYLIST_UKRAINIAN_CHAR_SET);
       
   710                break;
       
   711           case ELangBulgarian:
       
   712                ReadCharacterSetResourceL(R_MPX_PLAYLIST_BULGARIAN_CHAR_SET);
       
   713                break;
       
   714           case ELangCroatian:
       
   715                ReadCharacterSetResourceL(R_MPX_PLAYLIST_CROATIAN_CHAR_SET);
       
   716                break;
       
   717           case ELangSerbian:
       
   718                ReadCharacterSetResourceL(R_MPX_PLAYLIST_SERBIAN_CHAR_SET);
       
   719                break;
       
   720           case ELangIndonesian:
       
   721                ReadCharacterSetResourceL(R_MPX_PLAYLIST_INDONESIAN_CHAR_SET);
       
   722                break;
       
   723           case ELangMalay:
       
   724           case ELangTagalog:
       
   725                ReadCharacterSetResourceL(R_MPX_PLAYLIST_MALAY_CHAR_SET);
       
   726                break;
       
   727           case ELangIcelandic:
       
   728                ReadCharacterSetResourceL(R_MPX_PLAYLIST_ICELANDIC_CHAR_SET);
       
   729                break;
       
   730           case ELangDanish:
       
   731                ReadCharacterSetResourceL(R_MPX_PLAYLIST_DANISH_CHAR_SET);
       
   732                break;
       
   733           case ELangNorwegian:
       
   734                ReadCharacterSetResourceL(R_MPX_PLAYLIST_NORWEGIAN_CHAR_SET);
       
   735                break;
       
   736           case ELangHindi:
       
   737                ReadCharacterSetResourceL(R_MPX_PLAYLIST_INDIAN_CHAR_SET);
       
   738                break;
       
   739           case ELangUrdu:
       
   740                ReadCharacterSetResourceL(R_MPX_PLAYLIST_URDU_CHAR_SET);
       
   741                break;
       
   742           case ELangCzech:
       
   743                ReadCharacterSetResourceL(R_MPX_PLAYLIST_CZECH_CHAR_SET);
       
   744                break;
       
   745           case ELangSlovak:
       
   746                ReadCharacterSetResourceL(R_MPX_PLAYLIST_SLOVAK_CHAR_SET);
       
   747                break;
       
   748           case ELangSlovenian:
       
   749                ReadCharacterSetResourceL(R_MPX_PLAYLIST_SLOVENIAN_CHAR_SET);
       
   750                break;
       
   751           case ELangTaiwanChinese:
       
   752           case ELangHongKongChinese:
       
   753                ReadCharacterSetResourceL(R_MPX_PLAYLIST_TAIWAN_HK_CHINESE_CHAR_SET);
       
   754                break;
       
   755           case ELangPrcChinese:
       
   756                ReadCharacterSetResourceL(R_MPX_PLAYLIST_CHINESE_CHAR_SET);
       
   757                break;
       
   758           case ELangEnglish_Taiwan:
       
   759           case ELangEnglish_Prc:
       
   760           case ELangEnglish_Japan:
       
   761           case ELangEnglish_Thailand:
       
   762                ReadCharacterSetResourceL(R_MPX_PLAYLIST_ENGLISH_CHAR_SET);
       
   763                break;
       
   764           case ELangJapanese:
       
   765                ReadCharacterSetResourceL(R_MPX_PLAYLIST_JAPANESE_CHAR_SET);
       
   766                break;
       
   767           case ELangThai:
       
   768                ReadCharacterSetResourceL(R_MPX_PLAYLIST_THAI_CHAR_SET);
       
   769                break;
       
   770           case ELangVietnamese:
       
   771                ReadCharacterSetResourceL(R_MPX_PLAYLIST_VIETNAMESE_CHAR_SET);
       
   772                break;
       
   773           case ELangMalay_Apac:
       
   774                ReadCharacterSetResourceL(R_MPX_PLAYLIST_MALAY_CHAR_SET);
       
   775                break;
       
   776           default:
       
   777                break;
       
   778           }
       
   779      }
       
   780 
       
   781 // -----------------------------------------------------------------------------
       
   782 // CMPXPlaylistEngine::ReadCharacterSetResourceL()
       
   783 // -----------------------------------------------------------------------------
       
   784 //
       
   785 void CMPXPlaylistEngine::ReadCharacterSetResourceL(TInt aResourceId)
       
   786      {
       
   787      TResourceReader rscReader;                       // Resource reader
       
   788      HBufC8* rscBuf;                                      // Buffer where resource is read
       
   789 
       
   790      rscBuf = iRscFile.AllocReadL(aResourceId);
       
   791      rscReader.SetBuffer(rscBuf);
       
   792      CleanupStack::PushL(rscBuf);
       
   793 
       
   794      TUint characterSetElementId;
       
   795      TInt numCharacterSetElements = rscReader.ReadInt16();
       
   796      TUint elemId;
       
   797      CCnvCharacterSetConverter::SCharacterSet elem;
       
   798 
       
   799      for (TInt i = 0; i < numCharacterSetElements; i++)
       
   800           {
       
   801           characterSetElementId = rscReader.ReadInt32();
       
   802           for (TInt j = 0; j < iCharacterSet->Count(); j++ )
       
   803                {
       
   804                elem = iCharacterSet->At(j);
       
   805                elemId = elem.Identifier();
       
   806                if ( elemId == characterSetElementId && !IsInTopCharacterSet(characterSetElementId) )
       
   807                     {
       
   808                     iTopCharacterSet->AppendL(elem);
       
   809                     }
       
   810                }
       
   811           }
       
   812 
       
   813      CleanupStack::PopAndDestroy(rscBuf);
       
   814      }
       
   815 
       
   816 // -----------------------------------------------------------------------------
       
   817 // CMPXPlaylistEngine::IsInTopCharacterSet()
       
   818 // -----------------------------------------------------------------------------
       
   819 //
       
   820 TBool CMPXPlaylistEngine::IsInTopCharacterSet(TUint aCharacterSetId)
       
   821      {
       
   822      for (TInt i = 0; i < iTopCharacterSet->Count(); i++)
       
   823           {
       
   824           if ( iTopCharacterSet->At(i).Identifier() == aCharacterSetId )
       
   825                {
       
   826                return ETrue;
       
   827                }
       
   828           }
       
   829      return EFalse;
       
   830      }
       
   831 
       
   832 // End of file