phonebookui/Phonebook2/Presentation/src/CPbk2AttachmentFile.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2005-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 * Description: 
       
    15 *        Attachment file handler
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDES
       
    21 #include    "CPbk2AttachmentFile.h"
       
    22 
       
    23 // System includes
       
    24 #include    <e32std.h>
       
    25 
       
    26 /// Unnamed namespace for local definitions
       
    27 namespace {
       
    28 
       
    29 // LOCAL CONSTANTS
       
    30 _LIT(KRamDrive, "d:");
       
    31 _LIT(KPersistentDrive, "c:");
       
    32 _LIT(KTempFilePath, "\\system\\temp\\");
       
    33 _LIT(KInvalidFileNameChars, "?*<>/\"|\\:");
       
    34 _LIT(KDefaultTempFileName, "TEMP.tmp");
       
    35 const TInt KMaxDriveNameLength = 2;
       
    36 const TInt KMaxNumberLength = 5;
       
    37 const TInt KMaxFileNumber = 99999;
       
    38 const TInt KFirstDuplicateNameIndex = 1;
       
    39 
       
    40 #ifdef _DEBUG
       
    41 enum TPanicCode
       
    42     {
       
    43     EPanicPostCond_Constructor = 1,
       
    44     EPanicPreCond_ConstructL,
       
    45     EPanicPostCond_ConstructL,
       
    46     EPanicPreCond_CreateFileL,
       
    47     EPanicPostCond_CreateFileL
       
    48     };
       
    49 
       
    50 void Panic(TPanicCode aReason)
       
    51     {
       
    52     _LIT(KPanicText, "CPbk2AttachmentFile");
       
    53     User::Panic(KPanicText,aReason);
       
    54     }
       
    55 
       
    56 #endif // _DEBUG
       
    57 
       
    58 } // namespace
       
    59 
       
    60 
       
    61 // ================= MEMBER FUNCTIONS =======================
       
    62 // --------------------------------------------------------------------------
       
    63 // CPbk2AttachmentFile::NewL
       
    64 // --------------------------------------------------------------------------
       
    65 //
       
    66 EXPORT_C CPbk2AttachmentFile* CPbk2AttachmentFile::NewL(
       
    67         const TDesC& aBaseName, 
       
    68         RFs& aRfs, 
       
    69         TUint aFileMode /*= EFileStream|EFileShareExclusive|EFileWrite*/)
       
    70     {
       
    71     CPbk2AttachmentFile* self = 
       
    72         CPbk2AttachmentFile::NewLC( aBaseName, aRfs, aFileMode );
       
    73     CleanupStack::Pop(self);  // self
       
    74     return self;
       
    75     }
       
    76     
       
    77 // --------------------------------------------------------------------------
       
    78 // CPbk2AttachmentFile::NewLC
       
    79 // --------------------------------------------------------------------------
       
    80 //
       
    81 EXPORT_C CPbk2AttachmentFile* CPbk2AttachmentFile::NewLC(
       
    82         const TDesC& aBaseName, 
       
    83         RFs& aRfs, 
       
    84         TUint aFileMode /*= EFileStream|EFileShareExclusive|EFileWrite*/)
       
    85     {
       
    86     CPbk2AttachmentFile* self = 
       
    87         new(ELeave) CPbk2AttachmentFile( aRfs, aFileMode );
       
    88     CleanupStack::PushL( self );
       
    89     self->ConstructL( aBaseName );
       
    90     return self;
       
    91     }
       
    92     
       
    93 // --------------------------------------------------------------------------
       
    94 // CPbk2AttachmentFile::~CPbk2AttachmentFile
       
    95 // --------------------------------------------------------------------------
       
    96 //
       
    97 CPbk2AttachmentFile::~CPbk2AttachmentFile()
       
    98     {
       
    99     DeleteFile();
       
   100     delete iFileName;
       
   101     delete iBaseName;
       
   102     }
       
   103     
       
   104 // --------------------------------------------------------------------------
       
   105 // CPbk2AttachmentFile::FileName
       
   106 // --------------------------------------------------------------------------
       
   107 //
       
   108 EXPORT_C const TDesC& CPbk2AttachmentFile::FileName() const
       
   109     {
       
   110     if ( iFileName )
       
   111         {
       
   112         return *iFileName;
       
   113         }
       
   114     else
       
   115         {
       
   116         return KNullDesC;
       
   117         }
       
   118     }
       
   119     
       
   120 // --------------------------------------------------------------------------
       
   121 // CPbk2AttachmentFile::File
       
   122 // --------------------------------------------------------------------------
       
   123 //
       
   124 EXPORT_C RFile& CPbk2AttachmentFile::File()
       
   125     {
       
   126     return iFile;
       
   127     }
       
   128     
       
   129 // --------------------------------------------------------------------------
       
   130 // CPbk2AttachmentFile::Release
       
   131 // --------------------------------------------------------------------------
       
   132 //
       
   133 EXPORT_C void CPbk2AttachmentFile::Release()
       
   134     {
       
   135     iFile.Close();
       
   136     iOwnsFile = EFalse;
       
   137     }
       
   138     
       
   139 // --------------------------------------------------------------------------
       
   140 // CPbk2AttachmentFile::SwitchDriveL
       
   141 // --------------------------------------------------------------------------
       
   142 //
       
   143 EXPORT_C void CPbk2AttachmentFile::SwitchDriveL()
       
   144     {
       
   145     TPtrC drive;
       
   146     if ( iFileName )
       
   147         {
       
   148         // File already created successfully: switch the drive
       
   149         TParsePtrC fileNameParser( *iFileName );
       
   150         drive.Set( fileNameParser.Drive()==KRamDrive ? KPersistentDrive : KRamDrive );
       
   151         }
       
   152     else
       
   153         {
       
   154         // Default is RAM drive in ConstructL
       
   155         drive.Set( KPersistentDrive );
       
   156         }
       
   157 
       
   158     // Create new file
       
   159     CreateFileL( drive, KTempFilePath, *iBaseName );
       
   160     }
       
   161     
       
   162 // --------------------------------------------------------------------------
       
   163 // CPbk2AttachmentFile::CPbk2AttachmentFile
       
   164 // --------------------------------------------------------------------------
       
   165 //
       
   166 CPbk2AttachmentFile::CPbk2AttachmentFile(
       
   167         RFs& aRfs, 
       
   168         TUint aFileMode ) :
       
   169     iRfs( aRfs ),
       
   170     iFileMode( aFileMode )
       
   171     {
       
   172     // CBase::operator new will reset members
       
   173     __ASSERT_DEBUG(!iBaseName && !iFileName && iFile.SubSessionHandle()==KNullHandle, 
       
   174         Panic(EPanicPostCond_Constructor) );
       
   175     }
       
   176     
       
   177 // --------------------------------------------------------------------------
       
   178 // CPbk2AttachmentFile::ConstructL
       
   179 // --------------------------------------------------------------------------
       
   180 //
       
   181 void CPbk2AttachmentFile::ConstructL( const TDesC& aBaseName )
       
   182     {
       
   183     __ASSERT_DEBUG(!iBaseName && !iFileName && 
       
   184                     iFile.SubSessionHandle()==KNullHandle, 
       
   185                         Panic(EPanicPreCond_ConstructL));
       
   186 
       
   187     // Call this to ensure that we create session handle that can be passed 
       
   188     // via IPC. We are sharing RFile handles with SendUi.
       
   189     iRfs.ShareProtected();
       
   190     
       
   191     // Clean up aBaseName
       
   192     const TInt maxLength = 
       
   193         KMaxFileName - 
       
   194         KMaxDriveNameLength - 
       
   195         KTempFilePath().Length() - 
       
   196         KMaxNumberLength;
       
   197     iBaseName = HBufC::NewL( maxLength );
       
   198     TPtr baseName = iBaseName->Des();
       
   199     for ( TInt i=0; i < aBaseName.Length() && i < maxLength; ++i )
       
   200         {
       
   201         TChar ch = aBaseName[i];
       
   202         if ( KInvalidFileNameChars().Locate( ch ) == KErrNotFound )
       
   203             {
       
   204             baseName.Append( ch );
       
   205             }
       
   206         }
       
   207     baseName.TrimAll();
       
   208     if ( baseName.Length() == 0 )
       
   209         {
       
   210         baseName = KDefaultTempFileName;
       
   211         }
       
   212 
       
   213     // Try to create the file
       
   214     TRAPD( err, CreateFileL( KRamDrive, KTempFilePath, baseName ) );
       
   215     if ( err != KErrNone )
       
   216         {
       
   217         // Try on different drive
       
   218         SwitchDriveL();
       
   219         }
       
   220 
       
   221     __ASSERT_DEBUG( iBaseName && iFileName, Panic(EPanicPostCond_ConstructL) );
       
   222     }
       
   223     
       
   224 // --------------------------------------------------------------------------
       
   225 // CPbk2AttachmentFile::CreateFileL
       
   226 // --------------------------------------------------------------------------
       
   227 //
       
   228 void CPbk2AttachmentFile::CreateFileL(
       
   229         const TDesC& aDrive, 
       
   230         const TDesC& aDir, 
       
   231         const TDesC& aBaseName )
       
   232     {
       
   233     __ASSERT_DEBUG(iBaseName && iRfs.Handle()!=KNullHandle, 
       
   234         Panic(EPanicPreCond_CreateFileL));
       
   235 
       
   236     // Create and init a local buffer for the file name
       
   237     HBufC* fileNameBuf = HBufC::NewLC( KMaxFileName );
       
   238     TPtr fileName = fileNameBuf->Des();
       
   239     fileName = aDrive;
       
   240     fileName.Append( aDir );
       
   241     // Create directory
       
   242     TInt error = iRfs.MkDirAll( fileName );
       
   243     if ( error != KErrAlreadyExists )
       
   244         {
       
   245         User::LeaveIfError( error );
       
   246         }
       
   247     fileName.Append( aBaseName );
       
   248 
       
   249     TInt number = KFirstDuplicateNameIndex;
       
   250     FOREVER
       
   251         {
       
   252         RFile file;
       
   253         const TInt error = file.Create( iRfs, fileName, iFileMode );
       
   254         if ( error == KErrNone )
       
   255             {
       
   256             // File created succesfully: switch state
       
   257             DeleteFile();  // Delete previous file
       
   258             iFile = file;
       
   259             delete iFileName;
       
   260             iFileName = fileNameBuf;
       
   261             iOwnsFile = ETrue;
       
   262             CleanupStack::Pop();  // fileNameBuf
       
   263             __ASSERT_DEBUG(iFileName && iFile.SubSessionHandle()!=KNullHandle, 
       
   264                 Panic(EPanicPostCond_CreateFileL));
       
   265             return;
       
   266             }
       
   267         else if ( error != KErrAlreadyExists )
       
   268             {
       
   269             User::Leave( error );
       
   270             }
       
   271 
       
   272         // File name was reserved: append number to basename to make it unique
       
   273         fileName = aDrive;
       
   274         fileName.Append( aDir );
       
   275         TParsePtrC baseNameParser( aBaseName );
       
   276         fileName.Append( baseNameParser.Name() );
       
   277         fileName.AppendNum( number );
       
   278         fileName.Append( baseNameParser.Ext() );
       
   279         if ( ++number > KMaxFileNumber )
       
   280             {
       
   281             User::Leave( KErrTooBig );
       
   282             }
       
   283         }
       
   284     }
       
   285     
       
   286 // --------------------------------------------------------------------------
       
   287 // CPbk2AttachmentFile::DeleteFile
       
   288 // --------------------------------------------------------------------------
       
   289 //
       
   290 void CPbk2AttachmentFile::DeleteFile()
       
   291     {
       
   292     iFile.Close();
       
   293     if ( iFileName && iOwnsFile )
       
   294         {
       
   295         // Delete the file. If the deletion fails for some reason trust that the
       
   296         // system will delete the file when it cleans up temp file directories.
       
   297         iRfs.Delete( *iFileName );
       
   298         }
       
   299     }
       
   300     
       
   301 // --------------------------------------------------------------------------
       
   302 // CPbk2AttachmentFileArray::CPbk2AttachmentFileArray
       
   303 // --------------------------------------------------------------------------
       
   304 //
       
   305 EXPORT_C CPbk2AttachmentFileArray::CPbk2AttachmentFileArray( TInt aGranularity )
       
   306     : CArrayPtrFlat<CPbk2AttachmentFile>( aGranularity )
       
   307     {
       
   308     }
       
   309     
       
   310 // --------------------------------------------------------------------------
       
   311 // CPbk2AttachmentFileArray::~CPbk2AttachmentFileArray
       
   312 // --------------------------------------------------------------------------
       
   313 //
       
   314 CPbk2AttachmentFileArray::~CPbk2AttachmentFileArray()
       
   315     {
       
   316     // Delete all objects in the array
       
   317     ResetAndDestroy();
       
   318     }
       
   319     
       
   320 // --------------------------------------------------------------------------
       
   321 // CPbk2AttachmentFileArray::MdcaCount
       
   322 // --------------------------------------------------------------------------
       
   323 //
       
   324 TInt CPbk2AttachmentFileArray::MdcaCount() const
       
   325     {
       
   326     return Count();
       
   327     }
       
   328     
       
   329 // --------------------------------------------------------------------------
       
   330 // CPbk2AttachmentFileArray::MdcaPoint
       
   331 // --------------------------------------------------------------------------
       
   332 //
       
   333 TPtrC CPbk2AttachmentFileArray::MdcaPoint( TInt aIndex ) const
       
   334     {
       
   335     return At( aIndex )->FileName();
       
   336     }
       
   337 
       
   338 // --------------------------------------------------------------------------
       
   339 // CPbk2AttachmentFileArray::FileHandleAt
       
   340 // --------------------------------------------------------------------------
       
   341 //    
       
   342 RFile& CPbk2AttachmentFileArray::FileHandleAt( TInt aIndex )
       
   343     {
       
   344     return At( aIndex )->File();
       
   345     }
       
   346 
       
   347 // End of File