internetradio2.0/streamsourcesrc/iricyflowreader.cpp
changeset 14 896e9dbc5f19
parent 12 608f67c22514
child 15 065198191975
--- a/internetradio2.0/streamsourcesrc/iricyflowreader.cpp	Tue Jul 06 14:07:20 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,714 +0,0 @@
-/*
-* Copyright (c) 2006-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:  ICY flow reader implementation
-*
-*/
-
-
-/* ---------------------------------------------------------------------------
-*  Version history:
-*  Template version:
-*  <ccm_history>
-*
-*  Version: 2, Tue Feb 28 18:00:00 2008 by Rohit/Kranthi
-*  Ref:
-*  Setting RawDataTransferredL() into DataTransferTracker for Byte Counter Impl
-*
-*  </ccm_history>
-* ============================================================================
-*/
-#include <utf.h>
-
-#include "iricyflowreader.h"
-#include "irdebug.h"
-#include "irmediaenginebuffer.h"
-#include "irmetadata.h"
-#include "irnetworkbuffer.h"
-#include "irstationconnection.h"
-#include "irstationdataobserver.h"
-#include "irstreamsourceerrors.h"
-#include "irnetworkcontroller.h"
-
-const TInt KMaxSongBufferSize = 61440;
-const TInt KNoInputBuffers = 60;
-const TInt KMaxBufferChunkSize = 1024;
-const TInt KMaxSocketBufferSize = 1024;
-const TInt KBufferPercentageInc = 1;
-const TInt KSixteen = 16;
-const TInt KThree=3;
-_LIT8( KIRStreamTitle, "StreamTitle='" );
-_LIT8( KIRStreamUrl, "StreamUrl='" );
-_LIT8( KIRMetaDataEndIdentifier, "';" );
-_LIT8( KIRSongDelimiter, " - " );
-
-// masks and prefices used in UTF-8 recognition
-const TInt KIRUtf8_2B1stByteMask = 0xE0;
-const TInt KIRUtf8_3B1stByteMask = 0xF0;
-const TInt KIRUtf8_4B1stByteMask = 0xF8;
-const TInt KIRUtf8FollowingByteMask = 0xC0;
-
-const TInt KIRUtf8_2B1stBytePrefix = 0xC0;
-const TInt KIRUtf8_3B1stBytePrefix = 0xE0;
-const TInt KIRUtf8_4B1stBytePrefix = 0xF0;
-const TInt KIRUtf8FollowingBytePrefix = 0x80;
-// ========================= MEMBER FUNCTIONS ================================
-
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::NewL
-// ---------------------------------------------------------------------------
-//
-CIRIcyFlowReader* CIRIcyFlowReader::NewL( RSocket& aSocket, CIRStationConnection& aOwner,
-	               MIRStationDataObserver& aDataObserver, TChannelInfo& aChannelInfo )
-    {
-    CIRIcyFlowReader* self = new ( ELeave ) CIRIcyFlowReader( aSocket, aOwner,
-    					 aDataObserver, aChannelInfo );
-    CleanupStack::PushL( self );
-    self->ConstructL();
-    CleanupStack::Pop( self );
-    return self;
-    }
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::CIRIcyFlowReader
-// ---------------------------------------------------------------------------
-//
-CIRIcyFlowReader::CIRIcyFlowReader( RSocket& aSocket, CIRStationConnection& aOwner,
-	              MIRStationDataObserver& aDataObserver, TChannelInfo& aChannelInfo )
-    :CActive( EPriorityStandard ), iSocket( aSocket ), iOwner( aOwner ),
-    				 iDataObserver( aDataObserver ),
-      iSocketBufferPtr( NULL, 0 ), iChannelInfo( aChannelInfo )
-    {
-
-    }
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::~CIRIcyFlowReader
-// ---------------------------------------------------------------------------
-//
-CIRIcyFlowReader::~CIRIcyFlowReader()
-	{
-	Cancel();
-	while(!iSinkQ.IsEmpty())
-		{
-		//Deleting all the entries in sink buffers queue
-		iTempBufferHolder = iSinkQ.First();
-		iSinkQ.Remove(*iTempBufferHolder);
-		delete iTempBufferHolder;
-		}
-	while(!iSourceQ.IsEmpty())
-		{
-		//deleting all the entries in source buffers queue
-		iTempBufferHolder = iSourceQ.First();
-		iSourceQ.Remove(*iTempBufferHolder);
-		delete iTempBufferHolder;
-		}
-	delete[] iSongBuffer;
-	delete iSocketBuffer;
-	delete iTempSongBuffer;
-	delete iTempMetaBuffer;
-    delete iMetaData;
-	if(iNetworkControllerHandle)
-		{
-		iNetworkControllerHandle->Close();
-		}
-	}
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::ConstructL()
-// ---------------------------------------------------------------------------
-//
-void CIRIcyFlowReader::ConstructL()
-    {
-    IRLOG_DEBUG( "CIRIcyFlowReader::ConstructL" );
-    iAudioDataOffset = iChannelInfo.iAudioDataOffset;
-    TInt f_off = _FOFF( CIRNetworkBuffer, iLink ); //for the buffer queue which is maintained
-    iSourceQ.SetOffset( f_off ); 	// It is Queue of buffer given to socket to fill
-    iSinkQ.SetOffset( f_off );  // It is Queue of buffer given to media engine
-    InitializeBuffersL();
-    iMetaData = CIRMetaData::NewL();
-    CActiveScheduler::Add( this );
-    iNetworkControllerHandle = CIRNetworkController::OpenL();
-    IRLOG_DEBUG( "CIRIcyFlowReader::ConstructL - Exiting." );
-    }
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::HandleReceivedDataL
-// ---------------------------------------------------------------------------
-//
-void CIRIcyFlowReader::HandleReceivedDataL( const TDesC8& aData )
-    {
-    switch ( iParsingState )
-        {
-        case EIRReadingAudioData:
-            {
-            if ( iAudioDataOffset + aData.Length() > iChannelInfo.iMetaInterval )
-                {
-                // Part of this data contains meta data information already.
-                TInt audioDataAmount = iChannelInfo.iMetaInterval - iAudioDataOffset;
-                // Only the audio part of the data is added to the song buffer.
-                HandleReceivedAudioData( aData.Left( audioDataAmount ) );
-                iParsingState = EIRReadingMetaDataLength;
-                iAudioDataOffset = 0; // Resets the audio data offset, will start increment again after meta data is handled.
-                HandleReceivedDataL( aData.Mid( audioDataAmount ) ); // Recursive call to handle meta data mixed in with this audio data block.
-                }
-            else // All of it is data is audio data.
-                {
-                HandleReceivedAudioData( aData );
-                }
-            break;
-            }
-        case EIRReadingMetaDataLength:
-            {
-            // ICY protocol specifies that meta data length is the first byte of the data multiplied by 16.
-            iMetaDataLength = aData[0] * KSixteen;
-
-            delete iTempMetaBuffer;
-            iTempMetaBuffer = NULL;
-
-            if ( iMetaDataLength > 0 ) // Meta data is provided, so we have to parse it.
-                {
-                iTempMetaBuffer = HBufC8::NewL( iMetaDataLength );
-                iParsingState = EIRReadingMetaData;
-                }
-            else // No meta data available, so resume reading audio data.
-                {
-                iParsingState = EIRReadingAudioData;
-                }
-
-            if ( aData.Length() > 1 ) // Just to check that the data doesn't only contain the length byte.
-                {
-                HandleReceivedDataL( aData.Mid( 1 ) ); // Strips off the length byte. Recursive call as data can also contain audio data.
-                }
-
-            break;
-            }
-        case EIRReadingMetaData:
-            {
-            if ( iTempMetaBuffer->Length() + aData.Length() > iMetaDataLength )
-                {
-                // All of the meta data block is now received, and part of it is continuation to the audio data.
-                TInt metaDataAmount = iMetaDataLength - iTempMetaBuffer->Length();
-                HandleReceivedMetaData( aData.Left( metaDataAmount ) );
-                ExtractMetadataL(); // Extracts the meta data from the temporary meta data buffer.
-                iParsingState = EIRReadingAudioData;
-                HandleReceivedDataL( aData.Mid( metaDataAmount ) ); // Strips off the meta data from the descriptor.
-                }
-            else // All of it is meta data.
-                {
-                HandleReceivedMetaData( aData );
-                }
-            break;
-            }
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::HandleReceivedAudioData
-// ---------------------------------------------------------------------------
-//
-void CIRIcyFlowReader::HandleReceivedAudioData( const TDesC8& aData )
-    {
-    // Check to see if we've got enough audio data to fill a buffer.
-    if ( iTempSongBuffer->Length() + aData.Length() >= KMaxBufferChunkSize )
-        {
-		// Data contains more audio data than the buffer can handle.
-		TInt amountToAdd = KMaxBufferChunkSize - iTempSongBuffer->Length();
-
-		// Enough audio data to fill the buffer is added.
-		iTempSongBuffer->Des().Append( aData.Left( amountToAdd ) );
-
-		AddToSinkQueue( *iTempSongBuffer );
-		
-		//while loop is written for only if left over amount in aData is 
-		//greater then 1024, then it should be again added into SinkQueue
-		while(1)
-			{
-			iTempSongBuffer->Des().Zero();
-	 		//calculates the length of the leftover amount to be added
-			TInt length = aData.Length() - amountToAdd;
-
-			if(length <= 0)
-				{
-				break;	
-				}
-			else if(length >= KMaxBufferChunkSize) //if the left over amount is >= 1024 then add to SinkQueue
-				{
-				iTempSongBuffer->Des().Append( aData.Mid( amountToAdd,KMaxBufferChunkSize ) );
-		 		// updates the amountToAdd value by 1024
-				amountToAdd += KMaxBufferChunkSize;
-
-				AddToSinkQueue( *iTempSongBuffer );
-				}
-			else //if the left over amount is < 1024 then append to tempSongBuffer & break
-				{
-				// Then the overflowing audio data part is added to the new clean buffer.
-				iTempSongBuffer->Des().Append( aData.Mid( amountToAdd ) );
-				break;	
-				}
-			}
-        }
-    else // There is enough room in the temporary audio buffer to hold all of the data.
-        {
-        iTempSongBuffer->Des().Append( aData );
-        }
-
-    iAudioDataOffset += aData.Length();
-
-
-
-    }
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::HandleReceivedMetaData
-// ---------------------------------------------------------------------------
-//
-void CIRIcyFlowReader::HandleReceivedMetaData( const TDesC8& aData )
-    {
-    iTempMetaBuffer->Des().Append( aData );
-    }
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::RunL
-// ---------------------------------------------------------------------------
-//
-void CIRIcyFlowReader::RunL()
-    {
-     // Active object request complete handler
-    switch ( iStatus.Int() )
-        {
-        case KErrNone:
-            {
-			// Byte Counter Impl
-			iNetworkControllerHandle->DataTransferTracker().RawDataTransferredL( 0,
-					 iSocketBufferPtr.Size(), MIRDataTransferTracker::EIRTransferCategoryAudio);
-
-            HandleReceivedDataL( *iSocketBuffer );
-
-            if ( !iSourceQ.IsEmpty() )
-            	{
-            	//issue a read on empty buffer
-            	IssueRead();
-            	}
-            else
-            	{
-            	if( iReBuffering )
-            		{
-            		//	if rebuffering call continue using sink buffer
-            		FillRemainingBuffers();
-            		}
-            	if( iInitialBuffering )
-            		{
-            		//  if first time intimate media client to fill the buffer
-            		iDataObserver.AudioDataEvent( MIRStationDataObserver::EBufferFilled, KErrNone );
-            		iInitialBuffering = EFalse;
-            		}
-            	}
-
-		 	break;
-			}
-        case KErrDisconnected:
-        	{
-        	IRLOG_ERROR( "CIRIcyFlowReader::RunL - KErrDisconnected");
-        	iOwner.ConnectionError( KIRStreamSourceDisconnected );
-        	}
-            break;
-        case KErrEof:
-        	{
-        	IRLOG_INFO( "CIRIcyFlowReader::RunL - KErrEof" );
-        	iOwner.ConnectionError( KIRStreamSourceNoResponse );
-        	}
-        	break;
-        default:
-        	{
-        	IRLOG_ERROR2( "CIRIcyFlowReader::RunL - Error (%d)", iStatus.Int() );
-            iOwner.ConnectionError( KIRStreamSourceReadError );
-        	}
-            break;
-        }
-    }
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::DoCancel
-// ---------------------------------------------------------------------------
-//
-void CIRIcyFlowReader::DoCancel()
-    {
-    iSocket.CancelRead();
-    }
-
-
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::IssueRead
-// ---------------------------------------------------------------------------
-//
-void CIRIcyFlowReader::IssueRead()
-    {
-	if( !IsActive() )
-		{
-	    iSocketBufferPtr.Zero();
-	    iSocket.Read( iSocketBufferPtr, iStatus );
-	    SetActive();
-		}
-    }
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::Start
-// ---------------------------------------------------------------------------
-//
-void CIRIcyFlowReader::Start()
-    {
-    IRLOG_INFO( "CIRIcyFlowReader::Start" );
-    // Initiate a new read from socket into iBuffer
-    iInitialBuffering = ETrue;
-    iBufferCounter = 0;
-    iPublishStationInfo = ETrue;
-	IssueRead();
-	IRLOG_DEBUG( "CIRIcyFlowReader::Start - Exiting." );
-    }
-
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::InitializeBuffersL
-// ---------------------------------------------------------------------------
-//
-void CIRIcyFlowReader::InitializeBuffersL()
-	{
-	IRLOG_DEBUG( "CIRIcyFlowReader::InitializeBuffersL" );
-	// Allocate the buffer for audio data on heap
-	iSongBuffer = new TUint8[KMaxSongBufferSize];
-	User::LeaveIfNull( iSongBuffer );
-
-	IRLOG_INFO2( "CIRIcyFlowReader::InitializeBuffersL - Reserved %d bytes of memory", KMaxSongBufferSize );
-	TUint8* bufferaddress = iSongBuffer;
-	// since sink buffers are not created initially all buffers are filled with data and appended to sink buffer
-	// Create buffers ans append to source buffer queue
-	for(TInt buffercount = 0; buffercount < KNoInputBuffers; buffercount++ )
-		{
-		iTempBufferHolder = CIRNetworkBuffer::NewL(bufferaddress,
-			KMaxBufferChunkSize);
-		iSourceQ.AddLast(*iTempBufferHolder);
-		bufferaddress += KMaxBufferChunkSize;
-		}
-	// Create a buffer for the data read from socket
-	iSocketBuffer = HBufC8::NewL( KMaxSocketBufferSize );
-	iSocketBufferPtr.Set( iSocketBuffer->Des() );
-    iTempSongBuffer = HBufC8::NewL( KMaxSocketBufferSize );
-	IRLOG_DEBUG( "CIRIcyFlowReader::InitializeBuffersL - Exiting." );
-	}
-
-
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::FillBuffer
-// Fills the mediaengine buffer and rebuffers if necessary
-// ---------------------------------------------------------------------------
-//
-void CIRIcyFlowReader::FillBuffer(TDes8& aInputBuffer)
-	{
-	FillMediaEngineBuffer(aInputBuffer);
-	}
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::AddToSinkQueue
-// Adds the filled buffers to the sink Q so that it can be copied to media
-// engine buffer
-// ---------------------------------------------------------------------------
-//
-void CIRIcyFlowReader::AddToSinkQueue( const TDesC8& aData )
-	{
-	//call from runL
-	//removes the buffer from source queue and put in sink queue
-
-	if( !iSourceQ.IsEmpty() )
-		{
-		iTempBufferHolder = iSourceQ.First();
-		TPtr8 bufferPointer(iTempBufferHolder->Des() ,KMaxBufferChunkSize,
-			KMaxBufferChunkSize );
-		bufferPointer.Copy(aData);
-		iSourceQ.Remove(*iTempBufferHolder);
-		iSinkQ.AddLast(*iTempBufferHolder);
-		if( iInitialBuffering )
-			{
-			iBufferCounter += KBufferPercentageInc;
-			iDataObserver.AudioDataEvent( MIRStationDataObserver::EBufferPercentage, iBufferCounter );
-			}
-		}
-	}
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::FillMediaEngineBuffer
-// Fills the data into media engine's buffer
-// aInputBuffer Buffer into which data is to be filled
-// ---------------------------------------------------------------------------
-//
-
-void CIRIcyFlowReader::FillMediaEngineBuffer(const TDes8& aInputBuffer)
-	{
-
-	if( !iReBuffering )
-		{
-		//Determine no of bytes of data to be filled
-		TInt copyLength = aInputBuffer.MaxLength();
-		// Calculate the no of 1K chunks
-		iNoOfChunks = copyLength/KMaxBufferChunkSize;
-		// Initiailly remaining chunks to be filled is same as total no of
-		// chunks to be filled
-		iChunksRemaining = iNoOfChunks;
-		IRLOG_DEBUG3( "CIRIcyFlowReader::FillMediaEngineBuffer - Copying %d bytes/%d chunks", copyLength, iNoOfChunks );
-		// Store the starting address of buffer into which data is to be
-		// copied
-		iBufferFillPointer = (TUint8 *)aInputBuffer.Ptr();
-		// Start filling of the empty media engine buffers
-		FillRemainingBuffers();
-		}
-	}
-
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::FillRemainingBuffers
-// Fills the data into media engine's remaining buffers
-// called when the stream source runs out of buffers and
-// there is a pending request to media engine
-// ---------------------------------------------------------------------------
-//
-void CIRIcyFlowReader::FillRemainingBuffers()
-	{
-	TUint8* mediaBufferAddress = iBufferFillPointer;
-	TInt chunksFilled = iNoOfChunks - iChunksRemaining;
-	mediaBufferAddress += ( chunksFilled * KMaxBufferChunkSize );
-
-	TInt bufferNumber = iChunksRemaining;
-	while ( bufferNumber )
-		{
-		if ( !iSinkQ.IsEmpty() )
-			{
-			iTempBufferHolder = iSinkQ.First();
-			TPtr8 mediaBufferPointer(mediaBufferAddress,KMaxBufferChunkSize,
-				KMaxBufferChunkSize );
-			mediaBufferPointer.Copy( iTempBufferHolder->Des() ,
-				KMaxBufferChunkSize);
-			TPtr8 tempBufferPointer(iTempBufferHolder->Des(),
-				KMaxBufferChunkSize,KMaxBufferChunkSize );
-			tempBufferPointer.Delete(KMaxBufferChunkSize,
-				KMaxBufferChunkSize);
-			iSinkQ.Remove(*iTempBufferHolder);
-			iSourceQ.AddLast(*iTempBufferHolder);
-			iChunksRemaining--;
-			bufferNumber--;
-			iReBuffering = EFalse;
-			mediaBufferAddress += KMaxBufferChunkSize;
-			//issue  source rebuffering here if source is not empty
-			if( !iSourceQ.IsEmpty() )
-				{
-				IssueRead();
-				}
-			}
-		else
-			{
-			//rebuffer if sink buffer is empty
-			bufferNumber = 0;
-			iReBuffering = ETrue;
-			//issue  source rebuffering here if source is not empty
-			if( !iSourceQ.IsEmpty() )
-				{
-				IssueRead();
-				}
-			//break from for loop
-			}
-		}
-	iBufferCounter += (K100Percentage - KNoInputBuffers) / KIRInputBufferCount;
-    if ( iBufferCounter > K100Percentage )
-        {
-        iBufferCounter = K100Percentage;
-        }
-    iDataObserver.AudioDataEvent( MIRStationDataObserver::EBufferPercentage, iBufferCounter );
-	if( !iReBuffering )
-		{
-        iDataObserver.AudioDataEvent( MIRStationDataObserver::EOpenComplete, KErrNone );
-		}
-	}
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::ExtractMetadataL
-// Extracts the meta data from the stream
-// ---------------------------------------------------------------------------
-//
-void CIRIcyFlowReader::ExtractMetadataL()
-	{
-    IRLOG_DEBUG( "CIRIcyFlowReader::ExtractMetaDataL" );
-
-    // Erases old meta data information.
-    iMetaData->SetArtistL( KNullDesC );
-    iMetaData->SetSongL( KNullDesC );
-    iMetaData->SetStreamUrlL( KNullDesC );
-
-    TPtrC8 ptr( *iTempMetaBuffer );
-
-    TInt streamTitleIndex = ptr.Find( KIRStreamTitle );
-    TInt streamUrlIndex = ptr.Find( KIRStreamUrl );
-
-    // Extracts the "StreamTitle" part of the meta data.
-    if ( streamTitleIndex >= 0 )
-        {
-        TPtrC8 streamTitlePtr( ptr.Mid( streamTitleIndex + KIRStreamTitle().Length() ) );
-        TInt streamTitleEndIndex = streamTitlePtr.Find( KIRMetaDataEndIdentifier );
-        if ( streamTitleEndIndex >= 0 )
-            {
-            streamTitlePtr.Set( streamTitlePtr.Left( streamTitleEndIndex ) );
-
-            TPtrC8 artistPtr( KNullDesC8 );
-            TPtrC8 songPtr( KNullDesC8 );
-
-            TInt songDelimiterIndex = streamTitlePtr.Find( KIRSongDelimiter );
-            if ( songDelimiterIndex >= 0 )
-                {
-                artistPtr.Set( streamTitlePtr.Left( songDelimiterIndex ) );
-                songPtr.Set( streamTitlePtr.Mid( songDelimiterIndex + 
-                					KIRSongDelimiter().Length() ) );
-                }
-            else
-                {
-                IRLOG_WARNING( "CIRIcyFlowReader::ExtractMetaDataL - Song delimiter was not found" );
-                artistPtr.Set( streamTitlePtr );
-                }
-
-            HBufC* artist = DecodeMetadataStringLC( artistPtr );
-            iMetaData->SetArtistL( *artist );
-            CleanupStack::PopAndDestroy( artist );
-
-            HBufC* song = DecodeMetadataStringLC( songPtr );
-            iMetaData->SetSongL( *song );
-            CleanupStack::PopAndDestroy( song );
-            }
-        else
-            {
-            IRLOG_WARNING( "CIRIcyFlowReader::ExtractMetaDataL - \"StreamTitle\" end was not found" );
-            }
-        }
-    else
-        {
-        IRLOG_WARNING( "CIRIcyFlowReader::ExtractMetaDataL - \"StreamTitle\" was not found" );
-        }
-
-    // Extracts the "StreamUrl" part of the meta data.
-    if ( streamUrlIndex >= 0 )
-        {
-        TPtrC8 streamUrlPtr( ptr.Mid( streamUrlIndex + KIRStreamUrl().Length() ) );
-
-        TInt streamUrlEndIndex = streamUrlPtr.Find( KIRMetaDataEndIdentifier );
-        if ( streamUrlEndIndex >= 0 )
-            {
-            streamUrlPtr.Set( streamUrlPtr.Left( streamUrlEndIndex ) );
-            HBufC* streamUrl = HBufC::NewLC( streamUrlPtr.Length() );
-            streamUrl->Des().Copy( streamUrlPtr );  // 8 bit to 16 bit descriptor conversion.
-            iMetaData->SetStreamUrlL( *streamUrl );
-            CleanupStack::PopAndDestroy( streamUrl );
-            }
-        else
-            {
-            IRLOG_WARNING( "CIRIcyFlowReader::ExtractMetaDataL - \"StreamUrl\" end was not found" );
-            }
-        }
-    else
-        {
-        IRLOG_WARNING( "CIRIcyFlowReader::ExtractMetaDataL - \"StreamUrl\" was not found" );
-        }
-
-    iDataObserver.MetadataReceived( *iMetaData );
-
-    IRLOG_INFO4( "CIRIcyFlowReader::ExtractMetaDataL - Exit (artist=%S, song=%S, streamUrl=%S)", &iMetaData->Artist(), &iMetaData->Song(), &iMetaData->StreamUrl() );
-	}
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::DecodeMetadataStringLC
-// ---------------------------------------------------------------------------
-//
-HBufC* CIRIcyFlowReader::DecodeMetadataStringLC( const TDesC8& aString ) const
-    {
-    IRLOG_DEBUG( "CIRIcyFlowReader::DecodeMetadataStringLC" );
-    HBufC* decodedString = NULL;
-    if ( IsUtf8Encoded( aString ) )
-        {
-        TRAPD( err, 
-              IRLOG_DEBUG( "CIRIcyFlowReader::DecodeMetadataStringLC - String is UTF-8 encoded" );
-              decodedString = CnvUtfConverter::ConvertToUnicodeFromUtf8L( aString );
-             )
-        if ( err != KErrNone )
-            {
-            IRLOG_ERROR2( "CIRIcyFlowReader::DecodeMetadataStringLC - UTF-8 conversion failed, err=%d", err );
-            decodedString = HBufC::NewL( aString.Length() ); 
-            decodedString->Des().Copy( aString ); // 8 bit to 16 bit descriptor conversion (ISO-8859-1).    
-            }
-        }
-    else
-        {
-        decodedString = HBufC::NewL( aString.Length() ); 
-        decodedString->Des().Copy( aString ); // 8 bit to 16 bit descriptor conversion (ISO-8859-1).    
-        }
-    CleanupStack::PushL( decodedString );
-    IRLOG_DEBUG2( "CIRIcyFlowReader::DecodeMetadataStringLC - Returning %S", decodedString );    
-    return decodedString;
-    }
-
-// ---------------------------------------------------------------------------
-// CIRIcyFlowReader::IsUtf8Encoded
-// ---------------------------------------------------------------------------
-//
-TBool CIRIcyFlowReader::IsUtf8Encoded( const TDesC8& aData ) const
-    {
-    IRLOG_DEBUG( "CIRIcyFlowReader::IsUtf8Encoded" );    
-    TBool foundUtf8( EFalse );
-    
-    for ( TInt i(0); i + 1 < aData.Length() && !foundUtf8; i++ )
-        {
-        if ( ( aData[i] & KIRUtf8_2B1stByteMask ) == KIRUtf8_2B1stBytePrefix )
-            {
-            // Two-byte presentation: 110yyyyy 10zzzzzz
-            if ( ( aData[i + 1] & KIRUtf8FollowingByteMask ) == KIRUtf8FollowingBytePrefix )
-                {
-                foundUtf8 = ETrue;
-                }
-            }
-        else if ( ( aData[i] & KIRUtf8_3B1stByteMask ) == KIRUtf8_3B1stBytePrefix && 
-                  i + 2 < aData.Length() )
-            {
-            // Three-byte presentation: 1110xxxx 10yyyyyy 10zzzzzz
-            if ( ( aData[i + 1] & KIRUtf8FollowingByteMask ) == KIRUtf8FollowingBytePrefix && 
-                 ( aData[i + 2] & KIRUtf8FollowingByteMask ) == KIRUtf8FollowingBytePrefix )
-                {
-                foundUtf8 = ETrue;
-                }
-            }
-        else if ( ( aData[i] & KIRUtf8_4B1stByteMask ) == KIRUtf8_4B1stBytePrefix &&
-                i + KThree < aData.Length() )
-            {
-            // Four-byte presentation: 11110www 10xxxxxx 10yyyyyy 10zzzzzz
-            if ( ( aData[i + 1] & KIRUtf8FollowingByteMask ) == KIRUtf8FollowingBytePrefix && 
-                 ( aData[i + 2] & KIRUtf8FollowingByteMask ) == KIRUtf8FollowingBytePrefix && 
-                 ( aData[i + KThree] & KIRUtf8FollowingByteMask ) == KIRUtf8FollowingBytePrefix )
-                {
-                foundUtf8 = ETrue;
-                }
-            }
-        else
-            {
-            // NOP
-            }
-        }
-    IRLOG_DEBUG2( "CIRIcyFlowReader::IsUtf8Encoded - Returning %d", foundUtf8 );    
-    return foundUtf8;
-    }
-