upnpframework/upnputilities/src/upnppathutility.cpp
branchIOP_Improvements
changeset 40 08b5eae9f9ff
equal deleted inserted replaced
39:6369bfd1b60d 40:08b5eae9f9ff
       
     1 /*
       
     2 * Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 *
       
    15 * Description:  Utility class to get path related info for the media files
       
    16 */
       
    17 
       
    18 // INCLUDE FILES
       
    19 #include <bautils.h>    
       
    20 #include "upnpsettingsengine.h"
       
    21 #include "upnpconstantdefs.h"
       
    22 #include <upnpstring.h>
       
    23 #include <upnpitem.h>
       
    24 #include <upnpdlnaprotocolinfo.h>
       
    25 #include <pathinfo.h>
       
    26 
       
    27 #include "upnppathutility.h"
       
    28 #include "Upnpcommonutils.h"
       
    29 
       
    30 // CONSTANTS
       
    31 _LIT( KYearMonthDayFormat,        "%04d\\%02d\\%02d\\");
       
    32 _LIT( KTitleExtFormat,            "%S%S");
       
    33 _LIT( KArtistFormat,              "%S\\");
       
    34 _LIT( KAlbumFormat,               "%S\\");
       
    35 _LIT( KSlash,                     "\\");
       
    36 _LIT( KSlashData,                 "\\Data\\");
       
    37 _LIT( KUnknown,                   "Unknown");
       
    38 
       
    39 _LIT( KSeparator,                   ":" );
       
    40 _LIT( KNullTime,                    "000000" );
       
    41 
       
    42 const TInt KDateStringLength        = 10;
       
    43 const TInt KDateTimeStringLength    = 19;
       
    44 const TInt KMaxDateStringLength     = 30;
       
    45 
       
    46 // ============================ MEMBER FUNCTIONS ============================
       
    47 
       
    48 // ---------------------------------------------------------------------------
       
    49 // CUPnPPathUtility::CUPnPPathUtility
       
    50 // C++ default constructor can NOT contain any code, that
       
    51 // might leave.
       
    52 // ---------------------------------------------------------------------------
       
    53 //
       
    54 CUPnPPathUtility::CUPnPPathUtility()
       
    55     {
       
    56     }
       
    57 
       
    58 // ---------------------------------------------------------------------------
       
    59 // CUPnPPathUtility::NewL
       
    60 // Two-phased constructor.
       
    61 // ---------------------------------------------------------------------------
       
    62 //
       
    63 EXPORT_C CUPnPPathUtility* CUPnPPathUtility::NewL()
       
    64     {
       
    65     CUPnPPathUtility* self = CUPnPPathUtility::NewLC();
       
    66     CleanupStack::Pop();
       
    67     return self;
       
    68     }
       
    69 
       
    70 // ---------------------------------------------------------------------------
       
    71 // CUPnPPathUtility::NewLC
       
    72 // Two-phased constructor.
       
    73 // ---------------------------------------------------------------------------
       
    74 //
       
    75 EXPORT_C CUPnPPathUtility* CUPnPPathUtility::NewLC()
       
    76     {
       
    77     CUPnPPathUtility* self = new( ELeave ) CUPnPPathUtility;
       
    78     CleanupStack::PushL( self );
       
    79     self->ConstructL();
       
    80     return self;
       
    81     }
       
    82 
       
    83 // ---------------------------------------------------------------------------
       
    84 // CUPnPPathUtility::ConstructL
       
    85 // Symbian 2nd phase constructor can leave.
       
    86 // ---------------------------------------------------------------------------
       
    87 //
       
    88 void CUPnPPathUtility::ConstructL()
       
    89     {
       
    90     iSettingsEngine = CUPnPSettingsEngine::NewL();
       
    91     }
       
    92     
       
    93 // ---------------------------------------------------------------------------
       
    94 // CUPnPPathUtility::~CUPnPPathUtility()
       
    95 // Destructor
       
    96 // ---------------------------------------------------------------------------
       
    97 //
       
    98 EXPORT_C CUPnPPathUtility::~CUPnPPathUtility()
       
    99     {
       
   100     delete iSettingsEngine;
       
   101     }
       
   102 
       
   103 // --------------------------------------------------------------------------
       
   104 // CUPnPPathUtility::GetCopyPathDriveL
       
   105 // Gets the drive for the copy operation
       
   106 // (other items were commented in a header).
       
   107 // --------------------------------------------------------------------------
       
   108 //
       
   109 EXPORT_C void CUPnPPathUtility::GetCopyPathDriveL( 
       
   110              TDriveNumber& aDrive ) const
       
   111     {
       
   112     iSettingsEngine->GetCopyLocationDriveL( aDrive );
       
   113     }
       
   114 
       
   115 // --------------------------------------------------------------------------
       
   116 // CUPnPPathUtility::GetCopyPathL
       
   117 // Returns the path of the upnp item to be copied
       
   118 // (other items were commented in a header).
       
   119 // --------------------------------------------------------------------------
       
   120 //
       
   121 EXPORT_C HBufC* CUPnPPathUtility::GetCopyPathL(
       
   122                const CUpnpItem& aItem,
       
   123                const CUpnpElement& aResource,
       
   124                TBool aAppendTitleAndExt ) const
       
   125     {
       
   126     TDriveNumber drive;
       
   127     iSettingsEngine->GetCopyLocationDriveL( drive );   
       
   128     return GetCreateCopyPathL( aItem, 
       
   129                                aResource, 
       
   130                                aAppendTitleAndExt,
       
   131                                EFalse,
       
   132                                drive );
       
   133     }   
       
   134 
       
   135 // --------------------------------------------------------------------------
       
   136 // CUPnPPathUtility::GetCopyPathL
       
   137 // Returns the path of the upnp item to be copied
       
   138 // (other items were commented in a header).
       
   139 // --------------------------------------------------------------------------
       
   140 //
       
   141 EXPORT_C HBufC* CUPnPPathUtility::GetCopyPathL(
       
   142                const CUpnpItem& aItem,
       
   143                const CUpnpElement& aResource,
       
   144                TBool aAppendTitleAndExt,
       
   145                TDriveNumber aDriveNumber ) const
       
   146     {
       
   147     
       
   148     return GetCreateCopyPathL( aItem, 
       
   149                                aResource, 
       
   150                                aAppendTitleAndExt,
       
   151                                EFalse,
       
   152                                aDriveNumber );
       
   153     }   
       
   154 
       
   155 // --------------------------------------------------------------------------
       
   156 // CUPnPPathUtility::CreateCopyPathL
       
   157 // Returns the path of the upnp item to be copied
       
   158 // Creates the path if necessary and appends the filename and extension if
       
   159 // required
       
   160 // (other items were commented in a header).
       
   161 // --------------------------------------------------------------------------
       
   162 //
       
   163 EXPORT_C HBufC* CUPnPPathUtility::CreateCopyPathL(
       
   164                const CUpnpItem& aItem,
       
   165                const CUpnpElement& aResource,
       
   166                TBool aAppendTitleAndExt ) const
       
   167     {
       
   168     TDriveNumber drive;
       
   169     iSettingsEngine->GetCopyLocationDriveL( drive );
       
   170     return GetCreateCopyPathL( aItem, 
       
   171                                aResource, 
       
   172                                aAppendTitleAndExt,
       
   173                                ETrue,
       
   174                                drive );
       
   175     }
       
   176 
       
   177 // --------------------------------------------------------------------------
       
   178 // CUPnPPathUtility::CreateCopyPathL
       
   179 // Returns the path of the upnp item to be copied
       
   180 // Creates the path if necessary and appends the filename and extension if
       
   181 // required
       
   182 // (other items were commented in a header).
       
   183 // --------------------------------------------------------------------------
       
   184 //
       
   185 EXPORT_C HBufC* CUPnPPathUtility::CreateCopyPathL(
       
   186                const CUpnpItem& aItem,
       
   187                const CUpnpElement& aResource,
       
   188                TBool aAppendTitleAndExt,
       
   189                TDriveNumber aDriveNumber ) const
       
   190     {
       
   191     return GetCreateCopyPathL( aItem, 
       
   192                                aResource, 
       
   193                                aAppendTitleAndExt,
       
   194                                ETrue,
       
   195                                aDriveNumber );
       
   196     }
       
   197 
       
   198 // --------------------------------------------------------------------------
       
   199 // CUPnPPathUtility::RemoveEmptyFoldersFromCopyPathL
       
   200 // Removes empty folders from the copy path 
       
   201 // (other items were commented in a header).
       
   202 // --------------------------------------------------------------------------
       
   203 //
       
   204 EXPORT_C void CUPnPPathUtility::RemoveEmptyFoldersFromCopyPathL(
       
   205                             const TDesC& aCopyPath )
       
   206     {  
       
   207     TPtrC basePath;
       
   208     const TDesC& soundsPath = PathInfo::SoundsPath();
       
   209     const TDesC& videosPath = PathInfo::VideosPath();
       
   210     const TDesC& imagesPath = PathInfo::ImagesPath();
       
   211     const TDesC& othersPath = PathInfo::OthersPath();
       
   212     
       
   213     TInt baseLength = 0;
       
   214     TInt found = KErrNotFound;    
       
   215     if ( KErrNotFound != ( found = aCopyPath.Find( 
       
   216                                      soundsPath ) ) )
       
   217         {
       
   218         baseLength = soundsPath.Length();
       
   219         }
       
   220     else if ( KErrNotFound != ( found = aCopyPath.Find( 
       
   221                                     videosPath ) ) )
       
   222         {
       
   223         baseLength = videosPath.Length();
       
   224         }
       
   225     else if ( KErrNotFound != ( found = aCopyPath.Find( 
       
   226                                     imagesPath ) ) )
       
   227         {
       
   228         baseLength = imagesPath.Length();
       
   229         }
       
   230     else if ( KErrNotFound != ( found = aCopyPath.Find( 
       
   231                                     othersPath ) ) )
       
   232         {
       
   233         baseLength = othersPath.Length();
       
   234         }
       
   235 
       
   236     if ( KErrNotFound != found )
       
   237         {
       
   238         TPtrC basePath = aCopyPath.Left( found + baseLength );
       
   239         TParse parsePath;
       
   240         User::LeaveIfError( parsePath.Set( aCopyPath, NULL, NULL ) );
       
   241         //Remove filename and extension before passing the copy path
       
   242         RemoveEmptyFoldersL( basePath, parsePath.DriveAndPath() );
       
   243         }
       
   244     
       
   245     }
       
   246 
       
   247 // --------------------------------------------------------------------------
       
   248 // CUPnPPathUtility::GetCreateCopyPathL
       
   249 // Returns the path of the upnp item to be copied
       
   250 // Creates the path if necessary and appends the filename and extension if
       
   251 // required
       
   252 // (other items were commented in a header).
       
   253 // --------------------------------------------------------------------------
       
   254 //
       
   255 HBufC* CUPnPPathUtility::GetCreateCopyPathL(
       
   256                const CUpnpItem& aItem,
       
   257                const CUpnpElement& aResource,
       
   258                TBool aAppendTitleAndExt,
       
   259                TBool aCreatePath,
       
   260                TDriveNumber aDriveNumber ) const
       
   261     {
       
   262        
       
   263     HBufC* path = HBufC::NewLC( KMaxPath );
       
   264     TPtr refPath = path->Des();
       
   265     
       
   266     TDriveUnit driveUnit = TDriveUnit( aDriveNumber );
       
   267     AppendDataL( refPath, driveUnit.Name() );
       
   268     if ( EDriveC == driveUnit )
       
   269         {
       
   270         //C:\\Data\\(Images/Videos/Sounds)....
       
   271         AppendDataL( refPath, KSlashData );
       
   272         }
       
   273     else
       
   274         {
       
   275         //\\(Images/Videos/Sounds)....
       
   276         AppendDataL( refPath, KSlash );
       
   277         }
       
   278     
       
   279     // Get the protocolinfo-attribute
       
   280     const CUpnpAttribute* pInfo = FindAttributeByName(
       
   281             aResource, KAttributeProtocolInfo );
       
   282     if ( NULL == pInfo )
       
   283         {
       
   284         User::Leave( KErrArgument );
       
   285         }
       
   286     
       
   287     CUpnpDlnaProtocolInfo* dlnaInfo =
       
   288             CUpnpDlnaProtocolInfo::NewL( pInfo->Value() );
       
   289     CleanupStack::PushL( dlnaInfo );
       
   290     TUPnPItemType fileType = UPnPCommonUtils::FileTypeByMimeTypeL( 
       
   291             dlnaInfo->ThirdField() );
       
   292     
       
   293     switch( fileType )
       
   294         {
       
   295         case ETypeAudio:
       
   296             {
       
   297             AppendDataL( refPath, PathInfo::SoundsPath() );
       
   298             AppendArtistAlbumL( refPath, aItem );
       
   299             break;
       
   300             }
       
   301         case ETypeVideo:
       
   302             {
       
   303             AppendDataL( refPath, PathInfo::VideosPath() );
       
   304             AppendYearMonthDayL( refPath, aItem );
       
   305             break;
       
   306             }
       
   307         case ETypeImage:
       
   308             {
       
   309             AppendDataL( refPath, PathInfo::ImagesPath() );
       
   310             AppendYearMonthDayL( refPath, aItem );
       
   311             break;
       
   312             }
       
   313         case ETypePlaylist:
       
   314         case ETypeOther:
       
   315         default:
       
   316             {
       
   317             AppendDataL( refPath, PathInfo::OthersPath() );
       
   318             }                
       
   319         }
       
   320     if( aCreatePath )
       
   321         {
       
   322         RFs fs;
       
   323         User::LeaveIfError( fs.Connect() );
       
   324         CleanupClosePushL(fs);
       
   325         BaflUtils::EnsurePathExistsL( fs, refPath );
       
   326         CleanupStack::PopAndDestroy(&fs);
       
   327         }
       
   328     if( aAppendTitleAndExt )
       
   329         {
       
   330         AppendTitleAndExtL( refPath, *dlnaInfo, aItem );
       
   331         }
       
   332     
       
   333     CleanupStack::PopAndDestroy( dlnaInfo );
       
   334     CleanupStack::Pop( path );
       
   335     
       
   336     return path;
       
   337     }   
       
   338 
       
   339 // --------------------------------------------------------------------------
       
   340 // CUPnPPathUtility::AppendTitleAndExtL
       
   341 // Appends title and extension to the path.
       
   342 // --------------------------------------------------------------------------
       
   343 //
       
   344 void CUPnPPathUtility::AppendTitleAndExtL( 
       
   345              TDes& aPath, CUpnpDlnaProtocolInfo& aProtocolInfo, 
       
   346              const CUpnpItem& aItem ) const
       
   347     {
       
   348     HBufC* fileExt = UPnPCommonUtils::FileExtensionByMimeTypeL(
       
   349             aProtocolInfo.ThirdField() );
       
   350     
       
   351     User::LeaveIfNull( fileExt );
       
   352     CleanupStack::PushL( fileExt );
       
   353     
       
   354     HBufC* title16 = UpnpString::ToUnicodeL( aItem.Title() );
       
   355     CleanupStack::PushL( title16 );
       
   356     HBufC* title16checked =
       
   357         UPnPCommonUtils::ReplaceIllegalFilenameCharactersL( *title16 );
       
   358     CleanupStack::PopAndDestroy( title16 );
       
   359     
       
   360     CheckBufferSpaceL( aPath, 
       
   361             title16checked->Length()+fileExt->Length() );
       
   362     
       
   363     aPath.AppendFormat( KTitleExtFormat(), title16checked, fileExt );
       
   364     
       
   365     delete title16checked; title16checked = NULL;
       
   366     CleanupStack::PopAndDestroy( fileExt );
       
   367     }
       
   368 
       
   369 // --------------------------------------------------------------------------
       
   370 // CUPnPPathUtility::AppendYearMonthDayL
       
   371 // Appends year, month and day to the path.
       
   372 // --------------------------------------------------------------------------
       
   373 //
       
   374 void CUPnPPathUtility::AppendYearMonthDayL( 
       
   375         TDes& aPath, const CUpnpItem& aItem ) const
       
   376     {  
       
   377     // Get the date-element
       
   378     const CUpnpElement* dateElem = FindElementByName(
       
   379             aItem, KElementDate );
       
   380 
       
   381     TTime date; date.HomeTime();
       
   382     TInt offsetMonthDay = 1;
       
   383     // Use date element time instead of current time,
       
   384     // if element exist
       
   385     if ( dateElem != NULL )
       
   386         {
       
   387         UPnPDateAsTTimeL( dateElem->Value(), date );
       
   388         offsetMonthDay = 0;
       
   389         }
       
   390     TDateTime ymd = date.DateTime();
       
   391     CheckBufferSpaceL( aPath, 11 ); //4(year)+2(month)+2(day)+3(\)
       
   392         
       
   393     aPath.AppendFormat( KYearMonthDayFormat(), 
       
   394             ymd.Year(), 
       
   395             ymd.Month() + offsetMonthDay, 
       
   396             ymd.Day() + offsetMonthDay );
       
   397     
       
   398     }
       
   399 
       
   400 // --------------------------------------------------------------------------
       
   401 // CUPnPPathUtility::AppendArtistAlbumL
       
   402 // Appends artist and album to the path.
       
   403 // --------------------------------------------------------------------------
       
   404 //
       
   405 void CUPnPPathUtility::AppendArtistAlbumL( 
       
   406         TDes& aPath, const CUpnpItem& aItem ) const
       
   407     {
       
   408     
       
   409     // Get the artist-element
       
   410     const CUpnpElement* artistElem = FindElementByName(
       
   411                 aItem, KElementArtist );
       
   412     if ( NULL != artistElem )
       
   413         {
       
   414         HBufC* artist = UpnpString::ToUnicodeL( artistElem->Value() );
       
   415         CleanupStack::PushL( artist );
       
   416         
       
   417         HBufC* artistchecked =
       
   418             UPnPCommonUtils::ReplaceIllegalDirNameCharactersL( *artist );
       
   419         CleanupStack::PopAndDestroy( artist );
       
   420         
       
   421         CheckBufferSpaceL( aPath, artistchecked->Length()+1 );// 1 for '\'          
       
   422         aPath.AppendFormat( KArtistFormat(), artistchecked );
       
   423         
       
   424         delete artistchecked;
       
   425         }
       
   426     else
       
   427         {
       
   428         CheckBufferSpaceL( aPath, KUnknown().Length()+1 );  // 1 for '\'       
       
   429         aPath.AppendFormat( KArtistFormat(), &KUnknown() );
       
   430         }
       
   431     
       
   432     // Get the album-element
       
   433     const CUpnpElement* albumElem = FindElementByName(
       
   434                 aItem, KElementAlbum );
       
   435     if ( NULL != albumElem )
       
   436         {
       
   437         HBufC* album = UpnpString::ToUnicodeL( albumElem->Value() );
       
   438         CleanupStack::PushL( album );
       
   439         
       
   440         HBufC* albumchecked =
       
   441             UPnPCommonUtils::ReplaceIllegalDirNameCharactersL( *album );
       
   442         CleanupStack::PopAndDestroy( album );
       
   443         
       
   444         CheckBufferSpaceL( aPath, albumchecked->Length()+1 );// 1 for '\'
       
   445         aPath.AppendFormat( KAlbumFormat(), albumchecked );
       
   446         
       
   447         delete albumchecked;
       
   448         }
       
   449     else
       
   450         {
       
   451         CheckBufferSpaceL( aPath, KUnknown().Length()+1 );  // 1 for '\'       
       
   452         aPath.AppendFormat( KAlbumFormat(), &KUnknown() );
       
   453         }
       
   454     
       
   455     }
       
   456 
       
   457 // --------------------------------------------------------------------------
       
   458 // CUPnPPathUtility::AppendDataL
       
   459 // Appends data to the path's buffer.
       
   460 // --------------------------------------------------------------------------
       
   461 //
       
   462 void CUPnPPathUtility::AppendDataL( 
       
   463         TDes& aPath, const TDesC& aData ) const
       
   464     {  
       
   465     CheckBufferSpaceL( aPath, aData );
       
   466     aPath.Append( aData );
       
   467     }
       
   468 
       
   469 // --------------------------------------------------------------------------
       
   470 // CUPnPPathUtility::CheckBufferSpaceL
       
   471 // Checks whether the data can be appended to buffer or not.
       
   472 // --------------------------------------------------------------------------
       
   473 //
       
   474 void CUPnPPathUtility::CheckBufferSpaceL( 
       
   475         const TDes& aPath, const TDesC& aData ) const
       
   476     {
       
   477     CheckBufferSpaceL( aPath, aData.Length() );
       
   478     }
       
   479 
       
   480 // --------------------------------------------------------------------------
       
   481 // CUPnPPathUtility::CheckBufferSpaceL
       
   482 // Checks whether the data of the specified length
       
   483 // can be appended to buffer or not.
       
   484 // --------------------------------------------------------------------------
       
   485 //
       
   486 void CUPnPPathUtility::CheckBufferSpaceL( 
       
   487         const TDes& aPath, const TInt& aLength ) const
       
   488     {  
       
   489     if ( (aPath.Length() + aLength) > aPath.MaxLength() )
       
   490         {
       
   491         User::Leave( KErrOverflow );
       
   492         }
       
   493     }
       
   494 
       
   495 // --------------------------------------------------------------------------
       
   496 // CUPnPPathUtility::FindElementByName
       
   497 // Finds an element within an object.
       
   498 //---------------------------------------------------------------------------
       
   499 const CUpnpElement* CUPnPPathUtility::FindElementByName(
       
   500     const CUpnpObject& aObject, const TDesC8& aName ) const
       
   501     {
       
   502     CUpnpElement* element = NULL;
       
   503     const RUPnPElementsArray& array =
       
   504         const_cast<CUpnpObject&>(aObject).GetElements();
       
   505     for( TInt i = 0; i < array.Count(); i++ )
       
   506         {
       
   507         if( array[ i ]->Name() == aName )
       
   508             {
       
   509             element = array[ i ];
       
   510             i = array.Count();
       
   511             }
       
   512         }
       
   513     return element;
       
   514     }
       
   515 
       
   516 // --------------------------------------------------------------------------
       
   517 // CUPnPPathUtility::FindAttributeByName
       
   518 // Finds an attribute within an element.
       
   519 //---------------------------------------------------------------------------
       
   520 const CUpnpAttribute* CUPnPPathUtility::FindAttributeByName(
       
   521     const CUpnpElement& aElement, const TDesC8& aName ) const
       
   522     {
       
   523     CUpnpAttribute* attribute = NULL;
       
   524     const RUPnPAttributesArray& array =
       
   525         const_cast<CUpnpElement&>(aElement).GetAttributes();
       
   526     
       
   527     for( TInt i = 0; i < array.Count(); i++ )
       
   528         {
       
   529         
       
   530         TBufC8<255> buf(array[ i ]->Name());
       
   531         if( array[ i ]->Name() == aName )
       
   532             {
       
   533             attribute = array[ i ];
       
   534             i = array.Count();
       
   535             }
       
   536         }
       
   537     return attribute;
       
   538     }
       
   539 
       
   540 // --------------------------------------------------------------------------
       
   541 // CUPnPPathUtility::UPnPDateAsTTimeL
       
   542 // Converts upnp date to TTime object.
       
   543 //---------------------------------------------------------------------------
       
   544 void CUPnPPathUtility::UPnPDateAsTTimeL( const TDesC8& aUpnpDate,
       
   545     TTime& aTime ) const
       
   546     {
       
   547     // This method is capable of handling the most common dc:date formats:
       
   548     // CCYY-MM-DD and CCYY-MM-DDThh:mm:ss
       
   549     // Rest of the dc:date formats are handled as well, but they might not
       
   550     // be converted precisely
       
   551     
       
   552     TBuf<KMaxDateStringLength> formatDateString;
       
   553     HBufC* dateString = HBufC::NewL( aUpnpDate.Length() );
       
   554     dateString->Des().Copy( aUpnpDate );
       
   555 
       
   556     if( aUpnpDate.Length() >= KDateStringLength )
       
   557         {
       
   558         // CCYY-MM-DD --> CCYYMMDD
       
   559         formatDateString.Copy( dateString->Des().Left( 4 ) ); // Year
       
   560         formatDateString.Append( dateString->Des().Mid( 5,2 ) ); // Month
       
   561         formatDateString.Append( dateString->Des().Mid( 8,2 ) ); // Day        
       
   562 
       
   563         if( aUpnpDate.Length() >= KDateTimeStringLength )
       
   564             {
       
   565             // hh:mm:ss --> hhmmss
       
   566             formatDateString.Append( KSeparator );
       
   567             // Hours
       
   568             formatDateString.Append( dateString->Des().Mid( 11, 2 ) ); 
       
   569             // Minutes
       
   570             formatDateString.Append( dateString->Des().Mid( 14, 2 ) );
       
   571             // Seconds 
       
   572             formatDateString.Append( dateString->Des().Mid( 17, 2 ) ); 
       
   573             }
       
   574         else
       
   575             {
       
   576             // hh:mm:ss --> 000000
       
   577             formatDateString.Append( KSeparator );
       
   578             formatDateString.Append( KNullTime );
       
   579             }
       
   580         }
       
   581     delete dateString;
       
   582     
       
   583     User::LeaveIfError( aTime.Set( formatDateString ) );
       
   584     }
       
   585 
       
   586 // --------------------------------------------------------------------------
       
   587 // CUPnPPathUtility::RemoveEmptyFoldersL
       
   588 // Removes empty folders from the  path 
       
   589 // (other items were commented in a header).
       
   590 // --------------------------------------------------------------------------
       
   591 //
       
   592 void CUPnPPathUtility::RemoveEmptyFoldersL(
       
   593         const TDesC& aBasePath, const TDesC& aFullPath )
       
   594     {
       
   595         
       
   596     RFs fs;
       
   597     User::LeaveIfError( fs.Connect() );
       
   598     CleanupClosePushL(fs);
       
   599     
       
   600     TParse parsePath;
       
   601     User::LeaveIfError( parsePath.Set( aFullPath, NULL, NULL ) );
       
   602     while( 0 != aBasePath.Compare( parsePath.DriveAndPath() ) )
       
   603         {
       
   604         if ( KErrNone != fs.RmDir( parsePath.DriveAndPath() ) ||
       
   605              KErrNone != parsePath.PopDir() )
       
   606             {
       
   607             break;
       
   608             }
       
   609         }
       
   610     CleanupStack::PopAndDestroy(&fs);
       
   611      
       
   612     }
       
   613 
       
   614 //  End of File