--- a/upnpmpxplugins/upnpplaybackplugins/src/upnptrack.cpp Mon Nov 01 13:44:24 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,754 +0,0 @@
-/*
-* Copyright (c) 2008 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: Class for containing and obtaining music track-specific data
-* from media server
-*
-*/
-
-
-
-
-
-
-// INCLUDES
-#include <mpxmediaaudiodefs.h>
-#include <mpxmediamusicdefs.h>
-#include <mpxmediageneraldefs.h>
-#include <mpxmedia.h>
-#include <mpxattribute.h>
-#include <mpxplaybackpluginobserver.h>
-#include <mpxmessagegeneraldefs.h> // for messaging
-#include <mpxplaybackmessagedefs.h> // for messaging
-
-#include <escapeutils.h> // for unicode conversion
-
-#include <upnpitem.h>
-#include <upnpobject.h>
-#include "upnpitemutility.h" // for FindElementByName & ResourceFromItemL
-#include "upnpfileutility.h" // for IsFileProtectedL
-#include "upnpconstantdefs.h" // browse filtering and item element names
-#include <upnpdlnaprotocolinfo.h> // for resolving object mimetype
-#include "upnpavcontroller.h"
-#include "upnpavbrowsingsession.h"
-#include "upnpavdevice.h"
-#include "upnpavdevicelist.h"
-
-#include "upnpitemresolverobserver.h" // MUPnPItemResolverObserver
-#include "upnpitemresolverfactory.h" // factory class
-#include "upnpitemresolver.h" // MUPnPItemResolver
-
-#include "upnptrackobserver.h"
-#include "upnptrack.h"
-
-_LIT( KComponentLogfile, "musicplugins.txt");
-#include "upnplog.h"
-
-// CONSTANTS
-_LIT16( KUPnPPrefix, "upnp:" ); // Prefix for separate local/remote song
-const TInt KUPnPPrefixLength = 5;
-const TInt KCharCodeColon = 58;
-const TInt KCharCodeSeparate = 42;
-const TInt InitialTrackDuration = 1;
-_LIT( KTimeFormatYearOnly, "%F%Y" );
-
-// ======== MEMBER FUNCTIONS ========
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::NewL
-// 1st phase constructor.
-// --------------------------------------------------------------------------
-//
-CUPnPTrack* CUPnPTrack::NewL( MUPnPAVController& aAvController )
- {
- __LOG( "CUPnPTrack::NewL" );
- CUPnPTrack* self = new( ELeave ) CUPnPTrack( aAvController );
- return self;
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::Delete
-// deletor
-// --------------------------------------------------------------------------
-//
-void CUPnPTrack::Delete()
- {
- __LOG1( "CUPnPTrack::Delete, state=%d", iState );
- if ( iState == EStateResolving )
- {
- // asynchronous delete - will be deleted after
- // asynchronous operation is complete. This is because the
- // S60 command can not be cancelled
- iState = EStateSelfDestruct;
- }
- else
- {
- delete this;
- }
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::CUPnPTrack
-// Default constructor.
-// --------------------------------------------------------------------------
-//
-CUPnPTrack::CUPnPTrack( MUPnPAVController& aAvController )
- : iAvController( aAvController )
- , iQueriedAttributes()
- {
- iBrowsingSession = NULL;
- iOriginalURI = NULL;
- iMediaServer = NULL;
- iObjectId = NULL;
- iTrackObserver = NULL;
- // Use initial duration value (1). It will guarantee that in
- // case were remote device does not support duration query and playback
- // is unpaused, SetPosition is called with real value even
- // if remote player does not return real value for getposition
- // call. Note that SetPosition(0) is used when user really wants
- // to move to track beginning.
- iTrackDuration = InitialTrackDuration;
- iIsItemSolved = EFalse;
- iState = EStateIdle;
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::~CUPnPTrack
-// destructor.
-// --------------------------------------------------------------------------
-//
-CUPnPTrack::~CUPnPTrack()
- {
- __LOG( "CUPnPTrack::~CUPnPTrack()" );
- StopBrowsingSession();
-
- // Free memory of owned members
- delete iOriginalURI;
- delete iMediaServer;
- delete iObjectId;
- delete iItemResolver;
- iItemResolver = 0;
- __LOG( "CUPnPTrack::~CUPnPTrack End" );
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::ResolveURIL
-// Resolve local / remote URI.
-// --------------------------------------------------------------------------
-//
-void CUPnPTrack::ResolveURIL( const TDesC& aCodedTrackUri,
- MUPnPTrackObserver& aTrackObserver,
- TPlaybackDirection aPlaybackDirection )
- {
- __LOG( "CUPnPTrack::ResolveURI" );
-
- delete iOriginalURI;
- iOriginalURI = 0;
- delete iMediaServer;
- iMediaServer = 0;
- delete iObjectId;
- iObjectId = 0;
- iTrackObserver = &aTrackObserver;
-
- // Either local to remote or remote to remote
- if( aPlaybackDirection == EDirectionRemote )
- {
- if( aCodedTrackUri.Find( KUPnPPrefix ) == 0 )
- {
- // track is located in remote
- iTrackLocation = ETrackLocationRemote;
- // parse and save media server id and object id
- ParsePiecesL( aCodedTrackUri );
- // start a browsing session
- StartBrowsingSessionL();
- // create resolver
- iItemResolver =
- UPnPItemResolverFactory::NewRemoteItemResolverL(
- *iObjectId, *iBrowsingSession,
- iDefaultSelector, KFilterCommon );
- }
- else // Local stored. Save URI to local member
- {
- // track is located in local file system
- iTrackLocation = ETrackLocationLocal;
- // store original URI
- iOriginalURI = HBufC::NewL( aCodedTrackUri.Length() );
- iOriginalURI->Des().Copy( aCodedTrackUri );
- // check for DRM protection
- if ( UPnPFileUtility::IsFileProtectedL( iOriginalURI->Des() ) )
- {
- // call back directly with an error code
- iTrackObserver->ResolveURIComplete( KErrNotSupported );
- return;
- }
- else
- {
- // create resolver.
- iItemResolver =
- UPnPItemResolverFactory::NewLocalItemResolverL(
- *iOriginalURI, iAvController, iFirstSelector,
- UPnPItemResolverFactory::EOmitDrmCheck );
- }
- }
- }
- else // Remote to local direction
- {
- // track is located in remote
- iTrackLocation = ETrackLocationRemote;
- // parse and save media server id and object id
- ParsePiecesL( aCodedTrackUri );
- // start a browsing session
- StartBrowsingSessionL();
- // create resolver
- iItemResolver =
- UPnPItemResolverFactory::NewDownloadItemResolverL(
- *iObjectId, iAvController, *iBrowsingSession,
- iFirstSelector, KFilterCommon );
- }
-
- // Resolve remote item. Calls back to ResolveComplete
- iState = EStateResolving;
- TRAPD( e, iItemResolver->ResolveL( *this ); )
- if ( e != KErrNone )
- {
- if ( iState == EStateSelfDestruct )
- {
- __LOG( "CUPnPTrack: self-destructing" );
- delete this;
- }
- else
- {
- iState = EStateIdle;
- User::Leave( e );
- }
- }
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::StartBrowsingSessionL
-// Finds the apropriate mediaserver and starts a browsing session
-// --------------------------------------------------------------------------
-//
-void CUPnPTrack::StartBrowsingSessionL()
- {
- // Get list of media servers
- CUpnpAVDeviceList* devices = iAvController.GetMediaServersL();
- CleanupStack::PushL( devices );
-
- // Find out index of wanted media server from media server list
- TInt index = KErrNotFound;
- TInt count = devices->Count();
-
- for( TInt i = 0; i < count; i++ )
- {
- // If media server id match.
- if( !iMediaServer->Compare( (*devices)[ i ]->Uuid() ) )
- {
- index = i;
- break;
- }
- }
-
- // Leave if media server does not find by id
- if( index == KErrNotFound )
- {
- __LOG1( "CUPnPTrack: Media server not found: %S",
- iMediaServer );
- User::Leave( KErrNotFound );
- }
-
- // start a browsing session
- iBrowsingSession = &iAvController.StartBrowsingSessionL(
- *(*devices)[ index ] );
- CleanupStack::PopAndDestroy( devices );
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::StopBrowsingSession
-// Finds the apropriate mediaserver and starts a browsing session
-// --------------------------------------------------------------------------
-//
-void CUPnPTrack::StopBrowsingSession()
- {
- // Stop browsing session if exist.
- if( iBrowsingSession )
- {
- __LOG( "Stop browsing session" );
- iAvController.StopBrowsingSession( *iBrowsingSession );
- iBrowsingSession = 0;
- }
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::URI
-// Return original URI of track.
-// --------------------------------------------------------------------------
-//
-const TDesC& CUPnPTrack::URI() const
- {
- __ASSERTD( iOriginalURI != 0,__FILE__, __LINE__ );
- return *iOriginalURI;
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::UpnpURI
-// Return True UPNP URI of track.
-// --------------------------------------------------------------------------
-//
-const TDesC8& CUPnPTrack::UpnpURI() const
- {
- __ASSERTD( iIsItemSolved,__FILE__, __LINE__ );
- return iItemResolver->Resource().Value();
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::UpnpItem
-// Return True UPNP item representing the track
-// --------------------------------------------------------------------------
-//
-const CUpnpItem& CUPnPTrack::UpnpItem() const
- {
- __ASSERTD( iIsItemSolved,__FILE__, __LINE__ );
- return iItemResolver->Item();
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::FilePath
-// Returns the file path of local item
-// --------------------------------------------------------------------------
-//
-const TDesC& CUPnPTrack::FilePath() const
- {
- __ASSERTD( iTrackLocation == ETrackLocationRemote, __FILE__, __LINE__ );
- __ASSERTD( iIsItemSolved,__FILE__, __LINE__ );
- return iItemResolver->Resource().FilePath();
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::IsRemote
-// Return location of track. ETrue = remote. EFalse = local
-// --------------------------------------------------------------------------
-//
-TBool CUPnPTrack::IsRemote() const
- {
- return iTrackLocation == ETrackLocationRemote;
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::TrackDuration
-// returns duration of the track
-// --------------------------------------------------------------------------
-//
-TInt CUPnPTrack::TrackDuration()
- {
- __LOG1( "CUPnPTrack::TrackDuration duration: %d", iTrackDuration );
- TInt ms = InitialTrackDuration;
- if ( iTrackDuration > InitialTrackDuration )
- {
- ms = iTrackDuration;
- }
- else if ( iIsItemSolved )
- {
- const CUpnpAttribute* attr = UPnPItemUtility
- ::FindAttributeByName( iItemResolver->Resource(),
- KAttributeDuration );
- if ( attr != 0 )
- {
- if ( UPnPItemUtility::UPnPDurationAsMilliseconds(
- attr->Value(), ms ) == KErrNone )
- {
- // store duration for quicker future queries
- iTrackDuration = ms;
- __LOG1( "store duration: %d", iTrackDuration );
- }
- }
- }
- return ms;
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::SetTrackDuration
-// overrides duration of the track
-// --------------------------------------------------------------------------
-//
-void CUPnPTrack::SetTrackDuration( TInt aMilliseconds )
- {
- iTrackDuration = aMilliseconds;
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::GetMetaDataL
-// Get metadata information for track from media server
-// --------------------------------------------------------------------------
-//
-void CUPnPTrack::GetMetaDataL( const TArray<TMPXAttribute>& aAttrs,
- MMPXPlaybackPluginObserver& aObs )
- {
- // Check if remote track
- if( iTrackLocation == ETrackLocationLocal )
- {
- __LOG( "CUPnPTrack::GetMetaData - No metadata for local track!" );
- User::Leave( KErrNotSupported );
- }
-
- if ( iIsItemSolved )
- {
- __LOG( "CUPnPTrack::GetMetaDataL" );
- DeliverMedataL( aAttrs, aObs );
- }
- else
- {
- __LOG( "CUPnPTrack::GetMetaDataL - pending" );
- iMetadataObserver = &aObs;
- for( TInt i = 0; i < aAttrs.Count(); ++i )
- {
- iQueriedAttributes.AppendL( aAttrs[i] );
- }
- }
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::SendMediaChangedEventL
-// --------------------------------------------------------------------------
-//
-void CUPnPTrack::SendMediaChangedEventL(
- MMPXPlaybackPluginObserver& aObs )
- {
- RArray<TMPXAttribute> attrs;
- CleanupClosePushL( attrs );
- attrs.AppendL( KMPXMediaGeneralTitle );
- attrs.AppendL( KMPXMediaMusicArtist );
- attrs.AppendL( KMPXMediaMusicAlbum );
- attrs.AppendL( KMPXMediaMusicGenre );
- attrs.AppendL( KMPXMediaGeneralDate );
- attrs.AppendL( KMPXMediaMusicYear );
- attrs.AppendL( KMPXMediaGeneralComment );
- attrs.AppendL( KMPXMediaGeneralMimeType );
-
- // Create and fill CMPXMedia class
- RArray<TInt> suppIds;
- CleanupClosePushL( suppIds );
- suppIds.AppendL( KMPXMediaIdMusic );
- suppIds.AppendL( KMPXMediaIdGeneral );
- suppIds.AppendL( KMPXMediaIdAudio );
- CMPXMedia* media = CMPXMedia::NewL( suppIds.Array() );
- CleanupStack::PopAndDestroy( &suppIds );
- CleanupStack::PushL( media );
- FillMediaFromItemL( *media, attrs.Array() );
-
- // create an MPX message
- CMPXMessage* msg = CMPXMessage::NewL();
- CleanupStack::PushL( msg );
- msg->SetTObjectValueL<TMPXMessageId>(
- KMPXMessageGeneralId, KMPXMessagePbMediaChanged );
- msg->SetCObjectValueL<CMPXMedia>(
- KMPXMessagePbMedia, media );
-
- // send message
- aObs.HandlePlaybackMessage( *msg );
-
- CleanupStack::PopAndDestroy( msg );
- CleanupStack::PopAndDestroy( media );
- CleanupStack::PopAndDestroy( &attrs );
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::DeliverMedatataL
-// --------------------------------------------------------------------------
-//
-void CUPnPTrack::DeliverMedataL( const TArray<TMPXAttribute>& aAttrs,
- MMPXPlaybackPluginObserver& aObs, TInt aError )
- {
- __LOG( "CUPnPTrack::DeliverMedatata");
-
- // Create and fill CMPXMedia class
- RArray<TInt> suppIds;
- CleanupClosePushL( suppIds );
- suppIds.AppendL( KMPXMediaIdMusic );
- suppIds.AppendL( KMPXMediaIdGeneral );
- suppIds.AppendL( KMPXMediaIdAudio );
- CMPXMedia* media = CMPXMedia::NewL( suppIds.Array() );
- CleanupStack::PopAndDestroy( &suppIds );
- CleanupStack::PushL( media );
-
- if ( aError == KErrNone )
- {
- FillMediaFromItemL( *media, aAttrs );
- }
-
- // Return metadata
- aObs.HandleMedia( *media, aError );
- CleanupStack::PopAndDestroy( media );
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::FillMediaFromItemL
-// --------------------------------------------------------------------------
-//
-void CUPnPTrack::FillMediaFromItemL( CMPXMedia& aMedia,
- const TArray<TMPXAttribute>& aAttrs )
- {
- __ASSERTD( iIsItemSolved,__FILE__, __LINE__ );
-
- // Fill metadata
- const CUpnpElement* elem;
- // Song title
- if( Exists( aAttrs, KMPXMediaGeneralTitle ) )
- {
- __LOG( "CUPnPTrack: Metadata: Title");
- aMedia.SetTextValueL(
- KMPXMediaGeneralTitle, *To16LC(
- iItemResolver->Item().Title() ) );
- CleanupStack::PopAndDestroy();
- }
- // Artist
- if( Exists( aAttrs, KMPXMediaMusicArtist ) )
- {
- if ( ( elem = UPnPItemUtility::FindElementByName(
- iItemResolver->Item(), KElementArtist ) ) != 0 )
- {
- __LOG( "CUPnPTrack: Metadata: Artist" );
- aMedia.SetTextValueL(
- KMPXMediaMusicArtist, *To16LC( elem->Value() ) );
- CleanupStack::PopAndDestroy();
- }
- else if ( ( elem = UPnPItemUtility::FindElementByName(
- iItemResolver->Item(), KElementCreator ) ) != 0 )
- {
- __LOG( "CUPnPTrack: Metadata Creator" );
- aMedia.SetTextValueL(
- KMPXMediaMusicArtist, *To16LC( elem->Value() ) );
- CleanupStack::PopAndDestroy();
- }
- }
- // Album
- if( Exists( aAttrs, KMPXMediaMusicAlbum ) )
- {
- if ( ( elem = UPnPItemUtility::FindElementByName(
- iItemResolver->Item(), KElementAlbum ) ) != 0 )
- {
- __LOG( "CUPnPTrack: Metadata: Album");
- aMedia.SetTextValueL(
- KMPXMediaMusicAlbum, *To16LC( elem->Value() ) );
- CleanupStack::PopAndDestroy();
- }
- }
- // Genre
- if( Exists( aAttrs, KMPXMediaMusicGenre ) )
- {
- if ( ( elem = UPnPItemUtility::FindElementByName(
- iItemResolver->Item(), KElementGenre ) ) != 0 )
- {
- __LOG( "CUPnPTrack: Metadata: Genre" );
- aMedia.SetTextValueL(
- KMPXMediaMusicGenre, *To16LC( elem->Value() ) );
- CleanupStack::PopAndDestroy();
- }
- }
- // Date / Year
- if( ( elem = UPnPItemUtility::FindElementByName(
- iItemResolver->Item(), KElementDate ) ) != 0 )
- {
- TTime timestamp;
- TInt conversionError =
- UPnPItemUtility::UPnPDateAsTTime( elem->Value(), timestamp );
- if ( conversionError == KErrNone )
- {
- if ( Exists( aAttrs, KMPXMediaGeneralDate ) )
- {
- __LOG( "CUPnPTrack: Metadata: Date" );
- aMedia.SetTextValueL(
- KMPXMediaGeneralDate, iTempBuf );
- }
- if ( Exists( aAttrs, KMPXMediaMusicYear ) )
- {
- __LOG( "CUPnPTrack: Metadata: Year" );
- timestamp.FormatL( iTempBuf, KTimeFormatYearOnly );
- aMedia.SetTextValueL(
- KMPXMediaMusicYear, iTempBuf );
- }
- }
- }
- // Duration
- if( Exists( aAttrs, KMPXMediaGeneralDuration ) )
- {
- TInt duration = TrackDuration();
- if ( duration >= 0 )
- {
- aMedia.SetTObjectValueL<TInt>(
- KMPXMediaGeneralDuration, duration );
- }
- }
- // Size
- if( Exists( aAttrs, KMPXMediaGeneralSize ) )
- {
- const CUpnpAttribute* attr = UPnPItemUtility
- ::FindAttributeByName( iItemResolver->Resource(),
- KAttributeSize );
- if ( attr != 0 )
- {
- __LOG( "CUPnPTrack: Metadata: Size" );
- TInt size;
- TLex8 sizeconvert( attr->Value() );
- if ( sizeconvert.Val( size ) == KErrNone )
- {
- aMedia.SetTObjectValueL<TInt>(
- KMPXMediaGeneralSize, size );
- }
- }
- }
- // Mimetype
- if( Exists( aAttrs, KMPXMediaGeneralMimeType ) )
- {
- const CUpnpAttribute* attr = UPnPItemUtility
- ::FindAttributeByName( iItemResolver->Resource(),
- KAttributeProtocolInfo );
- if ( attr != 0 )
- {
- __LOG( "CUPnPTrack: Metadata: MimeType" );
- CUpnpDlnaProtocolInfo* pInfo =
- CUpnpDlnaProtocolInfo::NewL( attr->Value() );
- CleanupStack::PushL( pInfo );
- aMedia.SetTextValueL(
- KMPXMediaGeneralMimeType, *To16LC( pInfo->ThirdField() ) );
- CleanupStack::PopAndDestroy();
- CleanupStack::PopAndDestroy( pInfo );
- pInfo = NULL;
- }
- }
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::Exists
-// --------------------------------------------------------------------------
-//
-TBool CUPnPTrack::Exists( const TArray<TMPXAttribute>& aAttrs,
- const TMPXAttributeData& aAttrData ) const
- {
- TBool found = EFalse;
- for( TInt i = 0; i < aAttrs.Count() && !found; ++i )
- {
- if ( aAttrs[i].ContentId() == aAttrData.iContentId &&
- aAttrs[i].AttributeId() & aAttrData.iAttributeId )
- {
- found = ETrue;
- }
- }
- return found;
- }
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::To16LC
-// --------------------------------------------------------------------------
-//
-const HBufC16* CUPnPTrack::To16LC( const TDesC8& aText )
- {
- HBufC16* result = 0;
- result = EscapeUtils::ConvertToUnicodeFromUtf8L( aText );
- CleanupStack::PushL( result );
- return result;
- }
-
-// --------------------------------------------------------------------------
-// callbacks from MUPnPItemResolverObserver
-// --------------------------------------------------------------------------
-//
-void CUPnPTrack::ResolveComplete( const MUPnPItemResolver& /*aResolver*/,
- TInt aError )
- {
- __LOG1( "CUPnPTrack::ResolveComplete err: %d", aError );
- iIsItemSolved = ETrue;
- if ( iState == EStateResolving )
- {
- iState = EStateReady;
-
- // handle pending metadata query
- if ( iTrackLocation == ETrackLocationRemote && iMetadataObserver )
- {
- __LOG( "Handle pending metadata query");
- TRAP_IGNORE(
- DeliverMedataL( iQueriedAttributes.Array(), *iMetadataObserver,
- aError ) );
- iMetadataObserver = 0;
- iQueriedAttributes.Reset();
- }
-
- // call back
- MUPnPTrackObserver& observer = *iTrackObserver;
- iTrackObserver = 0;
- observer.ResolveURIComplete( aError );
- }
- else if ( iState == EStateSelfDestruct )
- {
- __LOG( "CUPnPTrack: self-destructing" );
- delete this;
- }
- }
-
-// --------------------------------------------------------------------------
-// Private methods of CUPnPTrack
-// --------------------------------------------------------------------------
-
-// --------------------------------------------------------------------------
-// CUPnPTrack::ParsePiecesL
-// Parse and save media server id and object id from given descriptor
-// --------------------------------------------------------------------------
-//
-void CUPnPTrack::ParsePiecesL( const TDesC& aSong )
- {
- // Delete if already exist
- if( iMediaServer )
- {
- delete iMediaServer;
- iMediaServer = 0;
- }
- if( iObjectId )
- {
- delete iObjectId;
- iObjectId = 0;
- }
-
- // Leave if argument is not valid
- if( aSong.Length() < KUPnPPrefixLength )
- {
- User::Leave( KErrArgument );
- }
-
- TInt lenght = aSong.Length();
- TInt position = 0;
- TChar colon( KCharCodeColon );
- TChar separate( KCharCodeSeparate );
-
- // At first separe "upnp:" prefix from descriptor
- position = aSong.Locate( colon );
- TPtrC tmp = aSong.Mid( position + 1, (lenght - KUPnPPrefixLength ) );
-
- // Get media server id
- position = tmp.Locate( separate );
- // Leave if separator character not found
- if( position == KErrNotFound )
- {
- User::Leave( KErrNotFound );
- }
- TPtrC mediaserverId = tmp.Left( position );
- iMediaServer = HBufC8::NewL( mediaserverId.Length() );
- iMediaServer->Des().Copy( mediaserverId );
-
- // Get object id
- TPtrC objId = tmp.Mid( position + 1, ( (tmp.Length()
- - mediaserverId.Length() ) - 1 ) );
- iObjectId = HBufC8::NewL( objId.Length() );
- iObjectId->Des().Copy( objId );
- }
-
-