upnpharvester/cdssync/cdssynclib/src/cdssyncimplsql.cpp
branchIOP_Improvements
changeset 40 08b5eae9f9ff
parent 39 6369bfd1b60d
child 41 b4d83ea1d6e2
equal deleted inserted replaced
39:6369bfd1b60d 40:08b5eae9f9ff
     1 /*
       
     2 * Copyright (c) 2008 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:      Cds Sync Implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 #include <hash.h>
       
    24 #include <xml/matchdata.h>
       
    25 #include "cmsqlmainfactory.h"
       
    26 #include "mcmsqlmain.h"
       
    27 #include "cmsqlbaseitem.h"
       
    28 #include "cmsqlgenericitem.h"
       
    29 #include "cmsqlaudioitem.h"
       
    30 #include "cmsqlimageitem.h"
       
    31 #include "cmsqlvideoitem.h"
       
    32 #include "cmsqlpropertyitem.h"
       
    33 #include "cmsqlresolutionpropertyitem.h"
       
    34 
       
    35 #include "cdssyncimplsql.h"
       
    36 #include "cdssyncsqlao.h"
       
    37 #include "msdebug.h"
       
    38 
       
    39 // Constants
       
    40 _LIT8( KXmlMimeType, "text/xml" );
       
    41 _LIT8( KSymbian, "Symbian");
       
    42 _LIT8( KSemicolon, ";");
       
    43 
       
    44 _LIT8( KXmlCdsDefaultNamespace, 
       
    45        "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/");
       
    46 _LIT8( KXmlCdsDcNamespace,"http://purl.org/dc/elements/1.1/");
       
    47 _LIT8( KXmlCdsUpnpNamespace,"urn:schemas-upnp-org:metadata-1-0/upnp/");
       
    48 
       
    49 _LIT8( KAlbum,      "album");
       
    50 _LIT8( KArtist,     "artist");
       
    51 _LIT8( KClass,      "class");
       
    52 _LIT8( KDescription,"description");
       
    53 _LIT8( KDate,       "date");
       
    54 _LIT8( KGenre,      "genre");
       
    55 _LIT8( KId,         "id");
       
    56 _LIT8( KItem,       "item");
       
    57 _LIT8( KRes,        "res");
       
    58 _LIT8( KTitle,      "title");
       
    59 _LIT8( KAlbumArtUri, "albumArtURI");
       
    60 
       
    61 _LIT8( KBitrate,        "bitrate");
       
    62 _LIT8( KDuration,       "duration");
       
    63 _LIT8( KProtocolInfo,   "protocolInfo");
       
    64 _LIT8( KResolution,     "resolution");
       
    65 _LIT8( KSize,           "size");
       
    66 
       
    67 _LIT8( KAudioItem,      "audioItem");
       
    68 _LIT8( KImageItem,      "imageItem");
       
    69 _LIT8( KVideoItem,      "videoItem");
       
    70 _LIT8( KAudioBroadCastItem, "audioItem.audioBroadcast");
       
    71 _LIT8( KVideoBroadCastItem, "videoItem.videoBroadcast");
       
    72 _LIT8( KDlnaPn,         "DLNA.ORG_PN=" );
       
    73 
       
    74 const TInt KAlbumIndex =        0;
       
    75 const TInt KArtistIndex =       1;
       
    76 const TInt KClassIndex =        2;
       
    77 const TInt KGenreIndex =        3;
       
    78 const TInt KResolutionIndex =   4;
       
    79 const TInt KUpnpProfileIndex =  5;
       
    80 
       
    81 const TCmMetadataField KMetadataTypes[] = 
       
    82     {
       
    83     ECmAlbum, ECmArtist, ECmUpnpClass, ECmGenre, ECmResolution, ECmProfileId
       
    84     };
       
    85 
       
    86 const TInt KMetadataTypeCount = 6;
       
    87 
       
    88 const TInt KParseChunkSize = 100 * KKilo; // 100 kB
       
    89 
       
    90 const TInt KCdsSyncMaxBufLength = 512;
       
    91 
       
    92 const TInt KCdsSyncPriority = CActive::EPriorityIdle; 
       
    93 
       
    94 // --------------------------------------------------------------------------
       
    95 // CItemResource::NewLC()
       
    96 // --------------------------------------------------------------------------
       
    97 CItemResource* CItemResource::NewLC()
       
    98     {
       
    99     CItemResource* self=new (ELeave) CItemResource();
       
   100     CleanupStack::PushL(self);
       
   101     self->ConstructL();
       
   102     return self;
       
   103     }
       
   104 
       
   105 
       
   106 // --------------------------------------------------------------------------
       
   107 // CItemResource::~CItemResource()
       
   108 // --------------------------------------------------------------------------
       
   109 CItemResource::~CItemResource() // destruct - virtual, so no export
       
   110     {
       
   111     delete iDuration;
       
   112     delete iBitrate;
       
   113     delete iSize;    
       
   114     delete iResolution;    
       
   115     delete iProtocol;    
       
   116     delete iUri;    
       
   117     }
       
   118 
       
   119 // --------------------------------------------------------------------------
       
   120 // CItemResource::CItemResource()
       
   121 // --------------------------------------------------------------------------
       
   122 CItemResource::CItemResource()
       
   123     {
       
   124     }
       
   125 
       
   126 // --------------------------------------------------------------------------
       
   127 // CItemResource::ConstructL()
       
   128 // --------------------------------------------------------------------------
       
   129 void CItemResource::ConstructL()
       
   130     {
       
   131     }
       
   132 
       
   133 // --------------------------------------------------------------------------
       
   134 // CCdsSyncImpl::NewL()
       
   135 // --------------------------------------------------------------------------
       
   136 CCdsSyncImpl* CCdsSyncImpl::NewL()
       
   137     {
       
   138     LOG(_L("[Cds Sync]\t CCdsSyncImpl::NewL"));
       
   139     CCdsSyncImpl* self = NewLC();
       
   140     CleanupStack::Pop( self );
       
   141     return self;
       
   142     }
       
   143 
       
   144 // --------------------------------------------------------------------------
       
   145 // CCdsSyncImpl::NewLC()
       
   146 // --------------------------------------------------------------------------
       
   147 CCdsSyncImpl* CCdsSyncImpl::NewLC()
       
   148     {
       
   149     LOG(_L("[Cds Sync]\t CCdsSyncImpl::NewLC"));
       
   150 
       
   151     CCdsSyncImpl* self = new (ELeave) CCdsSyncImpl();
       
   152     CleanupStack::PushL( self );
       
   153     self->ConstructL();
       
   154     return self;
       
   155     }
       
   156 
       
   157 
       
   158 // --------------------------------------------------------------------------
       
   159 // CCdsSyncImpl::~CCdsSyncImpl()
       
   160 // --------------------------------------------------------------------------
       
   161 CCdsSyncImpl::~CCdsSyncImpl() 
       
   162     {
       
   163     
       
   164     LOG(_L("[Cds Sync]\t CCdsSyncImpl::~CCdsSyncImpl"));
       
   165 
       
   166     if ( IsActive() )
       
   167         {
       
   168         Cancel();
       
   169         }
       
   170         
       
   171     // iCurrentContent is owned and needs to be deleted here before it is set
       
   172     // to NULL at CleanItemData-method.
       
   173     if ( iCurrentContent )
       
   174         {
       
   175         delete iCurrentContent;    
       
   176         }    
       
   177     CleanItemData();
       
   178     
       
   179     iState = ECdsSyncIdle;
       
   180     if ( iBackground )
       
   181         {
       
   182         delete iBackground;    
       
   183         }
       
   184     
       
   185     if ( iParser )
       
   186         {
       
   187         delete iParser;    
       
   188         }
       
   189     
       
   190     if ( iCurrentDocument )
       
   191         {
       
   192         delete iCurrentDocument;    
       
   193         }
       
   194     
       
   195     iItemsInDb.ResetAndDestroy();
       
   196     iItemsToAdd.ResetAndDestroy();
       
   197     for ( TInt i = 0; i < iNames.Count(); i++ )
       
   198         {
       
   199         iNames[ i ]->ResetAndDestroy();
       
   200         }
       
   201     iNames.ResetAndDestroy();
       
   202     iFs.Close();
       
   203     
       
   204     if ( iSqlAo )
       
   205         {
       
   206         delete iSqlAo;    
       
   207         }
       
   208     
       
   209     if ( iMetadataDb )
       
   210         {
       
   211         iMetadataDb->Close();    
       
   212         }    
       
   213     }
       
   214 
       
   215 
       
   216 // --------------------------------------------------------------------------
       
   217 // CCdsSyncImpl::CCdsSyncImpl()
       
   218 // --------------------------------------------------------------------------
       
   219 CCdsSyncImpl::CCdsSyncImpl() : 
       
   220     CActive( EPriorityStandard ),
       
   221     iHashOrder( CCmSqlBaseItem::CompareByHash ),
       
   222     iNameOrder( CCmSqlPropertyItem::CompareItemsByName )
       
   223     {
       
   224     CActiveScheduler::Add( this );
       
   225     }
       
   226 
       
   227 // --------------------------------------------------------------------------
       
   228 // CCdsSyncImpl::ConstructL() 
       
   229 // --------------------------------------------------------------------------
       
   230 void CCdsSyncImpl::ConstructL() 
       
   231     {
       
   232     LOG(_L("[Cds Sync]\t CCdsSyncImpl::ConstructL"));
       
   233 
       
   234     CMatchData *matchData = CMatchData::NewL();
       
   235     CleanupStack::PushL( matchData );
       
   236     matchData->SetMimeTypeL( KXmlMimeType );
       
   237     User::LeaveIfError( iFs.Connect() );
       
   238     matchData->SetVariantL( KSymbian );
       
   239 
       
   240     iParser  = CParser::NewL( *matchData, *this );
       
   241     CleanupStack::PopAndDestroy( matchData );
       
   242     
       
   243     iBackground = CIdle::NewL( KCdsSyncPriority );
       
   244     iMetadataDb = CCmSqlMainFactory::NewCmSqlMainL( iFs );
       
   245 
       
   246     }
       
   247 
       
   248 
       
   249 // --------------------------------------------------------------------------
       
   250 // CCdsSyncImpl::ResetL()
       
   251 // --------------------------------------------------------------------------
       
   252 void CCdsSyncImpl::ResetL() 
       
   253     {
       
   254     LOG(_L("[Cds Sync]\t CCdsSyncImpl::ResetL"));
       
   255     LOG(_L("[Cds Sync]\t cleaning objects.."));
       
   256     iBackground->Cancel();
       
   257     if( iSqlAo && iSqlAo->IsActive() && iMetadataDb )
       
   258         {
       
   259         iMetadataDb->CancelAsyncOperation();
       
   260         }
       
   261   
       
   262     delete iSqlAo; 
       
   263     iSqlAo = NULL;
       
   264     
       
   265     iItemsInDb.ResetAndDestroy();
       
   266     iItemsToAdd.ResetAndDestroy();
       
   267     for ( TInt i = 0; i < iNames.Count(); i++ )
       
   268         {
       
   269         iNames[ i ]->ResetAndDestroy();
       
   270         }
       
   271     iNames.ResetAndDestroy();
       
   272     CleanItemData();           
       
   273     }
       
   274 
       
   275 
       
   276 // --------------------------------------------------------------------------
       
   277 // CCdsSyncImpl::InitL()
       
   278 // --------------------------------------------------------------------------
       
   279 void CCdsSyncImpl::InitL( RPointerArray<HBufC8>& aSourceDataArray,
       
   280                                    const TInt& aDeviceId, 
       
   281                                    MCdsSyncObserver& aObserver,
       
   282                                    TInt aAddGranularity )
       
   283     {
       
   284     LOG(_L("[Cds Sync]\t CCdsSyncImpl::InitL"));
       
   285     iSearchIndex = 0;
       
   286     ResetL();
       
   287     
       
   288     LOG(_L("[Cds Sync]\t initializing variables.."));
       
   289     iObserver = &aObserver;
       
   290     iSourceDataArray = &aSourceDataArray;
       
   291     iSourceDataComplete = EFalse;
       
   292     iState = ECdsSyncInitializing;
       
   293     iUnchangedItemCount = 0;
       
   294         
       
   295     LOG(_L("[Cds Sync]\t creating ao.."));
       
   296     iSqlAo = CCdsSyncSqlAo::NewL( 
       
   297         *iMetadataDb, *this, iItemsToAdd, 
       
   298         iItemsInDb, aAddGranularity );
       
   299     
       
   300     LOG(_L("[Cds Sync]\t Requesting existing metadata.."));
       
   301     iMetadataDb->SetMsId( aDeviceId );
       
   302     iMetadataDb->GetItemsL( iItemsInDb, iSqlAo->iStatus );
       
   303     
       
   304     iSqlAo->iState = CCdsSyncSqlAo::ECdsSyncSqlAoInitializing;
       
   305     iSqlAo->Activate();
       
   306         
       
   307     LOG(_L("[Cds Sync]\t done."));
       
   308     }
       
   309 
       
   310 
       
   311 // --------------------------------------------------------------------------
       
   312 // CCdsSyncImpl::RunL()
       
   313 // --------------------------------------------------------------------------
       
   314 void CCdsSyncImpl::RunL()
       
   315     {
       
   316     TRACE( Print( _L("[Cds Sync]\t CCdsSyncImpl::RunL,\
       
   317     iStatus %d iState %d"), iStatus.Int(), (TInt)iState ) );
       
   318     
       
   319     switch ( iState )
       
   320         {
       
   321         case ECdsSyncInitializing:
       
   322             {
       
   323             TInt namesCount = iNames.Count();
       
   324             TRACE( Print( 
       
   325                 _L("[Cds Sync]\t iNames array size is %d out of %d"),
       
   326                 namesCount, 
       
   327                 KMetadataTypeCount ) );
       
   328             
       
   329             if ( namesCount == KMetadataTypeCount )
       
   330                 {
       
   331                 // all arrays ready, sort them
       
   332                 iItemsInDb.Sort( iHashOrder );
       
   333                 for ( TInt i = 0; i < KMetadataTypeCount; i++ )
       
   334                     {
       
   335                     iNames[ i ]->Sort( iNameOrder );
       
   336                     }
       
   337                 iState = ECdsSyncReadyToParse;
       
   338                 iSqlAo->iState = CCdsSyncSqlAo::ECdsSyncSqlAoIdle;
       
   339                 NotifySourceDataAddedL();
       
   340                 }
       
   341             else 
       
   342                 {
       
   343                 RPointerArray<CCmSqlPropertyItem>* nameArray =
       
   344                     new (ELeave) RPointerArray<CCmSqlPropertyItem>();
       
   345                 
       
   346                 iMetadataDb->GetPropertyValuesL( 
       
   347                     *nameArray,
       
   348                     iSqlAo->iStatus,
       
   349                     KMetadataTypes[namesCount]
       
   350                 );
       
   351                 iSqlAo->Activate();
       
   352                 iNames.AppendL( nameArray );
       
   353                 }
       
   354             break;
       
   355             }
       
   356         default: 
       
   357             {
       
   358             TRACE( Print( _L("[Cds Sync]\t RunL iState is \
       
   359             not ECdsSyncInitializing" ) ));
       
   360             break;
       
   361             }
       
   362         }
       
   363     }
       
   364 
       
   365 // --------------------------------------------------------------------------
       
   366 // CCdsSyncImpl::DoCancel()
       
   367 // --------------------------------------------------------------------------
       
   368 void CCdsSyncImpl::DoCancel()
       
   369     {
       
   370     LOG(_L("[Cds Sync]\t CCdsSyncImpl::DoCancel"));
       
   371     }
       
   372 
       
   373 // --------------------------------------------------------------------------
       
   374 // CCdsSyncImpl::NotifySourceDataAddedL()
       
   375 // --------------------------------------------------------------------------
       
   376 void CCdsSyncImpl::NotifySourceDataAddedL( 
       
   377     TBool aSourceDataComplete ) 
       
   378     {
       
   379     LOG(_L("[Cds Sync]\t CCdsSyncImpl::NotifySourceDataAdded"));
       
   380     
       
   381     if ( aSourceDataComplete )
       
   382         {
       
   383         iSourceDataComplete = ETrue;
       
   384         }
       
   385     
       
   386     if ( iState == ECdsSyncReadyToParse ) 
       
   387         {
       
   388         if ( iSourceDataArray->Count() )
       
   389             {
       
   390             iCurrentDocument = ( *iSourceDataArray )[ 0 ];
       
   391             iSourceDataArray->Remove( 0 );
       
   392             iChunkIndex = 0;
       
   393             iParser->ParseBeginL();
       
   394             iBackground->Start( 
       
   395                 TCallBack( CCdsSyncImpl::BackgroundParseL, this) );
       
   396             iState = ECdsSyncParsing;
       
   397             }
       
   398         else if ( iSourceDataComplete ) 
       
   399             {
       
   400             TRACE( Print( _L
       
   401             ("[Cds Sync]\t parsing complete, %d items to add"), 
       
   402                 iItemsToAdd.Count() ));
       
   403             TRACE( Print( _L("[Cds Sync]\t and %d items to remove"), 
       
   404                 iItemsInDb.Count() ));
       
   405      
       
   406             iState = ECdsSyncIdle;
       
   407             
       
   408             RemoveUnchangedItems( );
       
   409             
       
   410             iSqlAo->NotifyItemsAddedL( ETrue );
       
   411             }
       
   412         }
       
   413     }
       
   414     
       
   415 // --------------------------------------------------------------------------
       
   416 // CCdsSyncImpl::ProgressL()
       
   417 // --------------------------------------------------------------------------
       
   418 void CCdsSyncImpl::ProgressL( TInt aItemCount )
       
   419     {
       
   420     LOG(_L("[Cds Sync]\t CCdsSyncImpl::ProgressL"));
       
   421     iObserver->ProgressL( aItemCount );
       
   422     }
       
   423 
       
   424 
       
   425 // --------------------------------------------------------------------------
       
   426 // CCdsSyncImpl::ChunkCount()
       
   427 // --------------------------------------------------------------------------
       
   428 TInt CCdsSyncImpl::ChunkCount()
       
   429     {
       
   430     LOG(_L("[Cds Sync]\t CCdsSyncImpl::ChunkCount"));
       
   431     TInt chunkCount = iSourceDataArray->Count();
       
   432     if ( iCurrentDocument )
       
   433         {
       
   434         chunkCount++;
       
   435         }
       
   436     return chunkCount;
       
   437     }
       
   438 
       
   439 // --------------------------------------------------------------------------
       
   440 // Increment successfully processed number 
       
   441 // --------------------------------------------------------------------------
       
   442 //
       
   443 TInt CCdsSyncImpl::ProcessedItemCount()
       
   444 	{
       
   445 	return iProcessedItems;
       
   446 	}
       
   447 	
       
   448 // --------------------------------------------------------------------------
       
   449 // Increment chuch number ( search index )
       
   450 // --------------------------------------------------------------------------
       
   451 //
       
   452 void CCdsSyncImpl::SetSearchIndex( const TInt aSearchIndex )
       
   453     {
       
   454     iSearchIndex = aSearchIndex;
       
   455     } 
       
   456         
       
   457 // --------------------------------------------------------------------------
       
   458 // CCdsSyncImpl::ChunkCompleteL()
       
   459 // --------------------------------------------------------------------------
       
   460 void CCdsSyncImpl::ChunkCompleteL()
       
   461     {
       
   462     LOG(_L("[Cds Sync]\t CCdsSyncImpl::ChunkCompleteL"));
       
   463     iObserver->ChunkCompleteL();
       
   464     iProcessedItems = 0;
       
   465     }
       
   466     
       
   467 // --------------------------------------------------------------------------
       
   468 // CCdsSyncImpl::OperationsCompleteL()
       
   469 // --------------------------------------------------------------------------
       
   470 #ifdef _DEBUG
       
   471 void CCdsSyncImpl::OperationsCompleteL( TInt aErrCode ) 
       
   472 #else // _DEBUG
       
   473 void CCdsSyncImpl::OperationsCompleteL( TInt /*aErrCode*/ ) 
       
   474 #endif // _DEBUG
       
   475     {
       
   476     TRACE( Print( _L
       
   477     ("[Cds Sync]\t CCdsSyncImpl::OperationsCompleteL (err %d)"), 
       
   478         aErrCode ));
       
   479     
       
   480     if ( iState == ECdsSyncInitializing )
       
   481         {
       
   482         RunL();
       
   483         }
       
   484     else 
       
   485         {
       
   486         iObserver->SyncCompleteL();    
       
   487         iProcessedItems = 0;  
       
   488         }
       
   489     }
       
   490 
       
   491 // --------------------------------------------------------------------------
       
   492 // CCdsSyncImpl::BackgroundParseL()
       
   493 // --------------------------------------------------------------------------
       
   494 TInt CCdsSyncImpl::BackgroundParseL( TAny* aCdsSync )
       
   495     {
       
   496     LOG(_L("[Cds Sync]\t CCdsSyncImpl::BackgroundParseL"));
       
   497     
       
   498     return ((CCdsSyncImpl*)aCdsSync)->DoBackgroundParseL();
       
   499     }
       
   500  
       
   501 
       
   502 // --------------------------------------------------------------------------
       
   503 // CCdsSyncImpl::DoBackgroundParseL()
       
   504 // --------------------------------------------------------------------------
       
   505 TInt CCdsSyncImpl::DoBackgroundParseL()
       
   506     {
       
   507     LOG(_L("[Cds Sync]\t CCdsSyncImpl::DoBackgroundParseL"));
       
   508     if ( iCurrentDocument ) 
       
   509         {
       
   510 
       
   511     #ifdef _DEBUG
       
   512         iHashTime = 0;
       
   513         TTime timeBefore;
       
   514         timeBefore.HomeTime();
       
   515     #endif
       
   516         
       
   517         TBool parseMore = 
       
   518             ( iCurrentDocument->Length() - iChunkIndex ) > KParseChunkSize;
       
   519         TPtrC8 parseChunk = 
       
   520             parseMore ?
       
   521             iCurrentDocument->Mid( iChunkIndex, KParseChunkSize ) :
       
   522             iCurrentDocument->Mid( iChunkIndex );
       
   523         
       
   524         iUnchangedItemCount = 0;
       
   525             
       
   526         // in case of leave that is caused by out of memory
       
   527         TRAPD( error, iParser->ParseL( parseChunk ) );
       
   528     	if ( error != KErrNone )
       
   529         	{
       
   530         	TRACE( Print( _L("[Cds Sync]\t Parse error = %d"), error ));
       
   531         	}
       
   532         
       
   533     #ifdef _DEBUG
       
   534         TTime timeAfter;
       
   535         timeAfter.HomeTime();
       
   536         TRACE( Print( _L
       
   537             ("[Cds Sync]\t parsing of %d bytes of XML took %ld microsec"),
       
   538             parseChunk.Size(), 
       
   539             timeAfter.MicroSecondsFrom( timeBefore ).Int64() ) );
       
   540         TRACE( Print( _L
       
   541             ("[Cds Sync]\t of which hash comparison took %ld microsec"), 
       
   542             iHashTime));
       
   543     #endif
       
   544 
       
   545         if ( parseMore ) 
       
   546             {
       
   547             iChunkIndex += KParseChunkSize;
       
   548             }
       
   549         else 
       
   550             {
       
   551             // in case of leave that is caused by out of memory
       
   552             TRAPD( err, iParser->ParseEndL() );
       
   553     		if ( err != KErrNone )
       
   554         		{
       
   555         		TRACE( Print( _L("[Cds Sync]\t \
       
   556         		ParseEndL error = %d"), err ));
       
   557         		}
       
   558             iState = ECdsSyncReadyToParse;
       
   559             delete iCurrentDocument; iCurrentDocument = NULL;
       
   560             // check if there's more to parse and trap the leave
       
   561             TRAPD( errOne, NotifySourceDataAddedL() );
       
   562             if ( errOne != KErrNone )
       
   563                 {
       
   564                 TRACE( Print( _L("[Cds Sync]\t NotifySourceDataAdded \
       
   565                 error = %d"), errOne ));
       
   566                 }
       
   567             ChunkCompleteL();
       
   568             }
       
   569         iSqlAo->NotifyItemsAddedL();
       
   570         
       
   571         return parseMore;
       
   572         
       
   573         }
       
   574     LOG(_L("[Cds Sync]\t CCdsSyncImpl::BackgroundParseL END"));
       
   575     return EFalse;
       
   576     }
       
   577   
       
   578 
       
   579 // --------------------------------------------------------------------------
       
   580 // CCdsSyncImpl::FindAttribute()
       
   581 // --------------------------------------------------------------------------
       
   582 TInt CCdsSyncImpl::FindAttribute( const TDesC8& aName, 
       
   583                                   const TDesC8& aPref, 
       
   584                                   const RAttributeArray& aAttributes ) const
       
   585     {
       
   586     TInt returnvalue = KErrNotFound;
       
   587     for ( TInt i = 0; i < aAttributes.Count(); i++ ) 
       
   588         {
       
   589         if ( ( aAttributes[i].Attribute().LocalName().
       
   590                DesC().Compare( aName ) == 0) &&
       
   591              ( aAttributes[i].Attribute().Prefix().
       
   592                DesC().Compare( aPref ) == 0) )
       
   593             {
       
   594             returnvalue = i;
       
   595             // break out from the loop
       
   596             i = aAttributes.Count();
       
   597             }
       
   598         }
       
   599     return returnvalue;
       
   600     }
       
   601 
       
   602 
       
   603 // --------------------------------------------------------------------------
       
   604 // CCdsSyncImpl::ParseResolution()
       
   605 // --------------------------------------------------------------------------
       
   606 void CCdsSyncImpl::ParseResolution( const TDesC8& aDes,
       
   607                                     TUint& aWidth,
       
   608                                     TUint& aHeight ) const
       
   609     {
       
   610     TLex8 lex( aDes );
       
   611     if ( lex.Val( aWidth ) != KErrNone ) 
       
   612         {
       
   613         aWidth = 0;
       
   614         }
       
   615     if ( lex.Get() != 'x' || lex.Val( aHeight ) != KErrNone ) 
       
   616         {
       
   617         aHeight = 0;
       
   618         }
       
   619     }
       
   620 
       
   621 // --------------------------------------------------------------------------
       
   622 // CCdsSyncImpl::ParseUint()
       
   623 // --------------------------------------------------------------------------
       
   624 TUint CCdsSyncImpl::ParseUint( const TDesC8& aDes ) const
       
   625     {
       
   626     TUint res = 0;
       
   627     TLex8 lex( aDes );
       
   628     if ( lex.Val( res ) != KErrNone ) 
       
   629         {
       
   630         res = 0;
       
   631         }
       
   632     return res;
       
   633     }
       
   634 
       
   635 // --------------------------------------------------------------------------
       
   636 // CCdsSyncImpl::ParseInt64()
       
   637 // --------------------------------------------------------------------------
       
   638 TInt64 CCdsSyncImpl::ParseInt64( const TDesC8& aDes ) const
       
   639     {
       
   640     TInt64 res = 0;
       
   641     TLex8 lex( aDes );
       
   642     if ( lex.Val( res ) != KErrNone )
       
   643         {
       
   644         res = 0;
       
   645         }
       
   646     return res;
       
   647     }
       
   648 
       
   649 // --------------------------------------------------------------------------
       
   650 // CCdsSyncImpl::ParseTime()
       
   651 // --------------------------------------------------------------------------
       
   652 TTime CCdsSyncImpl::ParseTime( const TDesC8& aDes ) const 
       
   653     {
       
   654     TUint year = 0;
       
   655     TUint month = 1;
       
   656     TUint day = 1;
       
   657     TLex8 lex;
       
   658     
       
   659     TInt dashpos = aDes.Find( _L8("-") );
       
   660     TInt dashpos2 = aDes.Mid( dashpos + 1 ).Find( _L8("-") ) + dashpos + 1;
       
   661     
       
   662     lex = aDes.Left(4);
       
   663     if ( lex.Val( year ) != KErrNone )
       
   664         {
       
   665         year = 0;
       
   666         }        
       
   667     if ( dashpos2-dashpos > 1 ) 
       
   668         {
       
   669         lex = aDes.Mid( dashpos + 1,dashpos2 - dashpos - 1 );
       
   670         if ( lex.Val(month) != KErrNone )
       
   671             {
       
   672             month = 1;
       
   673             }
       
   674             
       
   675         }
       
   676     if (aDes.Length() - dashpos2 > 1) 
       
   677         {
       
   678         lex = aDes.Mid(dashpos2 + 1);
       
   679         if ( lex.Val(day) != KErrNone ) 
       
   680             {
       
   681             day = 1;
       
   682             }            
       
   683         }
       
   684     TDateTime time;
       
   685     if ( time.Set(year, TMonth(month-1), day-1, 0,0,0,0) != KErrNone )
       
   686         {
       
   687         return TTime( TDateTime(0, TMonth(0), 0, 0,0,0,0) );
       
   688         }
       
   689     else
       
   690         {
       
   691         return TTime( time );
       
   692         }
       
   693     }
       
   694 
       
   695 // --------------------------------------------------------------------------
       
   696 // CCdsSyncImpl::ParseDuration()
       
   697 // --------------------------------------------------------------------------
       
   698 TReal CCdsSyncImpl::ParseDuration( const TDesC8& aDes ) const
       
   699     {
       
   700     TInt multiplier = 1;
       
   701     TInt plusminuspos = aDes.Find( _L8("-") );
       
   702     if ( plusminuspos == KErrNotFound ) 
       
   703         {
       
   704         plusminuspos = aDes.Find( _L8("+") );
       
   705         }
       
   706     else 
       
   707         {
       
   708         multiplier = -1;
       
   709         }
       
   710         
       
   711     TInt hourminutepos = aDes.Find( _L8(":") );
       
   712     TInt minutesecondpos = aDes.Mid( hourminutepos + 1 ).
       
   713          Find( _L8(":") ) + hourminutepos + 1;
       
   714     TInt dotpos = aDes.Find( _L8(".") );
       
   715     TInt slashpos = aDes.Find( _L8("/") );
       
   716 
       
   717     TInt hours = 0; TInt minutes = 0; 
       
   718     TReal seconds = 0; TReal f0 = 0; TReal f1=1;    
       
   719     TLex8 lex;
       
   720     
       
   721     if ( hourminutepos - plusminuspos > 1 ) 
       
   722         {
       
   723         lex = aDes.Mid( plusminuspos + 1, hourminutepos - plusminuspos - 1 );
       
   724         if ( lex.Val( hours ) != KErrNone )
       
   725             {
       
   726             hours = 0;
       
   727             }            
       
   728         }
       
   729     if ( minutesecondpos - hourminutepos > 1 ) 
       
   730         {
       
   731         lex = aDes.Mid( hourminutepos + 1, 
       
   732                         minutesecondpos - hourminutepos - 1 );
       
   733         if ( lex.Val(minutes) != KErrNone ) 
       
   734             {
       
   735             minutes = 0;
       
   736             }
       
   737         }
       
   738     if ( (dotpos == KErrNotFound || slashpos == KErrNotFound) 
       
   739           && minutesecondpos != KErrNotFound ) 
       
   740         {
       
   741         lex = aDes.Mid( minutesecondpos + 1 );
       
   742         if ( lex.Val(seconds) != KErrNone )
       
   743             {
       
   744             seconds = 0;
       
   745             }            
       
   746         } 
       
   747     else if (slashpos - dotpos > 1 && dotpos - minutesecondpos > 1 
       
   748             && aDes.Length() - slashpos > 1) 
       
   749         {
       
   750         lex = aDes.Mid( minutesecondpos + 1, dotpos - minutesecondpos - 1 );
       
   751         if ( lex.Val( seconds ) != KErrNone ) 
       
   752             {
       
   753             seconds = 0;
       
   754             }
       
   755         lex = aDes.Mid( dotpos + 1, slashpos - dotpos - 1 );
       
   756         if ( lex.Val(f0) != KErrNone ) 
       
   757             {
       
   758             f0 = 0;
       
   759             }            
       
   760         lex = aDes.Mid( slashpos + 1 );
       
   761         if ( lex.Val(f1) != KErrNone ) 
       
   762             {
       
   763             f1 = 1;
       
   764             }            
       
   765         }
       
   766     
       
   767     return multiplier*(hours * 3600 + minutes * 60 + seconds + f0/f1);
       
   768     }
       
   769 
       
   770 // --------------------------------------------------------------------------
       
   771 // CCdsSyncImpl::CalculateHashL()
       
   772 // --------------------------------------------------------------------------
       
   773 HBufC8* CCdsSyncImpl::CalculateHashL() const
       
   774     {
       
   775     CSHA1* sha1 = CSHA1::NewL();
       
   776     CleanupStack::PushL( sha1 );
       
   777     sha1->Reset();
       
   778     
       
   779     if ( iArtist ) 
       
   780         {
       
   781         sha1->Update( *iArtist );    
       
   782         }
       
   783     else 
       
   784         {
       
   785         sha1->Update( KNullDesC8() );
       
   786         }
       
   787     
       
   788     if ( iAlbum ) 
       
   789         {
       
   790         sha1->Update( *iAlbum );    
       
   791         }
       
   792     else 
       
   793         {
       
   794         sha1->Update( KNullDesC8() );
       
   795         }
       
   796     
       
   797     if ( iTitle ) 
       
   798         {
       
   799         sha1->Update( *iTitle );
       
   800         }
       
   801     else 
       
   802         {
       
   803         sha1->Update( KNullDesC8() );
       
   804         }
       
   805     
       
   806     if ( iClass ) 
       
   807         {
       
   808         sha1->Update( *iClass );
       
   809         }
       
   810     else 
       
   811         {
       
   812         sha1->Update( KNullDesC8() );
       
   813         }
       
   814     
       
   815     if ( iGenre ) 
       
   816         {
       
   817         sha1->Update( *iGenre );
       
   818         }
       
   819     else 
       
   820         {
       
   821         sha1->Update( KNullDesC8() );
       
   822         }
       
   823         
       
   824     if ( iDate ) 
       
   825         {
       
   826         sha1->Update( *iDate );
       
   827         }
       
   828     else 
       
   829         {
       
   830         sha1->Update( KNullDesC8() );
       
   831         }
       
   832         
       
   833     if( iAlbumArtUri )
       
   834         {
       
   835         sha1->Update( *iAlbumArtUri );
       
   836         }
       
   837     else 
       
   838         {
       
   839         sha1->Update( KNullDesC8() );
       
   840         }        
       
   841     
       
   842     for ( TInt i = 0; i < iResources.Count(); i++ ) 
       
   843         {
       
   844         CItemResource* res = iResources[i];
       
   845         
       
   846         if ( res->iBitrate ) 
       
   847             {
       
   848             sha1->Update( *res->iBitrate );    
       
   849             }
       
   850         else 
       
   851             {
       
   852             sha1->Update( KNullDesC8() );
       
   853             }
       
   854         
       
   855         if ( res->iSize ) 
       
   856             {
       
   857             sha1->Update( *res->iSize );
       
   858             }
       
   859         else 
       
   860             {
       
   861             sha1->Update( KNullDesC8() );
       
   862             }
       
   863         
       
   864         
       
   865         if ( res->iResolution ) 
       
   866             {
       
   867             sha1->Update( *res->iResolution );
       
   868             }
       
   869         else 
       
   870             {
       
   871             sha1->Update( KNullDesC8() );    
       
   872             }
       
   873         
       
   874         
       
   875         if ( res->iDuration ) 
       
   876             {
       
   877             sha1->Update( *res->iDuration );
       
   878             }
       
   879         else 
       
   880             {
       
   881             sha1->Update( KNullDesC8() );    
       
   882             }
       
   883         
       
   884         if ( res->iProtocol ) 
       
   885             {
       
   886             sha1->Update( *res->iProtocol );
       
   887             }
       
   888         else 
       
   889             {
       
   890             sha1->Update( KNullDesC8() );
       
   891             }
       
   892         
       
   893         if ( res->iUri ) 
       
   894             {
       
   895             sha1->Update( *res->iUri );
       
   896             }
       
   897         else 
       
   898             {
       
   899             sha1->Update( KNullDesC8() );            
       
   900             }
       
   901         }
       
   902 
       
   903     // get the final hash value.
       
   904     TPtrC8 hash = sha1->Final();
       
   905     
       
   906     // create an object that can be returned and copy hash value there.
       
   907     HBufC8* retval = hash.AllocL();
       
   908 
       
   909     // delete SHA1 object.
       
   910     CleanupStack::PopAndDestroy( sha1 );
       
   911     sha1 = NULL;
       
   912     
       
   913     // return 
       
   914     return retval;
       
   915     }
       
   916 
       
   917 // --------------------------------------------------------------------------
       
   918 // CCdsSyncImpl::EscapeHashLC()
       
   919 // --------------------------------------------------------------------------
       
   920 HBufC* CCdsSyncImpl::EscapeHashLC( const TDesC8& aHash ) const
       
   921     {
       
   922     HBufC* escapedHash = HBufC::NewLC( 40 );
       
   923     TPtr ptr = escapedHash->Des();
       
   924     for ( TInt i=0; i < 20; i++ ) 
       
   925         {
       
   926         if ( aHash[i] == 0 ) 
       
   927             {
       
   928             ptr.Append( _L("\\0") );
       
   929             } 
       
   930         else if ( aHash[i] == '\\' )
       
   931             {
       
   932             ptr.Append( _L("\\\\") );
       
   933             } 
       
   934         else
       
   935             {
       
   936             ptr.Append( aHash[i] );
       
   937             }
       
   938         }
       
   939     return escapedHash;    
       
   940     }
       
   941 
       
   942 // --------------------------------------------------------------------------
       
   943 // CCdsSyncImpl::GetPropertyIdL()
       
   944 // --------------------------------------------------------------------------
       
   945 TInt64 CCdsSyncImpl::GetPropertyIdL( TInt aMetadataIndex,
       
   946                                      const TDesC8& aValue ) const
       
   947     {
       
   948     TInt64 id = 0;
       
   949     
       
   950     TCmMetadataField metadataType = KMetadataTypes[ aMetadataIndex ];
       
   951     
       
   952     CCmSqlPropertyItem* property = NULL;
       
   953     if ( metadataType == ECmResolution )
       
   954         {
       
   955         property = CCmSqlResolutionPropertyItem::NewLC();
       
   956         }
       
   957     else 
       
   958         {
       
   959         property = CCmSqlPropertyItem::NewLC();
       
   960         }
       
   961         
       
   962     
       
   963     property->SetNameL( aValue );
       
   964     CCmSqlPropertyItemArray* properties = iNames[ aMetadataIndex ];
       
   965     TInt index = properties->FindInOrder( property, iNameOrder );
       
   966 
       
   967     
       
   968     if ( index == KErrNotFound )
       
   969         {
       
   970         if ( metadataType == ECmResolution ) 
       
   971             {
       
   972             TUint width = 0;
       
   973             TUint height = 0;
       
   974             ParseResolution( aValue, width, height );
       
   975             
       
   976             CCmSqlResolutionPropertyItem* resolutionProperty = 
       
   977                 static_cast<CCmSqlResolutionPropertyItem*> ( property );
       
   978             resolutionProperty->SetWidth( width );
       
   979             resolutionProperty->SetHeight( height );
       
   980             resolutionProperty->SetPixelCount( width * height );
       
   981             }
       
   982         
       
   983         property->SetStatus( EFalse );
       
   984         
       
   985         iMetadataDb->SyncAddPropertyItemL( 
       
   986             *property, metadataType );
       
   987         properties->InsertInOrder( property, iNameOrder );
       
   988         id = property->Id();
       
   989         CleanupStack::Pop( property );
       
   990         }
       
   991     else 
       
   992         {
       
   993         id = (*properties)[ index ]->Id();
       
   994         CleanupStack::PopAndDestroy( property );
       
   995         }
       
   996 
       
   997     return id;
       
   998     }
       
   999 
       
  1000 // --------------------------------------------------------------------------
       
  1001 // CCdsSyncImpl::CleanItemData()
       
  1002 // --------------------------------------------------------------------------
       
  1003 void CCdsSyncImpl::CleanItemData() 
       
  1004     {
       
  1005     iCurrentContent = NULL;
       
  1006 
       
  1007     delete iItemId; 
       
  1008     iItemId = NULL;
       
  1009 
       
  1010     delete iArtist; 
       
  1011     iArtist = NULL;
       
  1012 
       
  1013     delete iAlbum; 
       
  1014     iAlbum = NULL;
       
  1015 
       
  1016     delete iTitle; 
       
  1017     iTitle = NULL;
       
  1018 
       
  1019     delete iClass; 
       
  1020     iClass = NULL;
       
  1021 
       
  1022     delete iGenre; 
       
  1023     iGenre = NULL;
       
  1024 
       
  1025     delete iDate; 
       
  1026     iDate = NULL;
       
  1027 
       
  1028     delete iDescription; 
       
  1029     iDescription = NULL;
       
  1030     
       
  1031     delete iAlbumArtUri;
       
  1032     iAlbumArtUri = NULL;
       
  1033 
       
  1034     iResources.ResetAndDestroy();
       
  1035     }
       
  1036 
       
  1037 // --------------------------------------------------------------------------
       
  1038 // CCdsSyncImpl::OnStartDocumentL()
       
  1039 // --------------------------------------------------------------------------
       
  1040 void CCdsSyncImpl::OnStartDocumentL( const RDocumentParameters&/*aDocParam*/, 
       
  1041                                      TInt aErrorCode ) 
       
  1042     {
       
  1043     LOG(_L("[Cds Sync]\t CCdsSyncImpl::OnStartDocumentL"));
       
  1044 
       
  1045     if ( aErrorCode ) 
       
  1046         {
       
  1047         iObserver->SyncErrorL( aErrorCode );
       
  1048         }
       
  1049         
       
  1050     }
       
  1051 
       
  1052 // --------------------------------------------------------------------------
       
  1053 // CCdsSyncImpl::OnEndDocumentL()
       
  1054 // --------------------------------------------------------------------------
       
  1055 void CCdsSyncImpl::OnEndDocumentL( TInt aErrorCode ) 
       
  1056     {
       
  1057     LOG(_L("[Cds Sync]\t CCdsSyncImpl::OnEndDocumentL"));
       
  1058 
       
  1059     if (aErrorCode) 
       
  1060         {
       
  1061         iObserver->SyncErrorL( aErrorCode );
       
  1062         }
       
  1063         
       
  1064 
       
  1065     }
       
  1066 
       
  1067 // --------------------------------------------------------------------------
       
  1068 // CCdsSyncImpl::OnStartElementL(
       
  1069 // --------------------------------------------------------------------------
       
  1070 void CCdsSyncImpl::OnStartElementL( const RTagInfo& aElement, 
       
  1071                                     const RAttributeArray& aAttributes,
       
  1072                                     TInt aErrorCode )
       
  1073     {
       
  1074     
       
  1075     if ( aErrorCode ) 
       
  1076         {
       
  1077         iObserver->SyncErrorL( aErrorCode );
       
  1078         }
       
  1079         
       
  1080     delete iCurrentContent;
       
  1081     iCurrentContent = NULL;
       
  1082         
       
  1083     const TDesC8& name = aElement.LocalName().DesC();
       
  1084     const TDesC8& uri = aElement.Uri().DesC();
       
  1085 
       
  1086     if ( !uri.Compare( KXmlCdsDefaultNamespace ) )
       
  1087         {
       
  1088         if ( !name.Compare( KItem ) ) // <item>
       
  1089             {
       
  1090             TInt id = FindAttribute( KId, _L8(""), aAttributes );
       
  1091             if ( id != KErrNotFound) 
       
  1092                 {
       
  1093                 CleanItemData();
       
  1094                 iItemId = aAttributes[ id ].Value().DesC().AllocL();
       
  1095                 }
       
  1096             }
       
  1097         else if ( !name.Compare( KRes ) ) // <res>
       
  1098             {
       
  1099             
       
  1100             CItemResource* res = CItemResource::NewLC();
       
  1101             
       
  1102             for (TInt i = 0; i < aAttributes.Count(); i++) 
       
  1103                 {
       
  1104                 
       
  1105                 const TDesC8& attrName = 
       
  1106                     aAttributes[i].Attribute().LocalName().DesC();
       
  1107                 HBufC8* attrValue = aAttributes[i].Value().DesC().AllocL();
       
  1108                 
       
  1109                 if ( !attrName.Compare( KBitrate ) )  
       
  1110                     {
       
  1111                     res->iBitrate = attrValue; 
       
  1112                     } 
       
  1113                 else if ( !attrName.Compare( KSize ) )  
       
  1114                     {
       
  1115                     res->iSize = attrValue; 
       
  1116                     } 
       
  1117                 else if ( !attrName.Compare( KDuration ) )  
       
  1118                     {
       
  1119                     res->iDuration = attrValue; 
       
  1120                     } 
       
  1121                 else if ( !attrName.Compare( KResolution ) )  
       
  1122                     {
       
  1123                     res->iResolution = attrValue; 
       
  1124                     } 
       
  1125                 else if ( !attrName.Compare( KProtocolInfo ) )  
       
  1126                     {
       
  1127                     res->iProtocol = attrValue; 
       
  1128                     } 
       
  1129                 }
       
  1130             iResources.AppendL( res );
       
  1131             CleanupStack::Pop( res );
       
  1132             }     
       
  1133         }
       
  1134     }  
       
  1135 
       
  1136 // --------------------------------------------------------------------------
       
  1137 // CCdsSyncImpl::OnEndElementL()
       
  1138 // --------------------------------------------------------------------------
       
  1139 void CCdsSyncImpl::OnEndElementL( const RTagInfo& aElement, 
       
  1140                                   TInt aErrorCode )
       
  1141     {
       
  1142     if ( aErrorCode ) 
       
  1143         {
       
  1144         iObserver->SyncErrorL( aErrorCode );
       
  1145         }
       
  1146         
       
  1147     const TDesC8& name = aElement.LocalName().DesC();
       
  1148     const TDesC8& uri = aElement.Uri().DesC();
       
  1149     
       
  1150     if ( !uri.Compare( KXmlCdsDefaultNamespace ) ) 
       
  1151         // element from DIDL-Lite namespace
       
  1152         {
       
  1153         if ( !name.Compare( KRes ) && iCurrentContent ) // </res>
       
  1154             {
       
  1155             // remove "http://" and IP from URI
       
  1156             TInt httpPos = iCurrentContent->Find( _L8("http://") );
       
  1157             if ( httpPos != KErrNotFound ) 
       
  1158                 {
       
  1159                 TInt ipLength = 
       
  1160                     iCurrentContent->Mid( httpPos + 7 ).Find(_L8("/"));
       
  1161                 if ( ipLength != KErrNotFound ) 
       
  1162                     {
       
  1163                     iCurrentContent->Des().Delete(0, httpPos + 7 + ipLength);
       
  1164                     } 
       
  1165                 } 
       
  1166             iResources[ iResources.Count() - 1 ]->iUri = iCurrentContent;
       
  1167             }
       
  1168         
       
  1169         else if ( !name.Compare( KItem )) // </item>
       
  1170             {
       
  1171             // calc hash and construct item here
       
  1172             HBufC8* hash = CalculateHashL();
       
  1173             CleanupStack::PushL( hash );
       
  1174             HBufC* escapedHash = EscapeHashLC( *hash );
       
  1175             CleanupStack::Pop( escapedHash );
       
  1176 
       
  1177             CleanupStack::PopAndDestroy( hash );
       
  1178             hash = NULL;
       
  1179             CleanupStack::PushL( escapedHash );
       
  1180             
       
  1181             CCmSqlBaseItem* baseItem = CCmSqlBaseItem::NewLC();
       
  1182             baseItem->SetHashL( *escapedHash );
       
  1183             TInt index = iItemsInDb.FindInOrder( baseItem, iHashOrder );
       
  1184             CleanupStack::PopAndDestroy( baseItem );
       
  1185             
       
  1186             if ( index == KErrNotFound ) // new or modified item
       
  1187                 {
       
  1188                 CCmSqlGenericItem* item = NULL;
       
  1189                 
       
  1190                 // find relevant resources
       
  1191                 CItemResource* httpRes = NULL;
       
  1192                 CItemResource* internalRes = NULL;
       
  1193                 for ( TInt i=0; i < iResources.Count(); i++ )
       
  1194                     {
       
  1195                     HBufC8* protocol = iResources[ i ]->iProtocol;
       
  1196                     if ( protocol )
       
  1197                         {
       
  1198                         if ( !httpRes && 
       
  1199                               protocol->Find(_L8("http-get:")) 
       
  1200                                 != KErrNotFound )
       
  1201                             {
       
  1202                             httpRes = iResources[ i ];
       
  1203                             }
       
  1204                         else if ( !internalRes &&
       
  1205                                    protocol->Find(_L8("internal:")) 
       
  1206                                     != KErrNotFound )
       
  1207                             {
       
  1208                             internalRes = iResources[ i ];
       
  1209                             }
       
  1210                         }
       
  1211                     }
       
  1212                 
       
  1213                 if( iClass && iClass->Find( KAudioBroadCastItem ) != 
       
  1214                     KErrNotFound )
       
  1215                     {
       
  1216                     // create audio item and set audio specific properties
       
  1217                     CCmSqlAudioItem* audioItem = CCmSqlAudioItem::NewLC();
       
  1218                     audioItem->SetMediaType( ECmAudioBroadCast );
       
  1219                     if ( iGenre ) 
       
  1220                         {
       
  1221                         audioItem->SetGenreId( 
       
  1222                             GetPropertyIdL( KGenreIndex, *iGenre ) );                        
       
  1223                         }
       
  1224                     item = audioItem;
       
  1225                     CleanupStack::Pop( audioItem );
       
  1226                     }
       
  1227                     
       
  1228                 else if( iClass && iClass->Find( KVideoBroadCastItem ) != 
       
  1229                     KErrNotFound  )
       
  1230                     {
       
  1231                     // create video item and set image specific properties
       
  1232                     CCmSqlVideoItem* videoItem = CCmSqlVideoItem::NewLC();
       
  1233                     videoItem->SetMediaType( ECmVideoBroadCast );
       
  1234                     if ( iGenre ) 
       
  1235                         {
       
  1236                         videoItem->SetGenreId( 
       
  1237                             GetPropertyIdL( KGenreIndex, *iGenre ) );                        
       
  1238                         }
       
  1239                     item = videoItem;
       
  1240                     CleanupStack::Pop( videoItem );                    
       
  1241                     }
       
  1242                     
       
  1243                 else if ( iClass && 
       
  1244                           iClass->Find( KAudioItem ) != KErrNotFound )
       
  1245                     {
       
  1246                     // create audio item and set audio specific properties
       
  1247                     CCmSqlAudioItem* audioItem = CCmSqlAudioItem::NewLC();
       
  1248                     audioItem->SetMediaType( ECmAudio );
       
  1249                     if ( iAlbum ) 
       
  1250                         {
       
  1251                         audioItem->SetAlbumId( 
       
  1252                             GetPropertyIdL( KAlbumIndex, *iAlbum ) );                        
       
  1253                         }
       
  1254                     if ( iArtist ) 
       
  1255                         {
       
  1256                         audioItem->SetArtistId( 
       
  1257                             GetPropertyIdL( KArtistIndex, *iArtist ) );                        
       
  1258                         }
       
  1259                     if ( iGenre ) 
       
  1260                         {
       
  1261                         audioItem->SetGenreId( 
       
  1262                             GetPropertyIdL( KGenreIndex, *iGenre ) );                        
       
  1263                         }
       
  1264                     if( iAlbumArtUri )
       
  1265                         {
       
  1266                         audioItem->SetAlbumArtUriL( *iAlbumArtUri );
       
  1267                         }
       
  1268                     if ( httpRes && httpRes->iDuration )
       
  1269                         {
       
  1270                         audioItem->SetDuration( 
       
  1271                             (TInt) ParseDuration( *httpRes->iDuration ) );
       
  1272                         }
       
  1273                     if ( httpRes && httpRes->iBitrate )
       
  1274                         {
       
  1275                         audioItem->SetBitrate( 
       
  1276                             ParseUint( *httpRes->iBitrate ) );
       
  1277                         }
       
  1278                     item = audioItem;
       
  1279                     CleanupStack::Pop( audioItem );
       
  1280                     }
       
  1281                 
       
  1282                 else if ( iClass && 
       
  1283                           iClass->Find( KImageItem ) != KErrNotFound )
       
  1284                     {
       
  1285                     // create image item and set image specific properties
       
  1286                     CCmSqlImageItem* imageItem = CCmSqlImageItem::NewLC();
       
  1287                     imageItem->SetMediaType( ECmImage );
       
  1288                     
       
  1289                     if ( iDescription )
       
  1290                         {
       
  1291                         imageItem->SetDescriptionL( *iDescription );
       
  1292                         }
       
  1293                     if ( internalRes && internalRes->iResolution )
       
  1294                         {
       
  1295                         imageItem->SetResolutionId(
       
  1296                             GetPropertyIdL( KResolutionIndex, 
       
  1297                                 *internalRes->iResolution ));
       
  1298                         }
       
  1299                     item = imageItem;
       
  1300                     CleanupStack::Pop( imageItem );
       
  1301                     }
       
  1302                 else if ( iClass && 
       
  1303                           iClass->Find( KVideoItem ) != KErrNotFound )
       
  1304                     {
       
  1305                     // create video item and set image specific properties
       
  1306                     CCmSqlVideoItem* videoItem = CCmSqlVideoItem::NewLC();
       
  1307                     videoItem->SetMediaType( ECmVideo );
       
  1308                     if ( iGenre ) 
       
  1309                         {
       
  1310                         videoItem->SetGenreId( 
       
  1311                             GetPropertyIdL( KGenreIndex, *iGenre ) );                        
       
  1312                         }
       
  1313                     item = videoItem;
       
  1314                     CleanupStack::Pop( videoItem );
       
  1315                     }
       
  1316 
       
  1317                 if ( item )
       
  1318                     {
       
  1319                     CleanupStack::PushL( item );
       
  1320                     // Parsing dlna profile id from protocol info
       
  1321                     ParseProfileIdL( *item, *httpRes );
       
  1322                     ParseProfileIdL( *item, *internalRes );
       
  1323                     // set general properties
       
  1324                     item->SetHashL( *escapedHash );
       
  1325                     item->SetCdsIdL( *iItemId );
       
  1326                     if ( iClass ) 
       
  1327                         {
       
  1328                         item->SetUpnpclassId( 
       
  1329                             GetPropertyIdL( KClassIndex, *iClass ) );                        
       
  1330                         }
       
  1331                     if ( iTitle )
       
  1332                         {
       
  1333                         item->SetTitleL( *iTitle );
       
  1334                         }
       
  1335                     if ( iDate )
       
  1336                         {
       
  1337                         item->SetDate( ParseTime( *iDate ) );
       
  1338                         }
       
  1339                     if ( httpRes && httpRes->iUri )
       
  1340                         {
       
  1341                         item->SetUriL( *httpRes->iUri );
       
  1342                         }
       
  1343                     if ( httpRes && httpRes->iSize )
       
  1344                         {
       
  1345                         item->SetSize( ParseUint( *httpRes->iSize ) );
       
  1346                         }
       
  1347                     else if ( internalRes && internalRes->iSize ) 
       
  1348                         {
       
  1349                         item->SetSize( ParseUint( *internalRes->iSize ) );
       
  1350                         }
       
  1351                     TTime currentTime;
       
  1352                     currentTime.HomeTime();
       
  1353                     item->SetHarvestDate( currentTime );
       
  1354                     item->SetSearchId( iSearchIndex );
       
  1355                     iItemsToAdd.AppendL( item ); // transfer ownership
       
  1356                     ProgressL(1);
       
  1357                     iProcessedItems++;
       
  1358                     CleanupStack::Pop( item );
       
  1359                     }
       
  1360                 else
       
  1361                     {
       
  1362                     LOG(_L("[Cds Sync]\t item == NULL "));
       
  1363                     }                    
       
  1364                 }
       
  1365             else // unchanged item
       
  1366                 {
       
  1367                 CCmSqlBaseItem* itemToRemove = iItemsInDb[ index ];
       
  1368                 iItemsInDb.Remove( index );
       
  1369                 ProgressL(1);
       
  1370                 iProcessedItems++;
       
  1371                 delete itemToRemove;
       
  1372                 }
       
  1373             CleanItemData();
       
  1374             CleanupStack::PopAndDestroy( escapedHash );
       
  1375             }
       
  1376         }
       
  1377     
       
  1378     else if ( !uri.Compare( KXmlCdsDcNamespace ) ) 
       
  1379         // element from dc namespace
       
  1380         {
       
  1381         if ( !name.Compare( KTitle ) ) // </title>
       
  1382             {
       
  1383             iTitle = iCurrentContent;
       
  1384             }
       
  1385         else if ( !name.Compare( KDate ) ) // </date>
       
  1386             {
       
  1387             iDate = iCurrentContent;
       
  1388             }
       
  1389         else if ( !name.Compare( KDescription ) ) // </description>
       
  1390             {
       
  1391             iDescription = iCurrentContent;
       
  1392             }          
       
  1393         }
       
  1394     
       
  1395     else if ( !uri.Compare( KXmlCdsUpnpNamespace ) ) 
       
  1396         // element from UPnP namespace
       
  1397         {
       
  1398         if ( !name.Compare( KAlbum ) ) // </album>
       
  1399             {
       
  1400             iAlbum = iCurrentContent;
       
  1401             }
       
  1402         else if ( !name.Compare( KArtist ) ) // </artist>
       
  1403             {
       
  1404             iArtist = iCurrentContent;
       
  1405             }
       
  1406         else if ( !name.Compare( KClass ) ) // </class>
       
  1407             {
       
  1408             iClass = iCurrentContent;
       
  1409             }
       
  1410         else if ( !name.Compare( KGenre ) ) // </genre>
       
  1411             {
       
  1412             iGenre = iCurrentContent;
       
  1413             }
       
  1414         else if ( !name.Compare( KAlbumArtUri ) ) // </albumarturi>
       
  1415             {
       
  1416             // Parse uri removes ip and port for iCurrentContent
       
  1417             ParseUri();
       
  1418             iAlbumArtUri = iCurrentContent;
       
  1419             }              
       
  1420         }
       
  1421     else
       
  1422         {
       
  1423         delete iCurrentContent;
       
  1424         }        
       
  1425     
       
  1426     iCurrentContent = NULL;
       
  1427     }
       
  1428 
       
  1429 // --------------------------------------------------------------------------
       
  1430 // CCdsSyncImpl::OnContentL()
       
  1431 // --------------------------------------------------------------------------
       
  1432 void CCdsSyncImpl::OnContentL( const TDesC8& aBytes, TInt aErrorCode )
       
  1433     {
       
  1434     if ( aErrorCode ) 
       
  1435         {
       
  1436         iObserver->SyncErrorL( aErrorCode );
       
  1437         }                
       
  1438     if ( iCurrentContent )
       
  1439         {
       
  1440         if( iCurrentContent->Length() + aBytes.Length() < 
       
  1441             KCdsSyncMaxBufLength )
       
  1442             {
       
  1443             iCurrentContent->Des().Append( aBytes );
       
  1444             }
       
  1445         else
       
  1446             {
       
  1447             iCurrentContent = iCurrentContent->ReAllocL( 
       
  1448                 iCurrentContent->Length() + aBytes.Length() );
       
  1449             iCurrentContent->Des().Append( aBytes );                
       
  1450             }
       
  1451         }
       
  1452     else 
       
  1453         {
       
  1454         iCurrentContent = HBufC8::NewL( KCdsSyncMaxBufLength );
       
  1455         iCurrentContent->Des().Append( aBytes );
       
  1456         }        
       
  1457     }
       
  1458 
       
  1459 // --------------------------------------------------------------------------
       
  1460 // CCdsSyncImpl::OnStartPrefixMappingL()
       
  1461 // --------------------------------------------------------------------------
       
  1462 void CCdsSyncImpl::OnStartPrefixMappingL( const RString& /* aPrefix */, 
       
  1463                                           const RString& /* aUri */, 
       
  1464                                           TInt aErrorCode ) 
       
  1465     {
       
  1466     if (aErrorCode) 
       
  1467         {
       
  1468         iObserver->SyncErrorL( aErrorCode );
       
  1469         }
       
  1470         
       
  1471     
       
  1472     }
       
  1473 
       
  1474 // --------------------------------------------------------------------------
       
  1475 // CCdsSyncImpl::OnEndPrefixMappingL()
       
  1476 // --------------------------------------------------------------------------
       
  1477 void CCdsSyncImpl::OnEndPrefixMappingL( const RString& /* aPrefix */, 
       
  1478                                         TInt aErrorCode )
       
  1479     {
       
  1480     if (aErrorCode) 
       
  1481         {
       
  1482         iObserver->SyncErrorL( aErrorCode );
       
  1483         }
       
  1484     }
       
  1485 
       
  1486 // --------------------------------------------------------------------------
       
  1487 // CCdsSyncImpl::OnIgnorableWhiteSpaceL()
       
  1488 // --------------------------------------------------------------------------
       
  1489 void CCdsSyncImpl::OnIgnorableWhiteSpaceL( const TDesC8& /* aBytes */, 
       
  1490                                            TInt aErrorCode ) 
       
  1491     {
       
  1492     if (aErrorCode) 
       
  1493         {
       
  1494         iObserver->SyncErrorL( aErrorCode );
       
  1495         }
       
  1496     }
       
  1497 
       
  1498 // --------------------------------------------------------------------------
       
  1499 // CCdsSyncImpl::OnSkippedEntityL()
       
  1500 // --------------------------------------------------------------------------
       
  1501 void CCdsSyncImpl::OnSkippedEntityL( const RString& /* aName */, 
       
  1502                                      TInt aErrorCode ) 
       
  1503     {
       
  1504     if (aErrorCode) 
       
  1505         {
       
  1506         iObserver->SyncErrorL( aErrorCode );
       
  1507         }
       
  1508     }
       
  1509 
       
  1510 // --------------------------------------------------------------------------
       
  1511 // CCdsSyncImpl::OnProcessingInstructionL()
       
  1512 // --------------------------------------------------------------------------
       
  1513 void CCdsSyncImpl::OnProcessingInstructionL( const TDesC8& /* aTarget */, 
       
  1514                                              const TDesC8& /* aData */, 
       
  1515                                              TInt aErrorCode ) 
       
  1516     {
       
  1517     if (aErrorCode) 
       
  1518         {
       
  1519         iObserver->SyncErrorL( aErrorCode );
       
  1520         }
       
  1521     }
       
  1522 
       
  1523 // --------------------------------------------------------------------------
       
  1524 // void CCdsSyncImpl::OnError() 
       
  1525 // --------------------------------------------------------------------------
       
  1526 void CCdsSyncImpl::OnError( TInt aErrorCode ) 
       
  1527     {
       
  1528     if (aErrorCode && iState != ECdsSyncIdle) 
       
  1529         {
       
  1530         TRAP_IGNORE( iObserver->SyncErrorL( aErrorCode ) );
       
  1531         }
       
  1532         
       
  1533     
       
  1534     }
       
  1535 
       
  1536 // --------------------------------------------------------------------------
       
  1537 // CCdsSyncImpl::GetExtendedInterface() 
       
  1538 // --------------------------------------------------------------------------
       
  1539 TAny* CCdsSyncImpl::GetExtendedInterface( const TInt32 /* aUid */ ) 
       
  1540     {
       
  1541     return NULL;    
       
  1542     }
       
  1543 
       
  1544 // --------------------------------------------------------------------------
       
  1545 // CCdsSyncImpl::ParseProfileIdL()
       
  1546 // --------------------------------------------------------------------------
       
  1547 void CCdsSyncImpl::ParseProfileIdL( 
       
  1548     CCmSqlGenericItem& aItem, 
       
  1549     const CItemResource& aRes ) const
       
  1550     {
       
  1551     if( &aRes && &aItem )
       
  1552         {
       
  1553         TInt index( aRes.iProtocol->Find( KDlnaPn() ) );
       
  1554         if( KErrNotFound != index )
       
  1555             {
       
  1556             TInt index2( aRes.iProtocol->Find( KSemicolon() ) );
       
  1557             if( KErrNotFound != index2 )
       
  1558                 {                        
       
  1559                 HBufC8* temp = 
       
  1560                     aRes.iProtocol->Mid( 
       
  1561                         index + KDlnaPn().Length(), 
       
  1562                         index2 - ( index + KDlnaPn().Length() ) ).AllocLC();
       
  1563                 aItem.SetUpnpProfileId( 
       
  1564                     GetPropertyIdL( KUpnpProfileIndex, *temp ) );
       
  1565                 CleanupStack::PopAndDestroy( temp );
       
  1566                 }
       
  1567             }
       
  1568         }     
       
  1569     }
       
  1570 
       
  1571 // --------------------------------------------------------------------------
       
  1572 // CCdsSyncImpl::RemoveUnchangedItems()
       
  1573 // --------------------------------------------------------------------------
       
  1574 void CCdsSyncImpl::RemoveUnchangedItems()
       
  1575     {
       
  1576     for( TInt i = iItemsInDb.Count() - 1; i >= 0; i-- )
       
  1577         {
       
  1578         if( iItemsInDb[i]->SearchId() < iSearchIndex )
       
  1579             {
       
  1580             CCmSqlBaseItem* itemToRemove = iItemsInDb[ i ];
       
  1581             iItemsInDb.Remove( i );
       
  1582             delete itemToRemove;            
       
  1583             }
       
  1584         }    
       
  1585     }
       
  1586 
       
  1587 // --------------------------------------------------------------------------
       
  1588 // CCdsSyncImpl::ParseUri()
       
  1589 // --------------------------------------------------------------------------
       
  1590 void CCdsSyncImpl::ParseUri()
       
  1591     {
       
  1592     // Removes ip and port from iCurrentContent
       
  1593     TInt httpPos = iCurrentContent->Find( _L8("http://") );
       
  1594     if ( httpPos != KErrNotFound ) 
       
  1595         {
       
  1596         TInt ipLength = 
       
  1597             iCurrentContent->Mid( httpPos + 7 ).Find(_L8("/"));
       
  1598         if ( ipLength != KErrNotFound ) 
       
  1599             {
       
  1600             iCurrentContent->Des().Delete(0, httpPos + 7 + ipLength);
       
  1601             } 
       
  1602         }  
       
  1603     }
       
  1604     
       
  1605 // End of file