--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/internetradio2.0/uisrc/irplsplaylist.cpp Mon Apr 19 14:01:53 2010 +0300
@@ -0,0 +1,423 @@
+/*
+* Copyright (c) 2007-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Describes a single item in PLS playlist.
+*
+*/
+
+
+#include <f32file.h>
+
+#include "irplsplaylist.h"
+#include "irplsplaylistitem.h"
+#include "irdebug.h"
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CIRPlsPlayList::CIRPlsPlayList
+// ---------------------------------------------------------------------------
+//
+CIRPlsPlayList::CIRPlsPlayList()
+ {
+ IRLOG_DEBUG( "CIRPlsPlayList::CIRPlsPlayList" );
+ }
+
+// ---------------------------------------------------------------------------
+// CIRPlsPlayList::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CIRPlsPlayList::ConstructL(RFile& aFileToParse)
+ {
+ IRLOG_DEBUG( "CIRPlsPlayList::ConstructL - Entering" );
+ ParseFileL(aFileToParse);
+ IRLOG_DEBUG( "CIRPlsPlayList::ConstructL - Exiting" );
+ }
+
+// ---------------------------------------------------------------------------
+// CIRPlsPlayList::NewL
+// ---------------------------------------------------------------------------
+//
+CIRPlsPlayList* CIRPlsPlayList::NewL(RFile& aFileToParse)
+ {
+ IRLOG_DEBUG( "CIRPlsPlayList::NewL - Entering" );
+ CIRPlsPlayList* self = CIRPlsPlayList::NewLC(aFileToParse);
+ CleanupStack::Pop( self );
+ IRLOG_DEBUG( "CIRPlsPlayList::NewL - Exiting" );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CIRPlsPlayList::NewLC
+// ---------------------------------------------------------------------------
+//
+CIRPlsPlayList* CIRPlsPlayList::NewLC(RFile& aFileToParse)
+ {
+ IRLOG_DEBUG( "CIRPlsPlayList::NewLC - Entering" );
+ CIRPlsPlayList* self = new( ELeave ) CIRPlsPlayList;
+ CleanupStack::PushL( self );
+ self->ConstructL(aFileToParse);
+ IRLOG_DEBUG( "CIRPlsPlayList::NewLC - Exiting" );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CIRPlsPlayList::~CIRPlsPlayList
+// ---------------------------------------------------------------------------
+//
+CIRPlsPlayList::~CIRPlsPlayList()
+ {
+ IRLOG_DEBUG( "CIRPlsPlayList::~CIRPlsPlayList - Entering" );
+ iItems.ResetAndDestroy();
+ iItems.Close();
+ iIndexes.Close();
+ IRLOG_DEBUG( "CIRPlsPlayList::~CIRPlsPlayList - Exiting" );
+ }
+
+// ---------------------------------------------------------------------------
+// CIRPlsPlayList::AddItemAt
+// ---------------------------------------------------------------------------
+//
+void CIRPlsPlayList::AddItemAtL( TInt aIndex, CIRPlsPlayListItem* aItem )
+ {
+ IRLOG_DEBUG( "CIRPlsPlayList::AddItemAtL - Entering" );
+ __ASSERT_DEBUG( iItems.Count() == iIndexes.Count(), User::Panic(_L("InternetRadio"), KErrCorrupt));
+
+ TInt foundIndex = iIndexes.Find(aIndex);
+ if (foundIndex >= 0)
+ {
+ iItems.Remove(foundIndex);
+ //delete item;
+ iIndexes.Remove(foundIndex);
+ }
+ else if (foundIndex != KErrNotFound)
+ {
+ User::LeaveIfError(foundIndex);
+ }
+ else
+ {
+ }
+ iIndexes.AppendL(aIndex);
+ TRAPD( err, iItems.AppendL(aItem) )
+ if (err)
+ {
+ iIndexes.Remove(iIndexes.Count()-1);
+ User::Leave(err);
+ }
+ IRLOG_DEBUG( "CIRPlsPlayList::AddItemAtL - Exiting" );
+ }
+
+// ---------------------------------------------------------------------------
+// CIRPlsPlayList::RemoveItemAt
+// ---------------------------------------------------------------------------
+//
+void CIRPlsPlayList::RemoveItemAt( TInt aIndex )
+ {
+ IRLOG_DEBUG( "CIRPlsPlayList::RemoveItemAt - Entering" );
+ __ASSERT_DEBUG( iItems.Count() == iIndexes.Count(), User::Panic(_L("InternetRadio"), KErrCorrupt));
+
+ TInt foundIndex = iIndexes.Find(aIndex);
+ if (foundIndex >= 0)
+ {
+ iItems.Remove(foundIndex);
+ //delete item;
+ iIndexes.Remove(foundIndex);
+ }
+ IRLOG_DEBUG( "CIRPlsPlayList::RemoveItemAt - Exiting" );
+ }
+
+// ---------------------------------------------------------------------------
+// CIRPlsPlayList::ItemAt
+// ---------------------------------------------------------------------------
+//
+CIRPlsPlayListItem* CIRPlsPlayList::ItemAt( TInt aIndex ) const
+ {
+ IRLOG_DEBUG( "CIRPlsPlayList::ItemAt - Entering" );
+ __ASSERT_DEBUG( iItems.Count() == iIndexes.Count(), User::Panic(_L("InternetRadio"), KErrCorrupt));
+
+ CIRPlsPlayListItem* retItem = NULL;
+ TInt foundIndex = iIndexes.Find(aIndex);
+ if (foundIndex >= 0)
+ {
+ retItem = iItems[foundIndex];
+ }
+ IRLOG_DEBUG( "CIRPlsPlayList::ItemAt - Exiting" );
+ return retItem;
+ }
+
+// ---------------------------------------------------------------------------
+// CIRPlsPlayList::ItemAt
+// ---------------------------------------------------------------------------
+//
+TInt CIRPlsPlayList::Count() const
+ {
+ IRLOG_DEBUG( "CIRPlsPlayList::Count - Entering" );
+ __ASSERT_DEBUG( iItems.Count() == iIndexes.Count(), User::Panic(_L("InternetRadio"), KErrCorrupt));
+ IRLOG_DEBUG( "CIRPlsPlayList::Count - Exiting" );
+
+ return iItems.Count();
+ }
+
+// ---------------------------------------------------------------------------
+// CIRPlsPlayList::ParseFileL
+// ---------------------------------------------------------------------------
+//
+void CIRPlsPlayList::ParseFileL(RFile& aFileToParse)
+ {
+ IRLOG_DEBUG( "CIRPlsPlayList::ParseFileL - Entering" );
+ TBool firstLine(ETrue);
+ TBool done(EFalse);
+ TInt numberOfEntries(0);
+ HBufC8* lineBuf = NULL;
+ while ( !done )
+ {
+ TInt ret = KErrNone;
+ ReadLineL( aFileToParse, lineBuf, &ret );
+ if (ret == KErrEof)
+ {
+ // Last line is in the buffer.
+ done = ETrue;
+ }
+ CleanupStack::PushL( lineBuf );
+ TPtr8 line( lineBuf->Des() );
+
+ if( firstLine )
+ {
+ _LIT8(KIRHeader, "[playlist]");
+ if( line.Compare( KIRHeader ) )
+ {
+ User::Leave(KErrCorrupt);
+ }
+ firstLine = EFalse;
+ }
+ else
+ {
+ _LIT8(KIRFileLine, "File");
+ _LIT8(KIRTitleLine, "Title");
+ _LIT8(KIRLengthLine, "Length");
+ _LIT8(KIRNumberOfEntries, "NumberOfEntries");
+ TPtrC8 contentType;
+ if( line.Find( KIRFileLine ) == 0 )
+ {
+ contentType.Set( KIRFileLine );
+ }
+ else if( line.Find( KIRTitleLine ) == 0 )
+ {
+ contentType.Set( KIRTitleLine );
+ }
+ else if( line.Find( KIRLengthLine ) == 0 )
+ {
+ contentType.Set( KIRLengthLine );
+ }
+ else if( line.FindC( KIRNumberOfEntries ) == 0 )
+ {
+ contentType.Set( KIRNumberOfEntries );
+ }
+ else
+ {
+ contentType.Set( KNullDesC8 );
+ }
+ // If found parsable content.
+ if( contentType.Length() )
+ {
+ // Every line must have an "equals" sign.
+ _LIT8(KIREqualsSign, "=");
+ TInt equalsSignPos = line.Find( KIREqualsSign );
+ if (equalsSignPos == KErrNotFound)
+ {
+ // Sign was not found.
+ User::Leave(KErrCorrupt);
+ }
+ // Find the content index of certain content types.
+ TInt contentIndex(0);
+ if ( (!contentType.Compare( KIRFileLine )) ||
+ (!contentType.Compare( KIRTitleLine )) ||
+ (!contentType.Compare( KIRLengthLine )) )
+ {
+ TLex8 indexLex( line.Mid( contentType.Length(),
+ equalsSignPos-contentType.Length()) );
+ indexLex.Val( contentIndex );
+ if ( !contentIndex )
+ {
+ // Index couldn't be resolved.
+ User::Leave(KErrCorrupt);
+ }
+ // To convert indexes "1.." of file to "0.." of array.
+ --contentIndex;
+ }
+ TPtrC8 content( line.Mid( equalsSignPos+KIREqualsSign().Length() ) );
+ if( !contentType.Compare( KIRFileLine ) )
+ {
+ HBufC* convertedContent = HBufC::NewLC(content.Length());
+ convertedContent->Des().Copy(content);
+ CIRPlsPlayListItem* item = ItemAt(contentIndex);
+ if (item)
+ {
+ // Update existing item.
+ item->SetFileL(*convertedContent);
+ }
+ else
+ {
+ // Create new item.
+ item = CIRPlsPlayListItem::NewLC();
+ item->SetFileL( *convertedContent );
+ AddItemAtL( contentIndex, item );
+ CleanupStack::Pop( item );
+ }
+ CleanupStack::PopAndDestroy( convertedContent );
+ }
+ else if( !contentType.Compare( KIRTitleLine ) )
+ {
+ HBufC* convertedContent = HBufC::NewLC(content.Length());
+ convertedContent->Des().Copy(content);
+ CIRPlsPlayListItem* item = ItemAt(contentIndex);
+ if (item)
+ {
+ // Update existing item.
+ item->SetTitleL(*convertedContent);
+ }
+ else
+ {
+ // Create new item.
+ item = CIRPlsPlayListItem::NewLC();
+ item->SetTitleL( *convertedContent );
+ AddItemAtL( contentIndex, item );
+ CleanupStack::Pop( item );
+ }
+ CleanupStack::PopAndDestroy( convertedContent );
+ }
+ else if( !contentType.Compare( KIRLengthLine ) )
+ {
+ TInt lengthVal(0);
+ TLex8 lengthLex( content );
+ lengthLex.Val( lengthVal );
+ CIRPlsPlayListItem* item = ItemAt(contentIndex);
+ if (item)
+ {
+ // Update existing item.
+ item->SetLength(lengthVal);
+ }
+ else
+ {
+ // Create new item.
+ item = CIRPlsPlayListItem::NewLC();
+ item->SetLength(lengthVal);
+ AddItemAtL( contentIndex, item );
+ CleanupStack::Pop( item );
+ }
+ }
+ else if( !contentType.CompareC( KIRNumberOfEntries ) )
+ {
+ TLex8 numberLex( content );
+ numberLex.Val( numberOfEntries );
+ }
+ else
+ {
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy(lineBuf);
+ }
+
+ if (Count() != numberOfEntries)
+ {
+ User::Leave(KErrCorrupt);
+ }
+ IRLOG_DEBUG( "CIRPlsPlayList::ParseFileL - Exiting" );
+ }
+
+// ---------------------------------------------------------------------------
+// CIRPlsPlayList::ReadLineL
+// ---------------------------------------------------------------------------
+//
+void CIRPlsPlayList::ReadLineL( RFile& aFile, HBufC8*& aLineBuf, TInt *aError ) const
+ {
+ IRLOG_DEBUG( "CIRPlsPlayList::ReadLineL - Entering" );
+ *aError = KErrNone;
+ TInt filePos(0);
+ User::LeaveIfError( aFile.Seek( ESeekCurrent, filePos ) );
+ TInt endLine( KErrNotFound );
+ TInt readAmount( 0 );
+ const TInt KIRBytesToRead = 64;
+ // Find next line end mark index.
+ while ( endLine == KErrNotFound )
+ {
+ // Increase read amount if end of line hasn't been yet found.
+ readAmount = readAmount + KIRBytesToRead;
+ HBufC8* nextBuf = HBufC8::NewLC( readAmount );
+ TPtr8 next( nextBuf->Des() );
+ User::LeaveIfError( aFile.Seek( ESeekStart, filePos ) );
+ User::LeaveIfError( aFile.Read( next, readAmount ) );
+ // Locate nearest LF and CR.
+ TInt lfEnd = next.Locate(EKeyLineFeed);
+ TInt crEnd = next.Locate(EKeyEnter);
+ if ((lfEnd != KErrNotFound) || (crEnd != KErrNotFound))
+ {
+ // Either CR or LF was found.
+ if( ((lfEnd != KErrNotFound) && (crEnd != KErrNotFound) && (lfEnd < crEnd)) ||
+ (crEnd == KErrNotFound) )
+ {
+ // LF is nearer.
+ if (lfEnd)
+ {
+ // Mark end line position as the position of LF.
+ endLine = lfEnd;
+ }
+ else
+ {
+ // LF is at the begining of the line.
+ // Skip it and read file again but not increase read amount.
+ ++filePos;
+ readAmount = readAmount - KIRBytesToRead;
+ }
+ }
+ else
+ {
+ // CR is nearer.
+ if (crEnd)
+ {
+ // Mark end line position as the position of CR.
+ endLine = crEnd;
+ }
+ else
+ {
+ // CR is at the begining of the line.
+ // Skip it and read file again but not increase read amount.
+ ++filePos;
+ readAmount = readAmount - KIRBytesToRead;
+ }
+ }
+ }
+ else
+ {
+ // No CR or LF was found.
+ // Check are we in the end of the file.
+ if (next.Length() < readAmount)
+ {
+ // Reached the end of file.
+ endLine = next.Length();
+ *aError = KErrEof;
+ }
+ }
+ CleanupStack::PopAndDestroy(nextBuf);
+ }
+ // Read the line to buf.
+ aLineBuf = HBufC8::NewLC( endLine );
+ TPtr8 line( aLineBuf->Des() );
+ User::LeaveIfError( aFile.Seek( ESeekStart, filePos ) );
+ User::LeaveIfError( aFile.Read( line, endLine ) );
+ CleanupStack::Pop( aLineBuf );
+ IRLOG_DEBUG( "CIRPlsPlayList::ReadLineL - Exiting" );
+ }