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