--- 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;
- }
-