|
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.Append( 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.Append( 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.Append( 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 |