internetradio2.0/uisrc/irplsplaylist.cpp
changeset 3 ee64f059b8e1
parent 2 2e1adbfc62af
child 4 3f2d53f144fe
child 5 0930554dc389
equal deleted inserted replaced
2:2e1adbfc62af 3:ee64f059b8e1
     1 /*
       
     2 * Copyright (c) 2007-2007 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:  Describes a single item in PLS playlist.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <f32file.h>
       
    20 
       
    21 #include "irplsplaylist.h"
       
    22 #include "irplsplaylistitem.h"
       
    23 #include "irdebug.h"
       
    24 
       
    25 
       
    26 // ======== MEMBER FUNCTIONS ========
       
    27 
       
    28 // ---------------------------------------------------------------------------
       
    29 // CIRPlsPlayList::CIRPlsPlayList
       
    30 // ---------------------------------------------------------------------------
       
    31 //
       
    32 CIRPlsPlayList::CIRPlsPlayList()
       
    33     {
       
    34     IRLOG_DEBUG( "CIRPlsPlayList::CIRPlsPlayList" );
       
    35     }
       
    36     
       
    37 // ---------------------------------------------------------------------------
       
    38 // CIRPlsPlayList::ConstructL
       
    39 // ---------------------------------------------------------------------------
       
    40 //
       
    41 void CIRPlsPlayList::ConstructL(RFile& aFileToParse)
       
    42     {
       
    43     IRLOG_DEBUG( "CIRPlsPlayList::ConstructL - Entering" );
       
    44     ParseFileL(aFileToParse);
       
    45     IRLOG_DEBUG( "CIRPlsPlayList::ConstructL - Exiting" );
       
    46     }
       
    47 
       
    48 // ---------------------------------------------------------------------------
       
    49 // CIRPlsPlayList::NewL
       
    50 // ---------------------------------------------------------------------------
       
    51 //
       
    52 CIRPlsPlayList* CIRPlsPlayList::NewL(RFile& aFileToParse)
       
    53     {
       
    54     IRLOG_DEBUG( "CIRPlsPlayList::NewL - Entering" );
       
    55     CIRPlsPlayList* self = CIRPlsPlayList::NewLC(aFileToParse);
       
    56     CleanupStack::Pop( self );
       
    57     IRLOG_DEBUG( "CIRPlsPlayList::NewL - Exiting" );
       
    58     return self;
       
    59     }
       
    60 
       
    61 // ---------------------------------------------------------------------------
       
    62 // CIRPlsPlayList::NewLC
       
    63 // ---------------------------------------------------------------------------
       
    64 //
       
    65 CIRPlsPlayList* CIRPlsPlayList::NewLC(RFile& aFileToParse)
       
    66     {
       
    67     IRLOG_DEBUG( "CIRPlsPlayList::NewLC - Entering" );
       
    68     CIRPlsPlayList* self = new( ELeave ) CIRPlsPlayList;
       
    69     CleanupStack::PushL( self );
       
    70     self->ConstructL(aFileToParse);
       
    71     IRLOG_DEBUG( "CIRPlsPlayList::NewLC - Exiting" );
       
    72     return self;
       
    73     }
       
    74 
       
    75 // ---------------------------------------------------------------------------
       
    76 // CIRPlsPlayList::~CIRPlsPlayList
       
    77 // ---------------------------------------------------------------------------
       
    78 //
       
    79 CIRPlsPlayList::~CIRPlsPlayList()
       
    80     {
       
    81     IRLOG_DEBUG( "CIRPlsPlayList::~CIRPlsPlayList - Entering" );
       
    82     iItems.ResetAndDestroy();
       
    83     iItems.Close();	
       
    84     iIndexes.Close();
       
    85     IRLOG_DEBUG( "CIRPlsPlayList::~CIRPlsPlayList - Exiting" );
       
    86     }
       
    87 
       
    88 // ---------------------------------------------------------------------------
       
    89 // CIRPlsPlayList::AddItemAt
       
    90 // ---------------------------------------------------------------------------
       
    91 //
       
    92 void CIRPlsPlayList::AddItemAtL( TInt aIndex, CIRPlsPlayListItem* aItem )
       
    93     {
       
    94     IRLOG_DEBUG( "CIRPlsPlayList::AddItemAtL - Entering" );
       
    95     __ASSERT_DEBUG( iItems.Count() == iIndexes.Count(), User::Panic(_L("InternetRadio"), KErrCorrupt));
       
    96     
       
    97     TInt foundIndex = iIndexes.Find(aIndex);
       
    98     if (foundIndex >= 0)
       
    99         {
       
   100         iItems.Remove(foundIndex);
       
   101         //delete item;
       
   102         iIndexes.Remove(foundIndex);
       
   103         }
       
   104     else if (foundIndex != KErrNotFound)
       
   105         {
       
   106         User::LeaveIfError(foundIndex);
       
   107         }
       
   108     else
       
   109         {
       
   110         }
       
   111     iIndexes.AppendL(aIndex);
       
   112     TRAPD( err, iItems.AppendL(aItem) )
       
   113     if (err)
       
   114         {
       
   115         iIndexes.Remove(iIndexes.Count()-1);
       
   116         User::Leave(err);
       
   117         }
       
   118     IRLOG_DEBUG( "CIRPlsPlayList::AddItemAtL - Exiting" );
       
   119     }
       
   120 
       
   121 // ---------------------------------------------------------------------------
       
   122 // CIRPlsPlayList::RemoveItemAt
       
   123 // ---------------------------------------------------------------------------
       
   124 //
       
   125 void CIRPlsPlayList::RemoveItemAt( TInt aIndex )
       
   126     {
       
   127     IRLOG_DEBUG( "CIRPlsPlayList::RemoveItemAt - Entering" );
       
   128     __ASSERT_DEBUG( iItems.Count() == iIndexes.Count(), User::Panic(_L("InternetRadio"), KErrCorrupt));
       
   129     
       
   130     TInt foundIndex = iIndexes.Find(aIndex);
       
   131     if (foundIndex >= 0)
       
   132         {
       
   133         iItems.Remove(foundIndex);
       
   134         //delete item;
       
   135         iIndexes.Remove(foundIndex);
       
   136         }
       
   137     IRLOG_DEBUG( "CIRPlsPlayList::RemoveItemAt - Exiting" );
       
   138     }
       
   139 
       
   140 // ---------------------------------------------------------------------------
       
   141 // CIRPlsPlayList::ItemAt
       
   142 // ---------------------------------------------------------------------------
       
   143 //
       
   144 CIRPlsPlayListItem* CIRPlsPlayList::ItemAt( TInt aIndex ) const
       
   145     {
       
   146     IRLOG_DEBUG( "CIRPlsPlayList::ItemAt - Entering" );
       
   147     __ASSERT_DEBUG( iItems.Count() == iIndexes.Count(), User::Panic(_L("InternetRadio"), KErrCorrupt));
       
   148     
       
   149     CIRPlsPlayListItem* retItem = NULL;
       
   150     TInt foundIndex = iIndexes.Find(aIndex);
       
   151     if (foundIndex >= 0)
       
   152         {
       
   153         retItem = iItems[foundIndex];
       
   154         }
       
   155     IRLOG_DEBUG( "CIRPlsPlayList::ItemAt - Exiting" );
       
   156     return retItem;
       
   157     }
       
   158 
       
   159 // ---------------------------------------------------------------------------
       
   160 // CIRPlsPlayList::ItemAt
       
   161 // ---------------------------------------------------------------------------
       
   162 //
       
   163 TInt CIRPlsPlayList::Count() const
       
   164     {
       
   165     IRLOG_DEBUG( "CIRPlsPlayList::Count - Entering" );
       
   166     __ASSERT_DEBUG( iItems.Count() == iIndexes.Count(), User::Panic(_L("InternetRadio"), KErrCorrupt));
       
   167     IRLOG_DEBUG( "CIRPlsPlayList::Count - Exiting" );
       
   168     
       
   169     return iItems.Count();
       
   170     }
       
   171 
       
   172 // ---------------------------------------------------------------------------
       
   173 // CIRPlsPlayList::ParseFileL
       
   174 // ---------------------------------------------------------------------------
       
   175 //
       
   176 void CIRPlsPlayList::ParseFileL(RFile& aFileToParse)
       
   177     {
       
   178     IRLOG_DEBUG( "CIRPlsPlayList::ParseFileL - Entering" );
       
   179     TBool firstLine(ETrue);
       
   180 	TBool done(EFalse);
       
   181 	TInt numberOfEntries(0);
       
   182 	HBufC8* lineBuf = NULL;
       
   183 	while ( !done )
       
   184 	    {
       
   185 	    TInt ret = KErrNone;
       
   186 	    ReadLineL( aFileToParse, lineBuf, &ret );
       
   187 	    if (ret == KErrEof)
       
   188 	        {
       
   189 	        // Last line is in the buffer.
       
   190 	        done = ETrue;
       
   191 	        }
       
   192 	    CleanupStack::PushL( lineBuf );
       
   193 	    TPtr8 line( lineBuf->Des() );
       
   194 	    
       
   195 	    if( firstLine )
       
   196 	        {
       
   197 	        _LIT8(KIRHeader, "[playlist]");
       
   198 	        if( line.Compare( KIRHeader ) )
       
   199     	        {
       
   200     	        User::Leave(KErrCorrupt);
       
   201     	        }
       
   202 	        firstLine = EFalse;
       
   203 	        }
       
   204 	    else
       
   205 	        {
       
   206     	    _LIT8(KIRFileLine, "File");
       
   207     	    _LIT8(KIRTitleLine, "Title");
       
   208     	    _LIT8(KIRLengthLine, "Length");
       
   209     	    _LIT8(KIRNumberOfEntries, "NumberOfEntries");
       
   210     	    TPtrC8 contentType;
       
   211     	    if( line.Find( KIRFileLine ) == 0 )
       
   212     	        {
       
   213     	        contentType.Set( KIRFileLine );
       
   214     	        }
       
   215     	    else if( line.Find( KIRTitleLine ) == 0 )
       
   216     	        {
       
   217     	        contentType.Set( KIRTitleLine );
       
   218     	        }
       
   219     	    else if( line.Find( KIRLengthLine ) == 0 )
       
   220     	        {
       
   221     	        contentType.Set( KIRLengthLine );
       
   222     	        }
       
   223     	    else if( line.FindC( KIRNumberOfEntries ) == 0 )
       
   224     	        {
       
   225     	        contentType.Set( KIRNumberOfEntries );
       
   226     	        }
       
   227     	    else
       
   228     	        {
       
   229     	        contentType.Set( KNullDesC8 );
       
   230     	        }
       
   231     	    // If found parsable content.
       
   232     	    if( contentType.Length() )
       
   233     	        {
       
   234     	        // Every line must have an "equals" sign.
       
   235         	    _LIT8(KIREqualsSign, "=");
       
   236         	    TInt equalsSignPos = line.Find( KIREqualsSign );
       
   237                 if (equalsSignPos == KErrNotFound)
       
   238                     {
       
   239                     // Sign was not found.
       
   240                     User::Leave(KErrCorrupt);
       
   241                     }
       
   242                 // Find the content index of certain content types.
       
   243                 TInt contentIndex(0);
       
   244                 if ( (!contentType.Compare( KIRFileLine )) || 
       
   245                      (!contentType.Compare( KIRTitleLine )) ||
       
   246                      (!contentType.Compare( KIRLengthLine )) )
       
   247                     {
       
   248             		TLex8 indexLex( line.Mid( contentType.Length(),
       
   249             				 equalsSignPos-contentType.Length()) );
       
   250             		indexLex.Val( contentIndex );
       
   251             		if ( !contentIndex )
       
   252                         {
       
   253                         // Index couldn't be resolved.
       
   254                         User::Leave(KErrCorrupt);
       
   255                         }
       
   256                     // To convert indexes "1.." of file to "0.." of array.
       
   257                     --contentIndex;
       
   258                     }
       
   259         		TPtrC8 content( line.Mid( equalsSignPos+KIREqualsSign().Length() ) );
       
   260         		if( !contentType.Compare( KIRFileLine ) )
       
   261         		    {
       
   262         		    HBufC* convertedContent = HBufC::NewLC(content.Length());
       
   263             		convertedContent->Des().Copy(content);
       
   264         		    CIRPlsPlayListItem* item = ItemAt(contentIndex);
       
   265         		    if (item)
       
   266         		        {
       
   267         		        // Update existing item.
       
   268             		    item->SetFileL(*convertedContent);
       
   269         		        }
       
   270         		    else
       
   271         		        {
       
   272         		        // Create new item.
       
   273         		        item = CIRPlsPlayListItem::NewLC();	    
       
   274             		    item->SetFileL( *convertedContent );
       
   275             		    AddItemAtL( contentIndex, item );
       
   276             		    CleanupStack::Pop( item );
       
   277         		        }
       
   278         		    CleanupStack::PopAndDestroy( convertedContent );
       
   279         		    }
       
   280         		else if( !contentType.Compare( KIRTitleLine ) )
       
   281         		    {
       
   282         		    HBufC* convertedContent = HBufC::NewLC(content.Length());
       
   283             		convertedContent->Des().Copy(content);
       
   284         		    CIRPlsPlayListItem* item = ItemAt(contentIndex);
       
   285         		    if (item)
       
   286         		        {
       
   287         		        // Update existing item.
       
   288             		    item->SetTitleL(*convertedContent);
       
   289         		        }
       
   290         		    else
       
   291         		        {
       
   292         		        // Create new item.
       
   293         		        item = CIRPlsPlayListItem::NewLC();
       
   294             		    item->SetTitleL( *convertedContent );
       
   295             		    AddItemAtL( contentIndex, item );
       
   296             		    CleanupStack::Pop( item );
       
   297         		        }
       
   298         		    CleanupStack::PopAndDestroy( convertedContent );
       
   299         		    }
       
   300         		else if( !contentType.Compare( KIRLengthLine ) )
       
   301         		    {
       
   302         		    TInt lengthVal(0);
       
   303         		    TLex8 lengthLex( content );
       
   304         		    lengthLex.Val( lengthVal ); 
       
   305         		    CIRPlsPlayListItem* item = ItemAt(contentIndex);
       
   306         		    if (item)
       
   307         		        {
       
   308         		        // Update existing item.
       
   309             		    item->SetLength(lengthVal);
       
   310         		        }
       
   311         		    else
       
   312         		        {
       
   313         		        // Create new item.
       
   314         		        item = CIRPlsPlayListItem::NewLC();
       
   315             		    item->SetLength(lengthVal);
       
   316             		    AddItemAtL( contentIndex, item );
       
   317             		    CleanupStack::Pop( item );
       
   318         		        }
       
   319         		    }
       
   320         		else if( !contentType.CompareC( KIRNumberOfEntries ) )
       
   321         		    {
       
   322         		    TLex8 numberLex( content );
       
   323         		    numberLex.Val( numberOfEntries );
       
   324         		    }
       
   325         		else
       
   326         		    {
       
   327         		    }
       
   328     	        }
       
   329 	        }
       
   330 	        
       
   331 	    CleanupStack::PopAndDestroy(lineBuf);
       
   332 	    }
       
   333 
       
   334     if (Count() != numberOfEntries)
       
   335         {
       
   336         User::Leave(KErrCorrupt);
       
   337         }
       
   338     IRLOG_DEBUG( "CIRPlsPlayList::ParseFileL - Exiting" );
       
   339     }
       
   340 
       
   341 // ---------------------------------------------------------------------------
       
   342 // CIRPlsPlayList::ReadLineL
       
   343 // ---------------------------------------------------------------------------
       
   344 //	
       
   345 void CIRPlsPlayList::ReadLineL( RFile& aFile, HBufC8*& aLineBuf, TInt *aError ) const
       
   346     {
       
   347     IRLOG_DEBUG( "CIRPlsPlayList::ReadLineL - Entering" );
       
   348     *aError = KErrNone;
       
   349     TInt filePos(0);
       
   350     User::LeaveIfError( aFile.Seek( ESeekCurrent, filePos ) );
       
   351     TInt endLine( KErrNotFound );
       
   352     TInt readAmount( 0 );
       
   353     const TInt KIRBytesToRead = 64;
       
   354     // Find next line end mark index.
       
   355     while ( endLine == KErrNotFound )
       
   356         {
       
   357         // Increase read amount if end of line hasn't been yet found.
       
   358         readAmount = readAmount + KIRBytesToRead;
       
   359        	HBufC8* nextBuf = HBufC8::NewLC( readAmount );
       
   360         TPtr8 next( nextBuf->Des() );
       
   361         User::LeaveIfError( aFile.Seek( ESeekStart, filePos ) );
       
   362         User::LeaveIfError( aFile.Read( next, readAmount ) );
       
   363         // Locate nearest LF and CR.
       
   364         TInt lfEnd = next.Locate(EKeyLineFeed);
       
   365         TInt crEnd = next.Locate(EKeyEnter);
       
   366         if ((lfEnd != KErrNotFound) || (crEnd != KErrNotFound))
       
   367             {
       
   368             // Either CR or LF was found.
       
   369 	        if( ((lfEnd != KErrNotFound) && (crEnd != KErrNotFound) && (lfEnd < crEnd)) || 
       
   370                 (crEnd == KErrNotFound) )
       
   371                 {
       
   372                 // LF is nearer.
       
   373                 if (lfEnd)
       
   374                     {
       
   375                     // Mark end line position as the position of LF.
       
   376                     endLine = lfEnd;
       
   377                     }
       
   378                 else
       
   379                     {
       
   380                     // LF is at the begining of the line.
       
   381                     // Skip it and read file again but not increase read amount.
       
   382                     ++filePos;
       
   383                     readAmount = readAmount - KIRBytesToRead;
       
   384                     }
       
   385                 }
       
   386             else
       
   387                 {
       
   388                 // CR is nearer.
       
   389                 if (crEnd)
       
   390                     {
       
   391                     // Mark end line position as the position of CR.
       
   392                     endLine = crEnd;
       
   393                     }
       
   394                 else
       
   395                     {
       
   396                     // CR is at the begining of the line.
       
   397                     // Skip it and read file again but not increase read amount.
       
   398                     ++filePos;
       
   399                     readAmount = readAmount - KIRBytesToRead;
       
   400                     }
       
   401                 }
       
   402             }
       
   403         else
       
   404             {
       
   405             // No CR or LF was found.
       
   406             // Check are we in the end of the file.
       
   407             if (next.Length() < readAmount)
       
   408                 {
       
   409                 // Reached the end of file.
       
   410                 endLine = next.Length();
       
   411                 *aError = KErrEof;
       
   412                 }
       
   413             }
       
   414         CleanupStack::PopAndDestroy(nextBuf);
       
   415         }
       
   416     // Read the line to buf.
       
   417     aLineBuf = HBufC8::NewLC( endLine );
       
   418     TPtr8 line( aLineBuf->Des() );
       
   419     User::LeaveIfError( aFile.Seek( ESeekStart, filePos ) );
       
   420     User::LeaveIfError( aFile.Read( line, endLine ) );
       
   421     CleanupStack::Pop( aLineBuf );
       
   422     IRLOG_DEBUG( "CIRPlsPlayList::ReadLineL - Exiting" );
       
   423     }