diff -r 000000000000 -r 72b543305e3a mmsengine/mmsserver/src/mmsmmboxlist.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmsengine/mmsserver/src/mmsmmboxlist.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,911 @@ +/* +* Copyright (c) 2004-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: +* State machine for mmbox list +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include +#include // TTime + +// the rest are local includes +#include "mmsmmboxlist.h" +#include "mmsconst.h" +#include "mmsencode.h" +#include "mmsdecode.h" +#include "mmsheaders.h" +#include "mmsmmboxviewheaders.h" +#include "mmsserverentry.h" +#include "mmssettings.h" +#include "mmssession.h" +#include "mmserrors.h" +#include "MmsServerDebugLogging.h" + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + + +// CONSTANTS +_LIT( K1970, "19700000:000000.000000" ); // 1-Jan 1970 0:00:00 +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// ==================== LOCAL FUNCTIONS ==================== + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CMmsMmboxList::CMmsMmboxList +// +// --------------------------------------------------------- +// +CMmsMmboxList::CMmsMmboxList( RFs& aFs ): + CMmsBaseOperation( aFs ) + { + } + +// --------------------------------------------------------- +// CMmsMmboxList::ConstructL +// +// --------------------------------------------------------- +// +void CMmsMmboxList::ConstructL( CMmsSettings* aMmsSettings ) + { + CMmsBaseOperation::ConstructL( aMmsSettings ); + iMmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() ); + iOldNotifications = new ( ELeave ) CMsvEntrySelection; + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------- +// CMmsMmboxList::NewL +// +// --------------------------------------------------------- +// +CMmsMmboxList* CMmsMmboxList::NewL( RFs& aFs, CMmsSettings* aMmsSettings ) + { + CMmsMmboxList* self = new ( ELeave ) CMmsMmboxList( aFs ); + CleanupStack::PushL( self ); + self->ConstructL( aMmsSettings ); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------- +// CMmsMmboxList::~CMmsMmboxList +// +// --------------------------------------------------------- +// +CMmsMmboxList::~CMmsMmboxList() + { + Cancel(); // has to be called first + delete iOldNotifications; + delete iMmsHeaders; + } + +// --------------------------------------------------------- +// CMmsMmboxList::StartL +// +// --------------------------------------------------------- +// +void CMmsMmboxList::StartL( + CMsvEntrySelection& aSelection, + CMsvServerEntry& aServerEntry, + TMsvId aService, + TRequestStatus& aStatus ) + { + LOG( _L("CMmsMmboxList::StartL") ); + + // Make sure that the aSelection is empty + aSelection.Reset(); + CMmsBaseOperation::InitializeL( aSelection, aServerEntry, aService ); + iMmsHeaders->Reset(); + + iOldNotifications->Reset(); + // get current notifications from mmbox folder + iMmboxFolder = iMmsSettings->MMBoxFolder(); + if ( iError == KErrNone ) + { + iError = iServerEntry->SetEntry( iMmboxFolder ); + } + // If cannot access MMBoxFolder, we are in trouble + // When iError not equal to KErrNone, the operation will complete after running through RunL + if ( iError == KErrNone ) + { + iServerEntry->GetChildrenWithMtm( KUidMsgMMSNotification, *iOldNotifications ); + iOldQuotaEntryId = OldQuotaEntryL(); + } + else + { + iOldQuotaEntryId = KMsvNullIndexEntryId; + } + iServerEntry->SetEntry( KMsvNullIndexEntryId ); + + Queue( aStatus ); + FallThrough(); + } + +// --------------------------------------------------------- +// CMmsMmboxList::DoCancel +// +// --------------------------------------------------------- +// +void CMmsMmboxList::DoCancel() + { + LOG( _L("CMmsMmboxList::DoCancel") ); + CMmsBaseOperation::DoCancel(); + } + +// --------------------------------------------------------- +// CMmsMmboxList::EncodePDUL +// +// --------------------------------------------------------- +// +void CMmsMmboxList::EncodePDUL() + { + LOG( _L("CMmsMmboxList::EncodePDU") ); + + // As no entry exists to be encoded, mmsheaders are not restored and stored. + + // Set message type + iMmsHeaders->SetMessageType( KMmsMessageTypeMboxViewReq ); + + // Request mmbox total and quota information + CMmsMMBoxViewHeaders& viewHeaders = iMmsHeaders->MMBoxViewHeadersL(); + viewHeaders.SetMmsTotals( KMmsYes ); + viewHeaders.SetMmsQuotas( KMmsYes ); + + // Set TransactionId + TBufC8 tid; + tid.Des().NumUC( AllocateTID(), EHex ); + iMmsHeaders->SetTidL( tid ); + + // Encode the mmboxview request + iEncoder->EncodeHeadersL( *iMmsHeaders, *iEncodeBuffer ); + + FallThrough(); + } + +// --------------------------------------------------------- +// CMmsMmboxList::SubmitTransactionL +// +// --------------------------------------------------------- +// +void CMmsMmboxList::SubmitTransactionL() + { + LOG( _L("CMmsMmboxList::SubmitTransaction")); + + if ( !iConnected ) + { + if ( iError == KErrNone ) + { + iError = KErrCouldNotConnect; + } + } + + // This check is needed only when running tests in global mode + // if length of URI is 0, Symbian code will panic + if ( !iUri ) + { + if ( !iMmsSettings->LocalMode() ) + { + iError = KMmsErrorNoURI1; + } + } + else if ( iUri->Des().Length() == 0 && !iMmsSettings->LocalMode() ) + { + iError = KMmsErrorNoURI1; + } + + if ( iError != KErrNone ) + { + FallThrough(); + return; + } + + if ( !iMmsSettings->LocalMode() ) + { + // Send + iMmsSession->SendMessageL( + iUri->Des(), + *iEncodeBuffer, + *iEncoder, + *iDecoder, + iStatus ); + SetActive(); + } + else + { + LocalModeFetchL(); + } + } + +// --------------------------------------------------------- +// CMmsMmboxList::CreateEntryL +// +// --------------------------------------------------------- +// +void CMmsMmboxList::CreateEntryL() + { + LOG( _L("CMmsMmboxList CreateEntry")); + // Create an mms entry under mmbox folder + if ( iOldQuotaEntryId != KMsvNullIndexEntryId ) + { + // Reuse old quota + iEntryUnderConstruction = iOldQuotaEntryId; + } + else + { + // If no old quota entry exists, we create a new one + iError = iServerEntry->SetEntry( iMmboxFolder ); + if ( iError == KErrNone ) + { + // set all relevant flags in tMsvEntry + TMsvEntry tEntry; + tEntry.iMtm = KUidMsgTypeMultimedia; + tEntry.iDate.UniversalTime(); + SetFirstFlagsToNewEntry( tEntry ); + + iError = iServerEntry->CreateEntry( tEntry ); + if ( iError == KErrNone ) + { + iEntryUnderConstruction = tEntry.Id(); + } + } + iServerEntry->SetEntry( KMsvNullIndexEntryId ); + } + FallThrough(); + } + +// --------------------------------------------------------- +// CMmsMmboxList::DecodeResponseL +// +// --------------------------------------------------------- +// +void CMmsMmboxList::DecodeResponseL() + { + LOG( _L("CMmsMmboxList::DecodeResponseL")); + if( iEncodeBuffer->Size() < 1 ) + { + iError = KErrCorrupt; + } + if( iError != KErrNone ) + { + FallThrough(); + return; + } + + iMmsHeaders->Reset(); + // Decode mmbox view confirmation + TInt numAtt = 0; + TInt dataStart = 0; + TInt startInBuffer = 0; + TInt length = iEncodeBuffer->Size(); + iDecoder->DecodeHeadersL( *iEntryWrapper, + *iMmsHeaders, + *iEncodeBuffer, + startInBuffer, + length, + &numAtt, + &dataStart ); + + // The content type have to be mmbox view conf. + if ( iMmsHeaders->MessageType() != KMmsMessageTypeMboxViewConf ) + { + // the content type is not correct. Don't save the headers + if ( iMmsHeaders->MessageType() == KMmsMessageTypeMSendConf && + iMmsHeaders->ResponseStatus() == KMmsErrorUnsupportedMessage ) + { + iError = KErrNotSupported; + } + else + { + iError = KErrCorrupt; + } + } + + if ( iError == KErrNone ) + { + if ( iOldQuotaEntryId != KMsvNullIndexEntryId ) + { + // We must make the entry read only again + iError = iServerEntry->SetEntry( iOldQuotaEntryId ); + if ( iError == KErrNone ) + { + TMsvEntry tEntry = iServerEntry->Entry(); + tEntry.SetReadOnly( EFalse ); + iServerEntry->ChangeEntry( tEntry ); + } + iServerEntry->SetEntry( KMsvNullIndexEntryId ); + } + iError = iEntryWrapper->SetCurrentEntry( iEntryUnderConstruction ); + } + + // save the mmbox view confirmation headers, + // as the decode does not save them + if ( iError == KErrNone ) + { + iError = iEntryWrapper->StoreMmsHeadersL( *iMmsHeaders, NULL ); + } + + // decode rest of the PDUs if we have any. + TInt start = dataStart; // start of multipart data. + for ( TInt i = 0; i < numAtt && iError == KErrNone; i++ ) + { + length = iEncodeBuffer->Size() - start; + // We extract next data part, but we don't use the mime headers that would be returned + iDecoder->ExtractNextDataPartL( *iEncodeBuffer, + start, // start of next data part + dataStart, // start of actual data + length ); // length of data + + // Create a new entry for the mmbox description PDU + iError = iServerEntry->SetEntry( iMmboxFolder ); + TMsvEntry descEntry; + if ( iError == KErrNone ) + { + // set all relevant flags in tMsvEntry + descEntry.iMtm = KUidMsgMMSNotification; + SetFirstFlagsToNewEntry( descEntry ); + iError = iServerEntry->CreateEntry( descEntry ); + } + + if ( iError == KErrNone ) + { + // Decode description PDU + iMmsHeaders->Reset(); + TInt attaNum = 0; + TInt attaDataStart = 0; + iDecoder->DecodeHeadersL( *iEntryWrapper, + *iMmsHeaders, + *iEncodeBuffer, + dataStart, + length, + &attaNum, + &attaDataStart ); + + iError = iEntryWrapper->SetCurrentEntry( descEntry.Id() ); + } + + // Checking the content type + if( iError == KErrNone ) + { + // The content type has to be mmbox view description. + if( iMmsHeaders->MessageType() != KMmsMessageTypeMBoxDescr ) + { + // Content type is not correct. + iError = KErrCorrupt; + LOG( _L("ERROR: Wrong content type")); + } + else + { + // Mark mmbox notification specific flags + // Mark as notification. This information is important for UI. + descEntry.iMtmData1 = KMmsMessageMNotificationInd; + descEntry.iMtmData2 = KMmsStoredInMMBox; + descEntry.iMtmData2 |= KMmsNotifyResponseSent; + } + } + if( iError == KErrNone ) + { + // Set subject etc. to the notification entry + iError = StoreContentToNotificationEntryL( descEntry ); + } + if ( iError == KErrNone ) + { + // Save the headers as the decoder does not save them + iError = iEntryWrapper->StoreMmsHeadersL( *iMmsHeaders, NULL ); + } + if ( iError == KErrNone ) + { + // add new notification to iSelection list + iSelection->AppendL( descEntry.Id() ); + } + } // for loop + + iServerEntry->SetEntry( KMsvNullIndexEntryId ); + FallThrough(); + } + +// --------------------------------------------------------- +// CMmsMmboxList::MoveEntryL +// +// --------------------------------------------------------- +// +void CMmsMmboxList::MoveEntryL() + { + LOG( _L("CMmsMmboxList::MoveEntryL")); + if ( iError != KErrNone ) + { + FallThrough(); + return; + } + + // Delete old notifications + iError = RemoveOldNotifications(); + + // make new notifications visible + if ( iError == KErrNone ) + { + iError = MakeNewNotificationsVisible(); + } + + // Finalize the new quota entry - if we created a new one and did not + // just reuse the old entry + + TMsvEntry tEntry; + + if ( iError == KErrNone || iOldQuotaEntryId == KMsvNullIndexEntryId ) + { + iError = iServerEntry->SetEntry( iEntryUnderConstruction ); + if ( iError == KErrNone ) + { + tEntry = iServerEntry->Entry(); + SetFlagsToEntryBeingFinalized( tEntry ); + // update the time the quota entry was updated + tEntry.iDate.UniversalTime(); + tEntry.iError = KErrNone; // clear possible old error + + // Quota entry must not be visible. + // Otherwise the shows the number of notifications in mmboxfolder wrong. + tEntry.SetVisible( EFalse ); + iError = iServerEntry->ChangeEntry( tEntry ); + if ( iError == KErrNone ) + { + iEntryUnderConstruction = KMsvNullIndexEntryId; + } + } + iServerEntry->SetEntry( KMsvNullIndexEntryId ); + } + + FallThrough(); + } + +// --------------------------------------------------------- +// CMmsMmboxList::FinalizeL() +// +// --------------------------------------------------------- +// +void CMmsMmboxList::FinalizeL() + { + LOG( _L("CMmsMmboxList::FinalizeL")); + + TInt error; + + // In case something has failed. Delete the new quota entry + // - but only in case it was just created + if ( iError != KErrNone ) + { + error = iServerEntry->SetEntry( iMmboxFolder ); + if ( error == KErrNone ) + { + // we can only delete, if we can set context to parent + if ( iOldQuotaEntryId == KMsvNullIndexEntryId ) + { + iServerEntry->DeleteEntry( iEntryUnderConstruction ); + } + + // if iSelection contains now notifications, the notifications + // are not ready yet. They can be destroyed. + if ( iSelection->Count() > 0 ) + { + iServerEntry->DeleteEntries( *iSelection ); + } + } + iEntryUnderConstruction = KMsvNullIndexEntryId; + + iSelection->Reset(); + + // we don't care if the iOldNotifications is empty or not. + // If the old notifications are not deleted, they can stay + // in the mmbox folder. The array is reseted anyway. + iOldNotifications->Reset(); + + // set iError to old quota entry, if the entry exists + if ( iOldQuotaEntryId != KMsvNullIndexEntryId ) + { + + LOG( _L("- old quota entry exists")); + + error = iServerEntry->SetEntry( iOldQuotaEntryId ); + if ( error == KErrNone ) + { + TMsvEntry tEntry = iServerEntry->Entry(); + tEntry.iError = iError; + + error = iServerEntry->ChangeEntry( tEntry ); + if ( error == KErrNone ) + { + LOG( _L("- iError saved to old quota entry.")); + } + } + } + + iServerEntry->SetEntry( KMsvNullIndexEntryId ); + } + + CMmsBaseOperation::FinalizeL(); + } + +// --------------------------------------------------------- +// CMmsMmboxList::SetFirstFlagsToNewEntry +// +// --------------------------------------------------------- +// +void CMmsMmboxList::SetFirstFlagsToNewEntry( TMsvEntry& aEntry ) + { + aEntry.iType = KUidMsvMessageEntry; + aEntry.iServiceId = iService; + aEntry.SetVisible( EFalse ); + aEntry.SetComplete( EFalse ); + aEntry.SetInPreparation( ETrue ); + aEntry.SetReadOnly( EFalse ); + aEntry.SetNew( ETrue ); + aEntry.SetUnread( ETrue ); + } + +// --------------------------------------------------------- +// CMmsMmboxList::SetFlagsToEntryBeingFinalized +// +// --------------------------------------------------------- +// +void CMmsMmboxList::SetFlagsToEntryBeingFinalized( TMsvEntry& aEntry ) + { + aEntry.iMtmData1 |= KMmsMessageMobileTerminated; + aEntry.SetReadOnly( ETrue ); + aEntry.SetVisible( ETrue ); + aEntry.SetInPreparation( EFalse ); + aEntry.SetComplete( ETrue ); + } + +// --------------------------------------------------------- +// CMmsMmboxList::RemoveOldNotifications +// +// --------------------------------------------------------- +// +TInt CMmsMmboxList::RemoveOldNotifications() + { + LOG( _L("CMmsMmboxList::RemoveOldNotifications")); + + TInt error = iServerEntry->SetEntry( iMmboxFolder ); + if ( error == KErrNone && iOldNotifications->Count() > 0 ) + { + error = iServerEntry->DeleteEntries( *iOldNotifications ); + if ( error == KErrNone ) + { + iOldNotifications->Reset(); + } + } + + iServerEntry->SetEntry( KMsvNullIndexEntryId ); + return error; + } + +// --------------------------------------------------------- +// CMmsMmboxList::MakeNewNotificationsVisible +// +// --------------------------------------------------------- +// +TInt CMmsMmboxList::MakeNewNotificationsVisible() + { + LOG( _L("CMmsMmboxList::MakeNewNotificationsVisible")); + TInt count = iSelection->Count(); + TInt error = KErrNone; + for ( TInt i = count - 1; i >=0 && error == KErrNone; i-- ) + { + error = iServerEntry->SetEntry( iSelection->At( i ) ); + if ( error == KErrNone ) + { + TMsvEntry tEntry = iServerEntry->Entry(); + SetFlagsToEntryBeingFinalized( tEntry ); + error = iServerEntry->ChangeEntry( tEntry ); + if ( error == KErrNone ) + { + iSelection->Delete( i ); + } + } + } + iServerEntry->SetEntry( KMsvNullIndexEntryId ); + return error; + } + +// --------------------------------------------------------- +// CMmsMmboxList::StoreContentToNotificationEntryL +// +// --------------------------------------------------------- +// +TInt CMmsMmboxList::StoreContentToNotificationEntryL( TMsvEntry aEntry ) + { + LOG( _L("CMmsMmboxList::SetContentToNotificationL")); + + // Expiry interval must be changed to absolute time, + // otherwise it makes no sense. + if ( iMmsHeaders->ExpiryDate() == 0 ) + { + TTime time; + // handle expiry in universal time + time.UniversalTime(); + time += TTimeIntervalSeconds( iMmsHeaders->ExpiryInterval() ); + iMmsHeaders->SetExpiryDate( + ( time.MicroSecondsFrom( TTime( KMmsYear1970String ) ).Int64() ) / KMmsMillion ); + } + + // If the notifications does not contains the date value from the server, + // arrival time is set to notification. + // Otherwise the date from the server. + + LOG( _L("Mark time")); + + if ( iMmsHeaders->Date() == 0 ) + { + aEntry.iDate.UniversalTime(); + } + else + { + aEntry.iDate = ServerDate(); + } + + // Mark subject + if ( iMmsHeaders->Subject().Length() > 0 ) + { + aEntry.iDescription.Set( iMmsHeaders->Subject() ); + } + + // Mark size of the notification + aEntry.iSize = iMmsHeaders->Size(); + + // Mark message class. + // Default is personal + if ( iMmsHeaders->MessageClass() == EMmsClassAdvertisement ) + { + aEntry.iMtmData1 |= KMmsMessageAdvertisement; + } + else if (iMmsHeaders->MessageClass() == EMmsClassInformational ) + { + aEntry.iMtmData1 |= KMmsMessageInformational; + } + else + { + // keep LINT happy + } + + switch ( iMmsHeaders->MessagePriority() ) + { + case KMmsPriorityNormal: + aEntry.SetPriority( EMsvMediumPriority ); + break; + case KMmsPriorityLow: + aEntry.SetPriority( EMsvLowPriority ); + break; + case KMmsPriorityHigh: + aEntry.SetPriority( EMsvHighPriority ); + break; + default: + // if not defined default is normal + aEntry.SetPriority( EMsvMediumPriority ); + break; + } + + // mark sender + // If the sender is a phone number, add alias. + HBufC* buffer = HBufC::NewL( KMmsMaxDescription ); + TPtr pBuffer = buffer->Des(); + + if ( TMmsGenUtils::GenerateDetails( iMmsHeaders->Sender(), + pBuffer, KMmsMaxDescription, iFs ) == KErrNone ) + { + aEntry.iDetails.Set( pBuffer ); + } + else + { + // We come here only if there was an fatal error in GenerateDetails. + // Even if we don't find the alias, we have something in the string + aEntry.iDetails.Set( iMmsHeaders->Sender() ); + } + + TInt error = iServerEntry->ChangeEntry( aEntry ); + delete buffer; + buffer = NULL; + // iServerEntry is not set to KMsvNullIndexEntryId, + // as the next function demands that the iServerEntry is set to aEntry. + return error; + } + +// --------------------------------------------------------- +// CMmsMmboxList::OldQuotaEntryL +// +// --------------------------------------------------------- +// +TMsvId CMmsMmboxList::OldQuotaEntryL() + { + LOG( _L("CMmsMmboxList::OldQuotaEntryL")); + + // iServerEntry context must be set to iMmboxFolder + // before calling this function + TMsvId oldQuotaEntryId = KMsvNullIndexEntryId; + + // show invisible entries. + TMsvSelectionOrdering ordering = + TMsvSelectionOrdering( KMsvNoGrouping, EMsvSortByNone, ETrue ); + iServerEntry->SetSort( ordering ); + + CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection; + CleanupStack::PushL( selection ); + TInt error = iServerEntry->GetChildrenWithMtm( KUidMsgTypeMultimedia, *selection ); + TInt count = selection->Count(); + + LOG2( _L("- %d mms entries"), count ); + + if( error == KErrNone && count > 0 ) + { + for( TInt i = selection->Count() - 1 ; i >= 0; i-- ) + { + + LOG2( _L("- processing at selection[%d]"), i ); + + TMsvId entryId = selection->At( i ); + error = iServerEntry->SetEntry( entryId ); + if ( error == KErrNone ) + { + TMsvEntry entry = iServerEntry->Entry(); + // old quota entry is complete, but not visible + if ( ( !entry.Visible() ) && entry.Complete() ) + { + oldQuotaEntryId = entryId; + i = -1; + + LOG( _L("- Old quota found")); + + } + } + } + } + CleanupStack::PopAndDestroy( selection ); + + return oldQuotaEntryId; + } + +// --------------------------------------------------------- +// CMmsMmboxList::ServerDate +// +// --------------------------------------------------------- +// +TTime CMmsMmboxList::ServerDate() + { + + LOG( _L("CMmsMmboxList::ServerDate")); + + TInt64 inSeconds = iMmsHeaders->Date(); + + TTime y1970( K1970 ); + + // 1970 presented as microseconds after January 1st, 0 AD nominal Gregorian. + TInt64 ms1970 = y1970.Int64(); + + // If not defined in message headers return 0 + if ( inSeconds == 0 ) + { + return TTime(0); + } + + // microseconds after 1.1. 1970 + TInt64 msAfter1970; + msAfter1970 = KMmsMillion * inSeconds; + + return TTime( ms1970 + msAfter1970 ); + } + +// --------------------------------------------------------- +// +// --------------------------------------------------------- +// +void CMmsMmboxList::LocalModeFetchL() + { +// This functionality has no meaning in hardware +// It is available in WINS to help module testing + +#ifdef __WINS__ + RFs fs; // We need a separate session to be able to set the session path + RFile file; // local mode message + iError = fs.Connect(); + if ( iError != KErrNone ) + { + FallThrough(); + } + + CleanupClosePushL( fs ); + + CDir* fileList = NULL; + + TEntry* entry = new( ELeave ) TEntry; // allocated from heap to save stack space + CleanupStack::PushL( entry ); + HBufC* filename = HBufC::NewL( KMaxFileName ); + CleanupStack::PushL( filename ); + TPtr fileNamePtr = filename->Des(); + // use different directory in order to be able to simulate + // both mmbox view and fetching the corresponding messages + fileNamePtr.Copy( KMmsMMBoxDirectory ); + TInt err = fs.SetSessionPath( fileNamePtr ); + err = fs.Entry( fileNamePtr, *entry ); + TInt count = 0; + if ( err == KErrNone ) + { + TFindFile* finder = new( ELeave ) TFindFile( fs ); // allocated from heap to save stack space + CleanupStack::PushL( finder ); + _LIT( KWild, "*" ); + + err = finder->FindWildByPath( KWild, &fileNamePtr, fileList ); + CleanupStack::PopAndDestroy( finder ); + + if ( fileList ) + { + CleanupStack::PushL( fileList ); + count = fileList->Count(); + } + } + + + if ( count > 0 ) + { + TParse parse; + parse.Set( ( ( *fileList )[0] ).iName, &fileNamePtr, NULL ); + fileNamePtr.Copy( parse.FullName() ); + TInt size = fs.Entry( parse.FullName(), *entry ); + size = entry->iSize; + + iError = file.Open( fs, fileNamePtr, EFileShareExclusive ); + if ( iError == KErrNone ) + { + iEncodeBuffer->Reset(); + TRAP(iError, iEncodeBuffer->ResizeL( size )); + if ( iError == KErrNone ) + { + TPtr8 pos = iEncodeBuffer->Ptr( 0 ); + file.Read( 0, pos, size ); + } + file.Close(); + // delete the file after the view has been fetched + fs.Delete( fileNamePtr ); + } + } + + if ( fileList ) + { + CleanupStack::PopAndDestroy( fileList ); + } + + CleanupStack::PopAndDestroy( filename ); + CleanupStack::PopAndDestroy( entry ); + CleanupStack::PopAndDestroy( &fs ); // close fs +#endif + + FallThrough(); + } + + +// ================= OTHER EXPORTED FUNCTIONS ============== + +// End of File