diff -r 5b6f26637ad3 -r f4a778e096c2 phonebookui/Phonebook2/Presentation/src/CPbk2AttachmentFile.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook2/Presentation/src/CPbk2AttachmentFile.cpp Wed Sep 01 12:29:52 2010 +0100 @@ -0,0 +1,347 @@ +/* +* Copyright (c) 2005-2007 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: +* Attachment file handler +* +*/ + + +// INCLUDES +#include "CPbk2AttachmentFile.h" + +// System includes +#include + +/// Unnamed namespace for local definitions +namespace { + +// LOCAL CONSTANTS +_LIT(KRamDrive, "d:"); +_LIT(KPersistentDrive, "c:"); +_LIT(KTempFilePath, "\\system\\temp\\"); +_LIT(KInvalidFileNameChars, "?*<>/\"|\\:"); +_LIT(KDefaultTempFileName, "TEMP.tmp"); +const TInt KMaxDriveNameLength = 2; +const TInt KMaxNumberLength = 5; +const TInt KMaxFileNumber = 99999; +const TInt KFirstDuplicateNameIndex = 1; + +#ifdef _DEBUG +enum TPanicCode + { + EPanicPostCond_Constructor = 1, + EPanicPreCond_ConstructL, + EPanicPostCond_ConstructL, + EPanicPreCond_CreateFileL, + EPanicPostCond_CreateFileL + }; + +void Panic(TPanicCode aReason) + { + _LIT(KPanicText, "CPbk2AttachmentFile"); + User::Panic(KPanicText,aReason); + } + +#endif // _DEBUG + +} // namespace + + +// ================= MEMBER FUNCTIONS ======================= +// -------------------------------------------------------------------------- +// CPbk2AttachmentFile::NewL +// -------------------------------------------------------------------------- +// +EXPORT_C CPbk2AttachmentFile* CPbk2AttachmentFile::NewL( + const TDesC& aBaseName, + RFs& aRfs, + TUint aFileMode /*= EFileStream|EFileShareExclusive|EFileWrite*/) + { + CPbk2AttachmentFile* self = + CPbk2AttachmentFile::NewLC( aBaseName, aRfs, aFileMode ); + CleanupStack::Pop(self); // self + return self; + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFile::NewLC +// -------------------------------------------------------------------------- +// +EXPORT_C CPbk2AttachmentFile* CPbk2AttachmentFile::NewLC( + const TDesC& aBaseName, + RFs& aRfs, + TUint aFileMode /*= EFileStream|EFileShareExclusive|EFileWrite*/) + { + CPbk2AttachmentFile* self = + new(ELeave) CPbk2AttachmentFile( aRfs, aFileMode ); + CleanupStack::PushL( self ); + self->ConstructL( aBaseName ); + return self; + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFile::~CPbk2AttachmentFile +// -------------------------------------------------------------------------- +// +CPbk2AttachmentFile::~CPbk2AttachmentFile() + { + DeleteFile(); + delete iFileName; + delete iBaseName; + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFile::FileName +// -------------------------------------------------------------------------- +// +EXPORT_C const TDesC& CPbk2AttachmentFile::FileName() const + { + if ( iFileName ) + { + return *iFileName; + } + else + { + return KNullDesC; + } + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFile::File +// -------------------------------------------------------------------------- +// +EXPORT_C RFile& CPbk2AttachmentFile::File() + { + return iFile; + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFile::Release +// -------------------------------------------------------------------------- +// +EXPORT_C void CPbk2AttachmentFile::Release() + { + iFile.Close(); + iOwnsFile = EFalse; + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFile::SwitchDriveL +// -------------------------------------------------------------------------- +// +EXPORT_C void CPbk2AttachmentFile::SwitchDriveL() + { + TPtrC drive; + if ( iFileName ) + { + // File already created successfully: switch the drive + TParsePtrC fileNameParser( *iFileName ); + drive.Set( fileNameParser.Drive()==KRamDrive ? KPersistentDrive : KRamDrive ); + } + else + { + // Default is RAM drive in ConstructL + drive.Set( KPersistentDrive ); + } + + // Create new file + CreateFileL( drive, KTempFilePath, *iBaseName ); + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFile::CPbk2AttachmentFile +// -------------------------------------------------------------------------- +// +CPbk2AttachmentFile::CPbk2AttachmentFile( + RFs& aRfs, + TUint aFileMode ) : + iRfs( aRfs ), + iFileMode( aFileMode ) + { + // CBase::operator new will reset members + __ASSERT_DEBUG(!iBaseName && !iFileName && iFile.SubSessionHandle()==KNullHandle, + Panic(EPanicPostCond_Constructor) ); + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFile::ConstructL +// -------------------------------------------------------------------------- +// +void CPbk2AttachmentFile::ConstructL( const TDesC& aBaseName ) + { + __ASSERT_DEBUG(!iBaseName && !iFileName && + iFile.SubSessionHandle()==KNullHandle, + Panic(EPanicPreCond_ConstructL)); + + // Call this to ensure that we create session handle that can be passed + // via IPC. We are sharing RFile handles with SendUi. + iRfs.ShareProtected(); + + // Clean up aBaseName + const TInt maxLength = + KMaxFileName - + KMaxDriveNameLength - + KTempFilePath().Length() - + KMaxNumberLength; + iBaseName = HBufC::NewL( maxLength ); + TPtr baseName = iBaseName->Des(); + for ( TInt i=0; i < aBaseName.Length() && i < maxLength; ++i ) + { + TChar ch = aBaseName[i]; + if ( KInvalidFileNameChars().Locate( ch ) == KErrNotFound ) + { + baseName.Append( ch ); + } + } + baseName.TrimAll(); + if ( baseName.Length() == 0 ) + { + baseName = KDefaultTempFileName; + } + + // Try to create the file + TRAPD( err, CreateFileL( KRamDrive, KTempFilePath, baseName ) ); + if ( err != KErrNone ) + { + // Try on different drive + SwitchDriveL(); + } + + __ASSERT_DEBUG( iBaseName && iFileName, Panic(EPanicPostCond_ConstructL) ); + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFile::CreateFileL +// -------------------------------------------------------------------------- +// +void CPbk2AttachmentFile::CreateFileL( + const TDesC& aDrive, + const TDesC& aDir, + const TDesC& aBaseName ) + { + __ASSERT_DEBUG(iBaseName && iRfs.Handle()!=KNullHandle, + Panic(EPanicPreCond_CreateFileL)); + + // Create and init a local buffer for the file name + HBufC* fileNameBuf = HBufC::NewLC( KMaxFileName ); + TPtr fileName = fileNameBuf->Des(); + fileName = aDrive; + fileName.Append( aDir ); + // Create directory + TInt error = iRfs.MkDirAll( fileName ); + if ( error != KErrAlreadyExists ) + { + User::LeaveIfError( error ); + } + fileName.Append( aBaseName ); + + TInt number = KFirstDuplicateNameIndex; + FOREVER + { + RFile file; + const TInt error = file.Create( iRfs, fileName, iFileMode ); + if ( error == KErrNone ) + { + // File created succesfully: switch state + DeleteFile(); // Delete previous file + iFile = file; + delete iFileName; + iFileName = fileNameBuf; + iOwnsFile = ETrue; + CleanupStack::Pop(); // fileNameBuf + __ASSERT_DEBUG(iFileName && iFile.SubSessionHandle()!=KNullHandle, + Panic(EPanicPostCond_CreateFileL)); + return; + } + else if ( error != KErrAlreadyExists ) + { + User::Leave( error ); + } + + // File name was reserved: append number to basename to make it unique + fileName = aDrive; + fileName.Append( aDir ); + TParsePtrC baseNameParser( aBaseName ); + fileName.Append( baseNameParser.Name() ); + fileName.AppendNum( number ); + fileName.Append( baseNameParser.Ext() ); + if ( ++number > KMaxFileNumber ) + { + User::Leave( KErrTooBig ); + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFile::DeleteFile +// -------------------------------------------------------------------------- +// +void CPbk2AttachmentFile::DeleteFile() + { + iFile.Close(); + if ( iFileName && iOwnsFile ) + { + // Delete the file. If the deletion fails for some reason trust that the + // system will delete the file when it cleans up temp file directories. + iRfs.Delete( *iFileName ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFileArray::CPbk2AttachmentFileArray +// -------------------------------------------------------------------------- +// +EXPORT_C CPbk2AttachmentFileArray::CPbk2AttachmentFileArray( TInt aGranularity ) + : CArrayPtrFlat( aGranularity ) + { + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFileArray::~CPbk2AttachmentFileArray +// -------------------------------------------------------------------------- +// +CPbk2AttachmentFileArray::~CPbk2AttachmentFileArray() + { + // Delete all objects in the array + ResetAndDestroy(); + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFileArray::MdcaCount +// -------------------------------------------------------------------------- +// +TInt CPbk2AttachmentFileArray::MdcaCount() const + { + return Count(); + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFileArray::MdcaPoint +// -------------------------------------------------------------------------- +// +TPtrC CPbk2AttachmentFileArray::MdcaPoint( TInt aIndex ) const + { + return At( aIndex )->FileName(); + } + +// -------------------------------------------------------------------------- +// CPbk2AttachmentFileArray::FileHandleAt +// -------------------------------------------------------------------------- +// +RFile& CPbk2AttachmentFileArray::FileHandleAt( TInt aIndex ) + { + return At( aIndex )->File(); + } + +// End of File