--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/upnpsharing/upnpsharingalgorithm/src/upnpcontainerresolver.cpp Wed Nov 03 11:45:09 2010 +0200
@@ -0,0 +1,819 @@
+/*
+* Copyright (c) 2009 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: Implementation of the class CUpnpContainerResolver.
+*
+*/
+
+#include "upnpconstantdefs.h" // upnpobject class types
+#include <utf.h> // for CnvUtfConverter
+#include <bautils.h> // for BaflUtils
+#include <pathinfo.h> // for PathInfo
+#include <upnpitem.h> // for CUpnpItem
+#include <upnpelement.h> // for CUpnpElement
+#include "upnpitemutility.h" // for CUpnpItemUtility
+#include <upnpsharingalgorithm.rsg>
+#include <mm/mmcleanup.h> // for array cleanup
+
+#include "upnpcontainerresolver.h"
+#include "upnpsharingalgorithmconstants.h"
+#include "upnplog.h"
+#include "upnpcdsliteobject.h"
+
+const TInt KDateStringLength = 10;
+const TInt KMaxDateStringLength = 30;
+const TInt KMonthAndDayLength = 2;
+const TInt KMonthAndDayDigitLimit = 10;
+const TInt KSeparatorLength = 1;
+const TInt KDateYearLength = 4;
+const TInt KSecondSeparatorPosition = 7;
+
+_LIT( KZero, "0" );
+
+// Year, e.g. "2008"
+_LIT( KDateTimeYear,"%Y%3" );
+
+// Month, e.g. "October"
+_LIT( KDateTimeMonth,"%N%2" );
+
+// Day, e.g. "4th Mon"
+_LIT( KDateTimeDay,"%X%*D%1 %*E" );
+
+
+// --------------------------------------------------------------------------
+// CUpnpContainerResolver::NewL
+// --------------------------------------------------------------------------
+//
+CUpnpContainerResolver* CUpnpContainerResolver::NewL(
+ CUpnpCdsLiteObjectArray& aCdsLiteObjectArray )
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::NewL" );
+
+ CUpnpContainerResolver* self =
+ new ( ELeave ) CUpnpContainerResolver( aCdsLiteObjectArray );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CUpnpContainerResolver::ResolveContainerStructureL
+// --------------------------------------------------------------------------
+//
+RPointerArray<CUpnpContainer>
+ CUpnpContainerResolver::ResolveContainerStructureL( CUpnpItem& aItem )
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::\
+ResolveContainerStructureL" );
+
+ // List of needed containers
+ RPointerArray<CUpnpContainer> containers;
+ CleanupResetAndDestroyPushL( containers );
+
+ RPointerArray<HBufC8> containerNames;
+ CleanupResetAndDestroyPushL( containerNames );
+
+ HBufC8* itemParent = NULL;
+
+ if ( aItem.ObjectClass() == KClassAudioMusicTrack )
+ {
+ // Fill container name array, containers must be in
+ // hierarchical order staring from root
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_MUSIC_TEXT );
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_ALL_TEXT );
+
+ // Create non-existing containers
+ itemParent = CreateContainersL( containerNames,
+ containers,
+ KMusicClassContainer );
+ CleanupStack::PushL( itemParent );
+ }
+ else if ( aItem.ObjectClass() == KClassImage )
+ {
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_IMAGE_TEXT );
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_ALL_TEXT );
+
+ itemParent = CreateContainersL( containerNames,
+ containers,
+ KImageClassContainer );
+ CleanupStack::PushL( itemParent );
+ }
+ else if ( aItem.ObjectClass() == KClassVideo )
+ {
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_VIDEO_TEXT );
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_ALL_TEXT );
+
+ itemParent = CreateContainersL( containerNames,
+ containers,
+ KVideoClassContainer );
+ CleanupStack::PushL( itemParent );
+ }
+
+ // If new containers are not needed, set item parent id here,
+ // because caller does not know the item parent container
+ if ( !containers.Count() )
+ {
+ aItem.SetParentIdL( *itemParent );
+ }
+ if ( itemParent )
+ {
+ CleanupStack::PopAndDestroy( itemParent );
+ }
+
+ // Cleanup
+ CleanupStack::PopAndDestroy( &containerNames );
+ CleanupStack::Pop( &containers );
+
+ return containers;
+ }
+
+// --------------------------------------------------------------------------
+// CUpnpContainerResolver::ResolveReferenceContainersL
+// --------------------------------------------------------------------------
+//
+RPointerArray<CUpnpContainer>
+ CUpnpContainerResolver::ResolveReferenceContainersL( TInt aType,
+ CUpnpItem& aItem )
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::\
+ResolveReferenceContainersL" );
+
+ // List of needed containers
+ RPointerArray<CUpnpContainer> containers;
+ CleanupResetAndDestroyPushL( containers );
+
+ RPointerArray<HBufC8> containerNames;
+ CleanupResetAndDestroyPushL( containerNames );
+
+ HBufC8* itemParent = NULL;
+ TInt error( KErrNone );
+
+ // Get object elements from where metadata is fetched
+ const RUPnPElementsArray& elements = aItem.GetElements();
+
+ switch( aType )
+ {
+ case EGenreType :
+ {
+ // Fill container name array, containers must be in
+ // hierarchical order starting from root
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_MUSIC_TEXT );
+ // Append "By Genre" container
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_BY_GENRE_TEXT );
+
+ // Modify "Genre" element and append it to the array
+ TRAP( error, ModifyAndAppendElementL( containerNames,
+ elements,
+ KElementGenre ));
+
+ // If metadata is missing, containers are not created
+ if ( error == KErrNone )
+ {
+ // Create non-existing containers
+ itemParent = CreateContainersL( containerNames,
+ containers,
+ KMusicClassContainer );
+ CleanupStack::PushL( itemParent );
+ }
+ break;
+ }
+ case EAlbumType :
+ {
+ // Fill container name array, containers must be in
+ // hierarchical order staring from root
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_MUSIC_TEXT );
+ // Append "By Album" container
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_BY_ALBUM_TEXT );
+
+ // Modify "Album" element and append it to the array
+ TRAP( error, ModifyAndAppendElementL( containerNames,
+ elements,
+ KElementAlbum ));
+
+ // If metadata is missing, containers are not created
+ if ( error == KErrNone )
+ {
+ // Create non-existing containers
+ itemParent = CreateContainersL( containerNames,
+ containers,
+ KMusicClassContainer );
+ CleanupStack::PushL( itemParent );
+ }
+ break;
+ }
+ case EArtistType :
+ {
+ // Fill container name array, containers must be in
+ // hierarchical order staring from root
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_MUSIC_TEXT );
+ // Append "By Artist" container
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_BY_ARTIST_TEXT );
+
+ // Modify "Artist" element and append it to the array
+ TRAP( error, ModifyAndAppendElementL( containerNames,
+ elements,
+ KElementArtist ));
+
+ // If metadata is missing, containers are not created
+ if ( error == KErrNone )
+ {
+ // Create non-existing containers
+ itemParent = CreateContainersL( containerNames,
+ containers,
+ KMusicClassContainer );
+ CleanupStack::PushL( itemParent );
+ }
+ break;
+ }
+ case EMusicByDateType :
+ {
+ // Fill container name array, containers must be in
+ // hierarchical order staring from root
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_MUSIC_TEXT );
+ // Append "By Date" container
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_BY_DATE_TEXT );
+
+ TTime time;
+ HBufC8* elementValue = GetElementL( elements, KElementDate );
+ if ( elementValue )
+ {
+ CleanupStack::PushL( elementValue );
+ HBufC8* adjustedDate = AdjustDateL( *elementValue );
+ CleanupStack::PopAndDestroy( elementValue );
+ CleanupStack::PushL( adjustedDate );
+
+ error = UPnPItemUtility::UPnPDateAsTTime( *adjustedDate,
+ time );
+
+ CleanupStack::PopAndDestroy( adjustedDate );
+
+ if ( error == KErrNone &&
+ adjustedDate->Length() > 0 )
+ {
+ TBuf<KMaxDateStringLength> finalTime;
+
+ // Append Year container
+ time.FormatL( finalTime, KDateTimeYear );
+ HBufC8* timeStr =
+ CnvUtfConverter::ConvertFromUnicodeToUtf8L(
+ finalTime );
+ CleanupStack::PushL( timeStr );
+ containerNames.Append( timeStr );
+ CleanupStack::Pop( timeStr );
+
+ // Create non-existing containers
+ itemParent = CreateContainersL( containerNames,
+ containers,
+ KMusicClassContainer );
+ CleanupStack::PushL( itemParent );
+ }
+ }
+ else
+ {
+ error = KErrNotFound;
+ }
+
+ break;
+ }
+ case EImageByDateType :
+ {
+ // Fill container name array, containers must be in
+ // hierarchical order staring from root
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_IMAGE_TEXT );
+
+ error = AddByDateContainersL( containerNames, elements );
+
+ // If metadata is missing, containers are not created
+ if ( error == KErrNone )
+ {
+ // Create non-existing containers
+ itemParent = CreateContainersL( containerNames,
+ containers,
+ KImageClassContainer );
+ CleanupStack::PushL( itemParent );
+ }
+ break;
+ }
+ case EVideoByDateType :
+ {
+ // Fill container name array, containers must be in
+ // hierarchical order staring from root
+ AppendContainerNameToArrayL( containerNames,
+ R_UPNP_SHARE_VIDEO_TEXT );
+
+ error = AddByDateContainersL( containerNames, elements );
+
+ // If metadata is missing, containers are not created
+ if ( error == KErrNone )
+ {
+ // Create non-existing containers
+ itemParent = CreateContainersL( containerNames,
+ containers,
+ KVideoClassContainer );
+ CleanupStack::PushL( itemParent );
+ }
+ break;
+ }
+ default:
+ {
+ User::Leave( KErrNotSupported );
+ break;
+ }
+ }
+
+ // If new containers are not needed, set item parent id here,
+ // because caller does not know the item parent container.
+ // If metadata is not found, item is left untouched.
+ if ( !containers.Count() &&
+ error == KErrNone )
+ {
+ aItem.SetParentIdL( *itemParent );
+ }
+
+ if ( itemParent )
+ {
+ CleanupStack::PopAndDestroy( itemParent );
+ }
+
+ // Cleanup
+ CleanupStack::PopAndDestroy( &containerNames );
+ CleanupStack::Pop( &containers );
+
+ return containers;
+ }
+
+// --------------------------------------------------------------------------
+// CUpnpContainerResolver::ResolveEmptyContainersL
+// --------------------------------------------------------------------------
+//
+RPointerArray<CUpnpCdsLiteObject>
+ CUpnpContainerResolver::ResolveEmptyContainersL( TDesC8& aContainerId )
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::\
+ResolveEmptyContainersL" );
+
+ RPointerArray<CUpnpCdsLiteObject> emptyContainers;
+ TBool empty( ETrue );
+ const TDesC8* parentId = &aContainerId;
+
+ // Search empty containers from the array
+ while ( empty &&
+ parentId->Match( KRootContainer ) == KErrNotFound )
+ {
+ TInt count = iCdsLiteObjectArray.ChildCount( aContainerId );
+ if ( iCdsLiteObjectArray.ChildCount( *parentId ) > 1 )
+ {
+ // There is more than one item inside container
+ // Current container must not be removed, exit loop
+ empty = EFalse;
+ }
+ else
+ {
+ // Get object index from CDS object array
+ TInt objectIndex =
+ iCdsLiteObjectArray.FindByObjectId( *parentId );
+
+ // Append correct container from CDS object array
+ emptyContainers.Append(
+ &iCdsLiteObjectArray.ObjectAtL( objectIndex ) );
+
+ // Get parent container id of the current container
+ parentId =
+ &iCdsLiteObjectArray.ObjectAtL( objectIndex ).ParentId();
+ }
+ }
+ return emptyContainers;
+ }
+
+// --------------------------------------------------------------------------
+// CUpnpContainerResolver::ConstructL
+// --------------------------------------------------------------------------
+//
+void CUpnpContainerResolver::ConstructL()
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::\
+ConstructL" );
+
+ // Open file server session
+ User::LeaveIfError( iFs.Connect() );
+
+ TFileName resourceFileName( KSharingAlgorithmRscFile );
+
+ // Get the exact filename of the resource file
+ BaflUtils::NearestLanguageFile( iFs, resourceFileName );
+
+ TInt err( KErrNone );
+ // Open resource file
+ TRAP( err, iResourceFile.OpenL( iFs, resourceFileName ) );
+
+ if ( err != KErrNone )
+ {
+ // If not found, try to read resource file from memory card
+ resourceFileName.Copy( PathInfo::MemoryCardRootPath() );
+ resourceFileName.Delete( 2, 2 ); // remove //
+ resourceFileName.Append( KSharingAlgorithmRscFile );
+ iResourceFile.OpenL( iFs, resourceFileName );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CCUpnpContainerResolver::~CUpnpContainerResolver
+// --------------------------------------------------------------------------
+//
+CUpnpContainerResolver::~CUpnpContainerResolver()
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::\
+~CUpnpContainerResolver" );
+
+ // Close resource file
+ iResourceFile.Close();
+
+ // Close file server session
+ iFs.Close();
+ }
+
+// --------------------------------------------------------------------------
+// CCUpnpContainerResolver::CreateContainerL
+// --------------------------------------------------------------------------
+//
+CUpnpContainer* CUpnpContainerResolver::CreateContainerL(
+ const TDesC8& aTitle,
+ const TDesC8& aClass )
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::\
+CreateContainerL" );
+
+ CUpnpContainer* container = CUpnpContainer::NewL();
+ CleanupStack::PushL( container );
+
+ // Set container info
+ container->SetTitleL( aTitle );
+ container->SetObjectClassL( aClass );
+
+ CleanupStack::Pop( container );
+
+ return container;
+ }
+
+// --------------------------------------------------------------------------
+// CCUpnpContainerResolver::CreateContainersL
+// --------------------------------------------------------------------------
+//
+HBufC8* CUpnpContainerResolver::CreateContainersL(
+ RPointerArray<HBufC8>& aContainerNames,
+ RPointerArray<CUpnpContainer>& aContainers,
+ const TDesC8& aMediaClass )
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::\
+CreateContainersL" );
+
+ HBufC8* parentId = NULL;
+ TInt index( 1 );
+
+ // Find first media container, e.g. "Music"
+ TInt objectIndex ( iCdsLiteObjectArray.FindByMediaClassAndParentId(
+ aMediaClass, KRootContainer ) );
+
+ if ( objectIndex == KErrNotFound )
+ {
+ // Create media root container and append it to the container array.
+ // Parent container is root container ("0")
+ if ( aContainerNames.Count() )
+ {
+ CUpnpContainer* container = CreateContainerL(
+ *aContainerNames[0], aMediaClass );
+ CleanupStack::PushL( container );
+ aContainers.Append( container );
+ CleanupStack::Pop( container );
+ }
+ parentId = KRootContainer().AllocL();
+ }
+ else
+ {
+ // Remember media root container id
+ parentId = iCdsLiteObjectArray.ObjectAtL(
+ objectIndex ).ObjectId().AllocL();
+ }
+
+ // Find the first container that does not exist
+ for ( ; index < aContainerNames.Count(); index++ )
+ {
+ // Container is found by container name and parent id.
+ // If search cannot find the container, it needs to be created.
+ objectIndex = iCdsLiteObjectArray.FindByNameAndParentId(
+ *aContainerNames[index], *parentId );
+
+ if ( objectIndex == KErrNotFound )
+ {
+ break;
+ }
+ else
+ {
+ // Remember last found container id
+ parentId = iCdsLiteObjectArray.ObjectAtL(
+ objectIndex ).ObjectId().AllocL();
+ }
+ }
+
+ // Create needed containers
+ for ( TInt index2( index ); index2 < aContainerNames.Count(); index2++ )
+ {
+ CUpnpContainer* container = CreateContainerL(
+ *aContainerNames[index2], aMediaClass );
+ CleanupStack::PushL( container );
+ aContainers.Append( container );
+ CleanupStack::Pop( container );
+ }
+
+ // Use the last found object id as parent id of the first new container
+ if ( aContainers.Count() )
+ {
+ aContainers[0]->SetParentIdL( *parentId );
+ }
+
+ return parentId;
+ }
+
+// --------------------------------------------------------------------------
+// CUpnpContainerResolver::ReadResourceTextL
+// --------------------------------------------------------------------------
+//
+HBufC8* CUpnpContainerResolver::ReadResourceTextL( TInt aResourceId )
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::\
+ReadResourceTextL" );
+
+ // Load resource text
+ HBufC8* resourceString8 = iResourceFile.AllocReadLC( aResourceId );
+
+ TResourceReader theReader;
+ theReader.SetBuffer( resourceString8 );
+ HBufC16* resourceString16 = theReader.ReadHBufC16L();
+ CleanupStack::PushL( resourceString16 );
+
+ HBufC8* returnString8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L(
+ resourceString16->Des() );
+
+ CleanupStack::PopAndDestroy( resourceString16 );
+ CleanupStack::PopAndDestroy( resourceString8 );
+
+ return returnString8;
+ }
+
+// --------------------------------------------------------------------------
+// CUpnpContainerResolver::GetElementL
+// --------------------------------------------------------------------------
+//
+HBufC8* CUpnpContainerResolver::GetElementL(
+ const RUPnPElementsArray& aElements,
+ const TDesC8& aElement )
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::\
+GetElementL" );
+
+ HBufC8* elementValue = NULL;
+
+ // Find the element
+ for( TInt index = 0; index < aElements.Count(); index++ )
+ {
+ if( aElements[index]->Name().Match( aElement ) == KErrNone )
+ {
+ elementValue = aElements[index]->Value().AllocL();
+ index = aElements.Count();
+ }
+ }
+
+ return elementValue;
+ }
+
+// --------------------------------------------------------------------------
+// CUpnpContainerResolver::AdjustDateL
+// --------------------------------------------------------------------------
+//
+HBufC8* CUpnpContainerResolver::AdjustDateL( const TDesC8& aDate )
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::\
+AdjustDateL" );
+
+ HBufC* date = CnvUtfConverter::ConvertToUnicodeFromUtf8L( aDate );
+ CleanupStack::PushL( date );
+ TBuf<KMaxDateStringLength> modifiedDate;
+
+ TBuf<KMonthAndDayLength> month;
+ TBuf<KMonthAndDayLength> day;
+
+ if( aDate.Length() >= KDateStringLength )
+ {
+ // Month and day are decreased by 1, because
+ // both are started from zero in TTime::Set()
+ // Formats date e.g. 2008-10-30 --> 2008-09-29
+
+ // Add year and separator e.g. "2008-"
+ modifiedDate.Copy( date->Des().Left(
+ ( KDateYearLength + KSeparatorLength ) ) );
+
+ // Adjust month "10" --> "9"
+ month.Append( date->Des().Mid(
+ ( KDateYearLength + KSeparatorLength ),
+ KMonthAndDayLength) );
+ TLex monthLex( month );
+ TInt monthInt( 0 );
+ monthLex.Val( monthInt );
+ monthInt--;
+ TBuf<KMonthAndDayLength> adjustedMonth;
+ adjustedMonth.Num( monthInt );
+
+ // Month and day values need to contain
+ // two digits. Append extra zero, if needed,
+ // e.g. "9" --> "09"
+ if ( monthInt < KMonthAndDayDigitLimit )
+ {
+ modifiedDate.Append( KZero );
+ }
+
+ // Add modified month string
+ modifiedDate.Append( adjustedMonth );
+
+ // Add separator "-" that is between month and day
+ modifiedDate.Append( date->Des().Mid(
+ KSecondSeparatorPosition,
+ KSeparatorLength ) );
+
+ // Adjust day e.g. "30" --> "29"
+ day.Append( date->Des().Mid(
+ ( KSecondSeparatorPosition + KSeparatorLength ),
+ KMonthAndDayLength) );
+ TLex dayLex( day );
+ TInt dayInt( 0 );
+ dayLex.Val( dayInt );
+ dayInt--;
+ TBuf<KMonthAndDayLength> adjustedDay;
+ adjustedDay.Num( dayInt );
+
+ if ( dayInt < KMonthAndDayDigitLimit )
+ {
+ modifiedDate.Append( KZero );
+ }
+
+ // Add modified day string
+ modifiedDate.Append( adjustedDay );
+ }
+
+ CleanupStack::PopAndDestroy( date );
+
+ HBufC8* adjustedDate =
+ CnvUtfConverter::ConvertFromUnicodeToUtf8L( modifiedDate );
+
+ return adjustedDate;
+ }
+
+// --------------------------------------------------------------------------
+// CUpnpContainerResolver::AddByDateContainersL
+// --------------------------------------------------------------------------
+//
+TInt CUpnpContainerResolver::AddByDateContainersL(
+ RPointerArray<HBufC8>& aContainerNames,
+ const RUPnPElementsArray& aElements )
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::\
+AddByDateContainersL" );
+
+ TInt metadataError( KErrNone );
+ TTime time;
+
+ // Append "By Date" container
+ aContainerNames.AppendL(
+ ReadResourceTextL( R_UPNP_SHARE_BY_DATE_TEXT ) );
+
+ HBufC8* elementValue = GetElementL( aElements, KElementDate );
+ if ( elementValue )
+ {
+ CleanupStack::PushL( elementValue );
+ // Get date element and adjust it to match TTime::Set() time
+ HBufC8* adjustedDate = AdjustDateL( *elementValue );
+ CleanupStack::PopAndDestroy( elementValue );
+ CleanupStack::PushL( adjustedDate );
+
+ if ( adjustedDate->Length() <= 0 )
+ {
+ metadataError = KErrNotFound;
+ }
+
+ // Convert date to TTime
+ TInt adjustError ( UPnPItemUtility::UPnPDateAsTTime(
+ *adjustedDate, time ) );
+
+ CleanupStack::PopAndDestroy( adjustedDate );
+
+ if ( adjustError == KErrNone &&
+ metadataError == KErrNone )
+ {
+ TBuf<KMaxDateStringLength> finalTime;
+
+ // Append Year container
+ time.FormatL( finalTime, KDateTimeYear );
+ aContainerNames.Append(
+ CnvUtfConverter::ConvertFromUnicodeToUtf8L(
+ finalTime ) );
+
+ // Append Month container
+ time.FormatL( finalTime, KDateTimeMonth );
+ aContainerNames.Append(
+ CnvUtfConverter::ConvertFromUnicodeToUtf8L(
+ finalTime ) );
+
+ // Append Day container
+ time.FormatL( finalTime, KDateTimeDay );
+ aContainerNames.Append(
+ CnvUtfConverter::ConvertFromUnicodeToUtf8L(
+ finalTime ) );
+ }
+ }
+ else
+ {
+ metadataError = KErrNotFound;
+ }
+
+ return metadataError;
+ }
+
+// --------------------------------------------------------------------------
+// CUpnpContainerResolver::ModifyAndAppendElementL
+// --------------------------------------------------------------------------
+//
+void CUpnpContainerResolver::ModifyAndAppendElementL(
+ RPointerArray<HBufC8>& aContainerNames,
+ const RUPnPElementsArray& aElements,
+ const TDesC8& aElementType )
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::\
+ModifyAndAppendElementL" );
+
+ // Find correct element
+ HBufC8* elementValue = GetElementL( aElements, aElementType );
+ CleanupStack::PushL( elementValue );
+ if ( !elementValue ||
+ elementValue->Length() <= 0 )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ // Set all letters to lower case
+ elementValue->Des().LowerCase();
+
+ // Capitalize the first letter of the string
+ elementValue->Des().Capitalize();
+
+ // Append modified element value to container names array.
+ // aContainerNames array is responsible for deleteting objects in it.
+ // Transfer ownership.
+ aContainerNames.AppendL( elementValue );
+
+ CleanupStack::Pop( elementValue );
+ }
+
+// --------------------------------------------------------------------------
+// CUpnpContainerResolver::AppendContainerNameToArrayL
+// --------------------------------------------------------------------------
+//
+void CUpnpContainerResolver::AppendContainerNameToArrayL(
+ RPointerArray<HBufC8>& aArray,
+ TInt aResourceTextId )
+ {
+ __LOG( "[CUpnpSharingAlgorithm]\t CUpnpContainerResolver::\
+AppendContainerNameToArrayL" );
+
+ HBufC8* name = ReadResourceTextL( aResourceTextId );
+ CleanupStack::PushL( name );
+ aArray.AppendL( name );
+ CleanupStack::Pop( name );
+ }
+
+// End of file