34 const TInt KMinimumConfidenceRequired = 60; |
34 const TInt KMinimumConfidenceRequired = 60; |
35 const TInt KPathStartingChars = 3; |
35 const TInt KPathStartingChars = 3; |
36 |
36 |
37 // ============================ MEMBER FUNCTIONS ============================== |
37 // ============================ MEMBER FUNCTIONS ============================== |
38 // ---------------------------------------------------------------------------- |
38 // ---------------------------------------------------------------------------- |
39 // Constructor. |
39 // Constructor. |
40 // ---------------------------------------------------------------------------- |
40 // ---------------------------------------------------------------------------- |
41 EXPORT_C CMPXM3uPlaylistImporter::CMPXM3uPlaylistImporter( |
41 EXPORT_C CMPXM3uPlaylistImporter::CMPXM3uPlaylistImporter( |
42 RFs* aFs, |
42 RFs* aFs, |
43 MMPXPlaylistPluginObserver* aObserver, |
43 MMPXPlaylistPluginObserver* aObserver, |
44 const CArrayFix<CCnvCharacterSetConverter::SCharacterSet>& aTopCharacterSet, |
44 const CArrayFix<CCnvCharacterSetConverter::SCharacterSet>& aTopCharacterSet, |
69 |
69 |
70 __ASSERT_DEBUG(aPlaylistUri.Length() != 0, User::Leave(KErrArgument)); |
70 __ASSERT_DEBUG(aPlaylistUri.Length() != 0, User::Leave(KErrArgument)); |
71 iPlaylistFilePath.Set(aPlaylistUri); |
71 iPlaylistFilePath.Set(aPlaylistUri); |
72 |
72 |
73 iAutoEncodingPlaylistArray = CMPXMediaArray::NewL(); |
73 iAutoEncodingPlaylistArray = CMPXMediaArray::NewL(); |
74 |
74 |
75 *iCallerStatus = KRequestPending; |
75 *iCallerStatus = KRequestPending; |
76 |
76 |
77 TRequestStatus* status = &iStatus; |
77 TRequestStatus* status = &iStatus; |
78 *status = KRequestPending; |
78 *status = KRequestPending; |
79 User::RequestComplete(status, KErrNone); |
79 User::RequestComplete(status, KErrNone); |
80 SetActive(); |
80 SetActive(); |
81 |
81 |
82 MPX_DEBUG1("CMPXM3uPlaylistImporter::ConstructL() exiting"); |
82 MPX_DEBUG1("CMPXM3uPlaylistImporter::ConstructL() exiting"); |
83 } |
83 } |
84 |
84 |
85 // ---------------------------------------------------------------------------- |
85 // ---------------------------------------------------------------------------- |
86 // Two-phased constructor. |
86 // Two-phased constructor. |
87 // ---------------------------------------------------------------------------- |
87 // ---------------------------------------------------------------------------- |
88 EXPORT_C CMPXM3uPlaylistImporter* CMPXM3uPlaylistImporter::NewL( |
88 EXPORT_C CMPXM3uPlaylistImporter* CMPXM3uPlaylistImporter::NewL( |
89 RFs* aFs, |
89 RFs* aFs, |
90 MMPXPlaylistPluginObserver* aObserver, |
90 MMPXPlaylistPluginObserver* aObserver, |
91 const TDesC& aPlaylistUri, |
91 const TDesC& aPlaylistUri, |
92 const CArrayFix<CCnvCharacterSetConverter::SCharacterSet>& aTopCharacterSet, |
92 const CArrayFix<CCnvCharacterSetConverter::SCharacterSet>& aTopCharacterSet, |
93 const CArrayFix<CCnvCharacterSetConverter::SCharacterSet>& aAvailableCharacterSet, |
93 const CArrayFix<CCnvCharacterSetConverter::SCharacterSet>& aAvailableCharacterSet, |
94 TRequestStatus& aStatus ) |
94 TRequestStatus& aStatus ) |
95 { |
95 { |
96 CMPXM3uPlaylistImporter* self = |
96 CMPXM3uPlaylistImporter* self = |
97 new(ELeave)CMPXM3uPlaylistImporter( |
97 new(ELeave)CMPXM3uPlaylistImporter( |
98 aFs, aObserver, aTopCharacterSet, aAvailableCharacterSet, aStatus ); |
98 aFs, aObserver, aTopCharacterSet, aAvailableCharacterSet, aStatus ); |
99 CleanupStack::PushL( self ); |
99 CleanupStack::PushL( self ); |
117 // ---------------------------------------------------------------------------- |
117 // ---------------------------------------------------------------------------- |
118 // |
118 // |
119 EXPORT_C void CMPXM3uPlaylistImporter::RunL() |
119 EXPORT_C void CMPXM3uPlaylistImporter::RunL() |
120 { |
120 { |
121 MPX_DEBUG1("CMPXM3uPlaylistImporter::RunL"); |
121 MPX_DEBUG1("CMPXM3uPlaylistImporter::RunL"); |
122 |
122 |
123 if ( iMoreToDo && iStatus.Int() == KErrNone ) |
123 if ( iMoreToDo && iStatus.Int() == KErrNone ) |
124 { |
124 { |
125 DoTaskStep(); |
125 DoTaskStep(); |
126 SetActive(); |
126 SetActive(); |
127 } |
127 } |
128 else |
128 else |
129 { |
129 { |
130 User::RequestComplete( iCallerStatus, iStatus.Int() ); |
130 User::RequestComplete( iCallerStatus, iStatus.Int() ); |
131 NotifyClient(iStatus.Int()); |
131 NotifyClient(iStatus.Int()); |
132 Cleanup(); |
132 Cleanup(); |
133 } |
133 } |
134 } |
134 } |
135 |
135 |
136 // ---------------------------------------------------------------------------- |
136 // ---------------------------------------------------------------------------- |
137 // Implements cancellation of an outstanding request. |
137 // Implements cancellation of an outstanding request. |
138 // ---------------------------------------------------------------------------- |
138 // ---------------------------------------------------------------------------- |
139 // |
139 // |
140 EXPORT_C void CMPXM3uPlaylistImporter::DoCancel() |
140 EXPORT_C void CMPXM3uPlaylistImporter::DoCancel() |
141 { |
141 { |
142 MPX_DEBUG1("CMPXM3uPlaylistImporter::DoCancel"); |
142 MPX_DEBUG1("CMPXM3uPlaylistImporter::DoCancel"); |
143 |
143 |
144 TInt error( KErrCancel ); |
144 TInt error( KErrCancel ); |
145 |
145 |
146 // notify client that the request has been cancelled |
146 // notify client that the request has been cancelled |
147 NotifyClient(error); |
147 NotifyClient(error); |
148 |
148 |
149 Cleanup(); |
149 Cleanup(); |
150 |
150 |
151 if ( iCallerStatus ) |
151 if ( iCallerStatus ) |
152 { |
152 { |
153 User::RequestComplete( iCallerStatus, error ); |
153 User::RequestComplete( iCallerStatus, error ); |
154 } |
154 } |
155 } |
155 } |
159 // ---------------------------------------------------------------------------- |
159 // ---------------------------------------------------------------------------- |
160 // |
160 // |
161 EXPORT_C void CMPXM3uPlaylistImporter::DoTaskStep() |
161 EXPORT_C void CMPXM3uPlaylistImporter::DoTaskStep() |
162 { |
162 { |
163 MPX_DEBUG1("CMPXM3uPlaylistImporter::DoTaskStep()"); |
163 MPX_DEBUG1("CMPXM3uPlaylistImporter::DoTaskStep()"); |
164 |
164 |
165 TRequestStatus* status = &iStatus; |
165 TRequestStatus* status = &iStatus; |
166 *status = KRequestPending; |
166 *status = KRequestPending; |
167 |
167 |
168 TInt error( KErrNone ); |
168 TInt error( KErrNone ); |
169 |
169 |
170 MPX_TRAP( error, DoTaskStepL() ); |
170 MPX_TRAP( error, DoTaskStepL() ); |
171 |
171 |
172 User::RequestComplete( status, error ); |
172 User::RequestComplete( status, error ); |
173 } |
173 } |
174 |
174 |
175 // ---------------------------------------------------------------------------- |
175 // ---------------------------------------------------------------------------- |
176 // Performs one step of the task. Leaves when an error is encountered |
176 // Performs one step of the task. Leaves when an error is encountered |
177 // ---------------------------------------------------------------------------- |
177 // ---------------------------------------------------------------------------- |
178 // |
178 // |
179 EXPORT_C void CMPXM3uPlaylistImporter::DoTaskStepL() |
179 EXPORT_C void CMPXM3uPlaylistImporter::DoTaskStepL() |
180 { |
180 { |
181 MPX_DEBUG1("CMPXM3uPlaylistImporter::DoTaskStepL()"); |
181 MPX_DEBUG1("CMPXM3uPlaylistImporter::DoTaskStepL()"); |
182 |
182 |
183 switch( iState ) |
183 switch( iState ) |
184 { |
184 { |
185 case EMPXM3UReadBufferWithAutoDetectEncoding: |
185 case EMPXM3UReadBufferWithAutoDetectEncoding: |
186 { |
186 { |
187 ReadPlaylistFileToBufferL(); |
187 ReadPlaylistFileToBufferL(); |
188 iState = EMPXM3UParseWithAutoDetectEncoding; |
188 iState = EMPXM3UParseWithAutoDetectEncoding; |
189 } |
189 } |
190 break; |
190 break; |
191 |
191 |
192 case EMPXM3UParseWithAutoDetectEncoding: |
192 case EMPXM3UParseWithAutoDetectEncoding: |
193 { |
193 { |
194 ParsePlaylistBufferL( |
194 ParsePlaylistBufferL( |
195 *iAutoEncodingPlaylistArray, iAutoEncodingInvalidItems ); |
195 *iAutoEncodingPlaylistArray, iAutoEncodingInvalidItems ); |
196 |
196 |
197 // If at the moment, we know that there is at least one error parsing |
197 // If at the moment, we know that there is at least one error parsing |
198 // with auto detect encoding, we don't need to proceed until end of |
198 // with auto detect encoding, we don't need to proceed until end of |
199 // file anymore, this playlist file is concluded to be corrupted |
199 // file anymore, this playlist file is concluded to be corrupted |
200 if ( iAutoEncodingInvalidItems > 0 ) |
200 if ( iAutoEncodingInvalidItems > 0 ) |
201 { |
201 { |
202 delete iAutoEncodingPlaylistArray; |
202 delete iAutoEncodingPlaylistArray; |
203 iAutoEncodingPlaylistArray = NULL; |
203 iAutoEncodingPlaylistArray = NULL; |
204 |
204 |
205 User::Leave(KErrCorrupt); |
205 User::Leave(KErrCorrupt); |
206 } |
206 } |
207 |
207 |
208 // we've finished parsing with auto detect encoding we will return |
208 // we've finished parsing with auto detect encoding we will return |
209 // the playlist parsed with auto encoding |
209 // the playlist parsed with auto encoding |
210 else if ( iEndOfFile ) |
210 else if ( iEndOfFile ) |
211 { |
211 { |
212 iState = EMPXM3UComposePlaylistMedia; |
212 iState = EMPXM3UComposePlaylistMedia; |
213 } |
213 } |
214 } |
214 } |
215 break; |
215 break; |
216 |
216 |
217 case EMPXM3UComposePlaylistMedia: |
217 case EMPXM3UComposePlaylistMedia: |
218 { |
218 { |
219 ComposePlaylistL(); |
219 ComposePlaylistL(); |
220 iMoreToDo = EFalse; |
220 iMoreToDo = EFalse; |
221 } |
221 } |
222 break; |
222 break; |
223 |
223 |
224 default: |
224 default: |
225 { |
225 { |
226 User::Leave(KErrAbort); |
226 User::Leave(KErrAbort); |
227 } |
227 } |
228 break; |
228 break; |
233 // CMPXM3uPlaylistImporter::ReadPlaylistFileToBufferL |
233 // CMPXM3uPlaylistImporter::ReadPlaylistFileToBufferL |
234 // ----------------------------------------------------------------------------- |
234 // ----------------------------------------------------------------------------- |
235 // |
235 // |
236 void CMPXM3uPlaylistImporter::ReadPlaylistFileToBufferL() |
236 void CMPXM3uPlaylistImporter::ReadPlaylistFileToBufferL() |
237 { |
237 { |
238 MPX_DEBUG2("Before reading playlist to buffer: heap size = %d", User::Heap().Size()); |
238 MPX_DEBUG2("Before reading playlist to buffer: heap size = %d", User::Heap().Size()); |
239 |
239 |
240 delete iBuffer; |
240 delete iBuffer; |
241 iBuffer = NULL; |
241 iBuffer = NULL; |
242 iBufferPtr.Set(KNullDesC); |
242 iBufferPtr.Set(KNullDesC); |
243 |
243 |
244 // |
244 // |
245 // leave with KErrNotFound if the playlist file does not exist |
245 // leave with KErrNotFound if the playlist file does not exist |
246 // |
246 // |
247 if (!BaflUtils::FileExists(*iFs, iPlaylistFilePath)) |
247 if (!BaflUtils::FileExists(*iFs, iPlaylistFilePath)) |
248 { |
248 { |
249 User::Leave(KErrNotFound); |
249 User::Leave(KErrNotFound); |
250 } |
250 } |
251 |
251 |
252 TEntry entry; |
252 TEntry entry; |
253 User::LeaveIfError(iFs->Entry(iPlaylistFilePath, entry)); |
253 User::LeaveIfError(iFs->Entry(iPlaylistFilePath, entry)); |
254 |
254 |
255 HBufC* buffer = HBufC::NewLC(entry.iSize); |
255 HBufC* buffer = HBufC::NewLC(entry.iSize); |
256 TPtr ptr = buffer->Des(); |
256 TPtr ptr = buffer->Des(); |
257 |
257 |
258 HBufC8* buf8 = HBufC8::NewLC(entry.iSize); |
258 HBufC8* buf8 = HBufC8::NewLC(entry.iSize); |
259 TPtr8 ptr8 = buf8->Des(); |
259 TPtr8 ptr8 = buf8->Des(); |
269 |
269 |
270 // auto detect character encoding |
270 // auto detect character encoding |
271 TUint charSetId(0); |
271 TUint charSetId(0); |
272 TInt error = DetectCharacterSetL(*buf8, iTopCharacterSet, charSetId); |
272 TInt error = DetectCharacterSetL(*buf8, iTopCharacterSet, charSetId); |
273 MPX_DEBUG3("encoding detected using top character set is 0x%x, error %d", charSetId, error); |
273 MPX_DEBUG3("encoding detected using top character set is 0x%x, error %d", charSetId, error); |
274 |
274 |
275 // when we fail to detect the encoding, use all available character set in the |
275 // when we fail to detect the encoding, use all available character set in the |
276 // system to try again. If that also fails, abandon the operation. |
276 // system to try again. If that also fails, abandon the operation. |
277 if (error) |
277 if (error) |
278 { |
278 { |
279 User::LeaveIfError(DetectCharacterSetL(*buf8, iAvailableCharacterSet, charSetId)); |
279 User::LeaveIfError(DetectCharacterSetL(*buf8, iAvailableCharacterSet, charSetId)); |
280 MPX_DEBUG2("encoding detected using available character set is 0x%x", charSetId); |
280 MPX_DEBUG2("encoding detected using available character set is 0x%x", charSetId); |
281 } |
281 } |
282 |
282 |
283 // read the whole file if the sample taken isn't the whole file |
283 // read the whole file if the sample taken isn't the whole file |
284 if (sampleLength != entry.iSize) |
284 if (sampleLength != entry.iSize) |
285 { |
285 { |
286 User::LeaveIfError(iFs->ReadFileSection( |
286 User::LeaveIfError(iFs->ReadFileSection( |
287 iPlaylistFilePath, 0, ptr8, entry.iSize)); |
287 iPlaylistFilePath, 0, ptr8, entry.iSize)); |
288 } |
288 } |
289 |
289 |
290 // perform character conversion using the selected encoding |
290 // perform character conversion using the selected encoding |
291 TInt state(CCnvCharacterSetConverter::KStateDefault); |
291 TInt state(CCnvCharacterSetConverter::KStateDefault); |
292 TInt numOfUnconvertibleChars(0); |
292 TInt numOfUnconvertibleChars(0); |
293 CCnvCharacterSetConverter* charSetConv = CCnvCharacterSetConverter::NewLC(); |
293 CCnvCharacterSetConverter* charSetConv = CCnvCharacterSetConverter::NewLC(); |
294 charSetConv->PrepareToConvertToOrFromL(charSetId, iAvailableCharacterSet, *iFs); |
294 charSetConv->PrepareToConvertToOrFromL(charSetId, iAvailableCharacterSet, *iFs); |
304 retVal = 0; |
304 retVal = 0; |
305 User::LeaveIfError(DetectCharacterSetL(*buf8, iAvailableCharacterSet, charSetId)); |
305 User::LeaveIfError(DetectCharacterSetL(*buf8, iAvailableCharacterSet, charSetId)); |
306 charSetConv->PrepareToConvertToOrFromL(charSetId, iAvailableCharacterSet, *iFs); |
306 charSetConv->PrepareToConvertToOrFromL(charSetId, iAvailableCharacterSet, *iFs); |
307 retVal = charSetConv->ConvertToUnicode(ptr, *buf8, state, numOfUnconvertibleChars); |
307 retVal = charSetConv->ConvertToUnicode(ptr, *buf8, state, numOfUnconvertibleChars); |
308 } |
308 } |
309 |
309 |
310 if (retVal > 0 || numOfUnconvertibleChars > 0) |
310 if (retVal > 0 || numOfUnconvertibleChars > 0) |
311 { |
311 { |
312 MPX_DEBUG3("Unable to find character encoding for the playlist file. retVal = %d, numOfUnconvertibleChars = %d", |
312 MPX_DEBUG3("Unable to find character encoding for the playlist file. retVal = %d, numOfUnconvertibleChars = %d", |
313 retVal, numOfUnconvertibleChars); |
313 retVal, numOfUnconvertibleChars); |
314 User::Leave(KErrNotSupported); |
314 User::Leave(KErrNotSupported); |
315 } |
315 } |
316 |
316 |
317 // remove the byte order mark (BOM) character prepended at the beginning |
317 // remove the byte order mark (BOM) character prepended at the beginning |
318 // of the stream if encoded with unicode as per Unicode section 2.4 |
318 // of the stream if encoded with unicode as per Unicode section 2.4 |
319 if ((charSetId == KCharacterSetIdentifierUnicodeLittle || |
319 if ((charSetId == KCharacterSetIdentifierUnicodeLittle || |
320 charSetId == KCharacterSetIdentifierUnicodeBig) && |
320 charSetId == KCharacterSetIdentifierUnicodeBig) && |
321 ptr.Length() > 0 && |
321 ptr.Length() > 0 && |
322 ptr[0] == KUnicodeBOM) |
322 ptr[0] == KUnicodeBOM) |
323 { |
323 { |
324 ptr.Delete(0,1); |
324 ptr.Delete(0,1); |
325 } |
325 } |
326 |
326 |
327 iBuffer = buffer; |
327 iBuffer = buffer; |
328 iBufferPtr.Set(*iBuffer); |
328 iBufferPtr.Set(*iBuffer); |
329 |
329 |
330 CleanupStack::PopAndDestroy(2, buf8); // charSetConv & buf8 |
330 CleanupStack::PopAndDestroy(2, buf8); // charSetConv & buf8 |
331 CleanupStack::Pop(buffer); |
331 CleanupStack::Pop(buffer); |
332 |
332 |
333 // brand new buffer which hasn't been read, reset iCurrentLineNumber and |
333 // brand new buffer which hasn't been read, reset iCurrentLineNumber and |
334 // iEndLineNumber, and iEndOfFile |
334 // iEndLineNumber, and iEndOfFile |
335 iCurrentLineNumber = 0; |
335 iCurrentLineNumber = 0; |
336 iEndLineNumber = KMPXM3UNumOfLinesToProcess; |
336 iEndLineNumber = KMPXM3UNumOfLinesToProcess; |
337 iEndOfFile = EFalse; |
337 iEndOfFile = EFalse; |
338 |
338 |
339 MPX_DEBUG2("After reading playlist to buffer: heap size = %d", User::Heap().Size()); |
339 MPX_DEBUG2("After reading playlist to buffer: heap size = %d", User::Heap().Size()); |
340 } |
340 } |
341 |
341 |
342 // ----------------------------------------------------------------------------- |
342 // ----------------------------------------------------------------------------- |
343 // CMPXM3uPlaylistImporter::DetectCharacterSetL |
343 // CMPXM3uPlaylistImporter::DetectCharacterSetL |
344 // copied and revised based on CMetaDataParserID3v1::DetectCharacterSetL version 4 |
344 // copied and revised based on CMetaDataParserID3v1::DetectCharacterSetL version 4 |
495 else |
495 else |
496 { |
496 { |
497 // The file is in the extented format |
497 // The file is in the extented format |
498 iExtendedFormat = ETrue; |
498 iExtendedFormat = ETrue; |
499 return; |
499 return; |
500 } |
500 } |
501 } |
501 } |
502 |
502 |
503 if (!iItem) |
503 if (!iItem) |
504 { |
504 { |
505 iItem = CMPXMedia::NewL(); |
505 iItem = CMPXMedia::NewL(); |
506 iItem->SetTObjectValueL(KMPXMediaGeneralType, EMPXItem); |
506 iItem->SetTObjectValueL(KMPXMediaGeneralType, EMPXItem); |
507 iItem->SetTObjectValueL(KMPXMediaGeneralCategory, EMPXSong); |
507 iItem->SetTObjectValueL(KMPXMediaGeneralCategory, EMPXSong); |
508 } |
508 } |
509 |
509 |
510 // Parse line and then decide what to do with it |
510 // Parse line and then decide what to do with it |
511 switch (ParseLineL(iItem, aInvalidItemCount)) |
511 switch (ParseLineL(iItem, aInvalidItemCount)) |
512 { |
512 { |
513 case EMPXM3UPlaylistLineTypeExtinf: |
513 case EMPXM3UPlaylistLineTypeExtinf: |
514 // Continue to next round |
514 // Continue to next round |
515 break; |
515 break; |
516 |
516 |
517 case EMPXM3UPlaylistLineTypePath: |
517 case EMPXM3UPlaylistLineTypePath: |
518 { |
518 { |
519 // Line was a path => add item to playlist |
519 // Line was a path => add item to playlist |
520 aPlaylist.AppendL(iItem); |
520 aPlaylist.AppendL(iItem); |
521 iItem = NULL; // item now owned by aPlaylist |
521 iItem = NULL; // item now owned by aPlaylist |
522 } |
522 } |
523 break; |
523 break; |
524 |
524 |
525 case EMPXM3UPlaylistLineTypeNotSupported: |
525 case EMPXM3UPlaylistLineTypeNotSupported: |
526 case EMPXM3UPlaylistLineTypeCorrupted: |
526 case EMPXM3UPlaylistLineTypeCorrupted: |
527 default: |
527 default: |
528 { |
528 { |
529 // Line has unsupported extension tag or undefined has error |
529 // Line has unsupported extension tag or undefined has error |
586 aItem->SetTextValueL(KMPXMediaGeneralTitle, *title); |
586 aItem->SetTextValueL(KMPXMediaGeneralTitle, *title); |
587 MPX_DEBUG2(" title %S", title); |
587 MPX_DEBUG2(" title %S", title); |
588 CleanupStack::PopAndDestroy( title ); |
588 CleanupStack::PopAndDestroy( title ); |
589 |
589 |
590 return EMPXM3UPlaylistLineTypeExtinf; // line type extinf |
590 return EMPXM3UPlaylistLineTypeExtinf; // line type extinf |
591 } |
591 } |
592 } |
592 } |
593 } |
593 } |
594 |
594 |
595 // File is not in the extented format or supported info not found from this |
595 // File is not in the extented format or supported info not found from this |
596 // line. |
596 // line. |
597 switch (iLine->Find(KMPXM3UTagExt)) |
597 switch (iLine->Find(KMPXM3UTagExt)) |
598 { |
598 { |
599 case KMPXM3UNoOffset: |
599 case KMPXM3UNoOffset: |
600 // Unsupported extended info tag found from this line |
600 // Unsupported extended info tag found from this line |
601 return EMPXM3UPlaylistLineTypeNotSupported; |
601 return EMPXM3UPlaylistLineTypeNotSupported; |
602 |
602 |
603 case KErrNotFound: |
603 case KErrNotFound: |
604 default: |
604 default: |
605 // Extended info not found from the beginning of line => line is |
605 // Extended info not found from the beginning of line => line is |
606 // a path. |
606 // a path. |
607 { |
607 { |
608 // Get absolute path |
608 // Get absolute path |
609 TInt error(KErrNone); |
609 TInt error(KErrNone); |
610 HBufC* uri = ParseAbsolutePathLC(*iLine, error); |
610 HBufC* uri = ParseAbsolutePathLC(*iLine, error); |
611 |
611 |
612 if (error) |
612 if (error) |
613 { |
613 { |
614 if (error == KErrPathNotFound) |
614 if (error == KErrPathNotFound) |
615 { |
615 { |
616 TUint flag(KMPXMediaGeneralFlagsSetOrUnsetBit | KMPXMediaGeneralFlagsIsInvalid); |
616 TUint flag(KMPXMediaGeneralFlagsSetOrUnsetBit | KMPXMediaGeneralFlagsIsInvalid); |
620 { |
620 { |
621 if( uri ) |
621 if( uri ) |
622 { |
622 { |
623 CleanupStack::PopAndDestroy( uri ); |
623 CleanupStack::PopAndDestroy( uri ); |
624 } |
624 } |
625 |
625 |
626 ++aInvalidItemCount; |
626 ++aInvalidItemCount; |
627 |
627 |
628 // All other errors are considered to mean playlist is |
628 // All other errors are considered to mean playlist is |
629 // corrupt. |
629 // corrupt. |
630 return EMPXM3UPlaylistLineTypeCorrupted; |
630 return EMPXM3UPlaylistLineTypeCorrupted; |
631 } |
631 } |
632 } |
632 } |
633 |
633 |
634 aItem->SetTextValueL(KMPXMediaGeneralUri, *uri); |
634 aItem->SetTextValueL(KMPXMediaGeneralUri, *uri); |
635 MPX_DEBUG2(" uri %S", uri); |
635 MPX_DEBUG2(" uri %S", uri); |
636 |
636 |
637 // if title isn't supplied by the m3u file, extract file name from |
637 // if title isn't supplied by the m3u file, extract file name from |
638 // URI as the title |
638 // URI as the title |
639 if (!aItem->IsSupported(KMPXMediaGeneralTitle)) |
639 if (!aItem->IsSupported(KMPXMediaGeneralTitle)) |
640 { |
640 { |
641 TParsePtrC parser(*uri); |
641 TParsePtrC parser(*uri); |
696 tmpPtr = currentFolder; |
696 tmpPtr = currentFolder; |
697 tmpPtr += aPath; |
697 tmpPtr += aPath; |
698 |
698 |
699 aError = iFs->IsValidName(*path) ? KErrNone : KErrBadName; |
699 aError = iFs->IsValidName(*path) ? KErrNone : KErrBadName; |
700 } |
700 } |
701 |
701 |
702 // It is possible that a song exists in the filesystem but isn't added to |
702 // It is possible that a song exists in the filesystem but isn't added to |
703 // the database because it's not a supported type. If such song is included |
703 // the database because it's not a supported type. If such song is included |
704 // in a playlist, it will be added to the database when the playlist is added. |
704 // in a playlist, it will be added to the database when the playlist is added. |
705 // Because of this, we cannot rely on whether the song exists in the database |
705 // Because of this, we cannot rely on whether the song exists in the database |
706 // to conclude whether the song is a broken link. We need to check for file |
706 // to conclude whether the song is a broken link. We need to check for file |
725 // |
725 // |
726 // instantiate a CMPXMedia that represent the playlist which will |
726 // instantiate a CMPXMedia that represent the playlist which will |
727 // contain the CMPXMediaArray |
727 // contain the CMPXMediaArray |
728 // |
728 // |
729 iPlaylist = CMPXMedia::NewL(); |
729 iPlaylist = CMPXMedia::NewL(); |
730 |
730 |
731 // set playlist title |
731 // set playlist title |
732 TParsePtrC parser(iPlaylistFilePath); |
732 TParsePtrC parser(iPlaylistFilePath); |
733 iPlaylist->SetTextValueL(KMPXMediaGeneralTitle, parser.Name()); |
733 iPlaylist->SetTextValueL(KMPXMediaGeneralTitle, parser.Name()); |
734 |
734 |
735 // set playlist URI |
735 // set playlist URI |
736 iPlaylist->SetTextValueL(KMPXMediaGeneralUri, iPlaylistFilePath); |
736 iPlaylist->SetTextValueL(KMPXMediaGeneralUri, iPlaylistFilePath); |
737 |
737 |
738 // set type |
738 // set type |
739 iPlaylist->SetTObjectValueL(KMPXMediaGeneralType, EMPXItem); |
739 iPlaylist->SetTObjectValueL(KMPXMediaGeneralType, EMPXItem); |
740 |
740 |
741 // set category |
741 // set category |
742 iPlaylist->SetTObjectValueL(KMPXMediaGeneralCategory, EMPXPlaylist); |
742 iPlaylist->SetTObjectValueL(KMPXMediaGeneralCategory, EMPXPlaylist); |
743 |
743 |
744 // set playlist array |
744 // set playlist array |
745 iPlaylist->SetCObjectValueL(KMPXMediaArrayContents, iAutoEncodingPlaylistArray); |
745 iPlaylist->SetCObjectValueL(KMPXMediaArrayContents, iAutoEncodingPlaylistArray); |
746 |
746 |
747 // set array acount |
747 // set array acount |
748 iPlaylist->SetTObjectValueL(KMPXMediaArrayCount, iAutoEncodingPlaylistArray->Count()); |
748 iPlaylist->SetTObjectValueL(KMPXMediaArrayCount, iAutoEncodingPlaylistArray->Count()); |
749 |
749 |
750 // playlist makes a copy of the array, we can now free the medias |
750 // playlist makes a copy of the array, we can now free the medias |
751 // array |
751 // array |
752 delete iAutoEncodingPlaylistArray; |
752 delete iAutoEncodingPlaylistArray; |
753 iAutoEncodingPlaylistArray = NULL; |
753 iAutoEncodingPlaylistArray = NULL; |
754 } |
754 } |
755 |
755 |
756 // ---------------------------------------------------------------------------- |
756 // ---------------------------------------------------------------------------- |
757 // Cleanup. |
757 // Cleanup. |
758 // ---------------------------------------------------------------------------- |
758 // ---------------------------------------------------------------------------- |
759 // |
759 // |
760 void CMPXM3uPlaylistImporter::Cleanup() |
760 void CMPXM3uPlaylistImporter::Cleanup() |
761 { |
761 { |
762 delete iBuffer; |
762 delete iBuffer; |
763 iBuffer = NULL; |
763 iBuffer = NULL; |
764 |
764 |
765 delete iLine; |
765 delete iLine; |
766 iLine = NULL; |
766 iLine = NULL; |
767 |
767 |
768 delete iItem; |
768 delete iItem; |
769 iItem = NULL; |
769 iItem = NULL; |
770 |
770 |
771 delete iAutoEncodingPlaylistArray; |
771 delete iAutoEncodingPlaylistArray; |
772 iAutoEncodingPlaylistArray = NULL; |
772 iAutoEncodingPlaylistArray = NULL; |
773 |
773 |
774 delete iPlaylist; |
774 delete iPlaylist; |
775 iPlaylist = NULL; |
775 iPlaylist = NULL; |
776 } |
776 } |
777 |
777 |
778 // ---------------------------------------------------------------------------- |
778 // ---------------------------------------------------------------------------- |