os/mm/mmlibs/mmfw/src/Plugin/StdSourceAndSink/Mmffile.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <f32file.h>
sl@0
    17
#include <e32std.h>
sl@0
    18
#include <mmf/server/mmfdatabuffer.h>
sl@0
    19
#include <mmf/common/mmfutilities.h>
sl@0
    20
#include <mmf/common/mmfcontroller.h>
sl@0
    21
#include <mmf/common/mmfpaniccodes.h>
sl@0
    22
#include <mmf/server/mmffile.h>
sl@0
    23
#include "MmffilePriv.h"
sl@0
    24
#include "FileAccess.h"
sl@0
    25
sl@0
    26
void Panic(TMMFFilePanicCode aPanicCode)
sl@0
    27
	{
sl@0
    28
	_LIT(KMMFFilePanicCategory, "MMFFile");
sl@0
    29
	User::Panic(KMMFFilePanicCategory, aPanicCode);
sl@0
    30
	}
sl@0
    31
sl@0
    32
/**
sl@0
    33
 * Constructs a CTransferBufferCopy
sl@0
    34
 *
sl@0
    35
 * @return CTransferBufferCopy*
sl@0
    36
 */
sl@0
    37
CTransferBufferCopy* CTransferBufferCopy::NewL(TInt aMaxLength)
sl@0
    38
	{
sl@0
    39
	CTransferBufferCopy* self = new (ELeave) CTransferBufferCopy(aMaxLength);
sl@0
    40
	CleanupStack::PushL(self);
sl@0
    41
	self->ConstructL();
sl@0
    42
	CleanupStack::Pop(self);
sl@0
    43
	return self;
sl@0
    44
	}
sl@0
    45
sl@0
    46
/**
sl@0
    47
 * Second phase constructor for CTransferBufferCopy
sl@0
    48
 *
sl@0
    49
 * @return void
sl@0
    50
 */
sl@0
    51
void CTransferBufferCopy::ConstructL()
sl@0
    52
	{
sl@0
    53
	iBuffer = static_cast<TUint8*>(User::AllocL(iMaxLength));
sl@0
    54
	iBufferDes.Set(iBuffer,0,iMaxLength);
sl@0
    55
	}
sl@0
    56
sl@0
    57
/**
sl@0
    58
Destructor.
sl@0
    59
*/
sl@0
    60
CMMFFile::~CMMFFile() 
sl@0
    61
	{
sl@0
    62
	delete iFile;
sl@0
    63
	
sl@0
    64
	
sl@0
    65
	iHandle.Close();
sl@0
    66
	iFsSession.Close();
sl@0
    67
	delete iFileName;
sl@0
    68
	delete iFileExt;
sl@0
    69
	delete iFilePath;
sl@0
    70
	delete iFileDrive;
sl@0
    71
	delete iMmfFileEventHandler;
sl@0
    72
	delete iCAFParameters;
sl@0
    73
sl@0
    74
	// Get rid of everything in RArray's & close them.
sl@0
    75
	iRequests.ResetAndDestroy();
sl@0
    76
	iTransferBufferCopies.ResetAndDestroy();
sl@0
    77
	}
sl@0
    78
sl@0
    79
/**
sl@0
    80
Protected constructor.
sl@0
    81
sl@0
    82
The default implementation is empty.
sl@0
    83
*/
sl@0
    84
CMMFFile::CMMFFile() : CMMFClip( KUidMmfFileSource, KUidMmfFileSink ), iFileSize(-1)
sl@0
    85
	{
sl@0
    86
	iSinkNotStopped = EFalse;
sl@0
    87
	}
sl@0
    88
sl@0
    89
/**
sl@0
    90
Constructs an CMMFFile MDataSource.
sl@0
    91
sl@0
    92
@return A pointer to the new CMMFFile data source.
sl@0
    93
*/
sl@0
    94
MDataSource* CMMFFile::NewSourceL() 
sl@0
    95
	{
sl@0
    96
	CMMFFile* self = new (ELeave) CMMFFile ;
sl@0
    97
	return STATIC_CAST( MDataSource*, self ) ;
sl@0
    98
	}
sl@0
    99
sl@0
   100
/**
sl@0
   101
Constructs a CMMFFile MDataSink
sl@0
   102
sl@0
   103
@return A pointer to the new CMMFFile data sink.
sl@0
   104
*/
sl@0
   105
MDataSink* CMMFFile::NewSinkL()
sl@0
   106
	{
sl@0
   107
	CMMFFile* self = new (ELeave) CMMFFile ;
sl@0
   108
	return STATIC_CAST( MDataSink*, self ) ;
sl@0
   109
	}
sl@0
   110
sl@0
   111
/**
sl@0
   112
Perform source construction dependant on the source construction
sl@0
   113
initialisation data aInitData.
sl@0
   114
sl@0
   115
@param  aInitData
sl@0
   116
        The TPckg<TMMFFileParams> descriptor package containing the file name and full path.
sl@0
   117
*/
sl@0
   118
void CMMFFile::ConstructSourceL(const TDesC8& aInitData ) 
sl@0
   119
	{
sl@0
   120
	ConstructL(aInitData, ESourceMode);
sl@0
   121
	}
sl@0
   122
	
sl@0
   123
/**
sl@0
   124
Performs sink construction dependant on the sink construction
sl@0
   125
initialisation data aInitData.
sl@0
   126
sl@0
   127
@param  aInitData
sl@0
   128
        The TPckg<TMMFFileParams> descriptor package containing the file name and full path.
sl@0
   129
*/
sl@0
   130
void CMMFFile::ConstructSinkL(const TDesC8& aInitData)
sl@0
   131
	{
sl@0
   132
	ConstructL(aInitData, ESinkMode);
sl@0
   133
	}
sl@0
   134
sl@0
   135
/**
sl@0
   136
Protected constructor.
sl@0
   137
sl@0
   138
Extracts the initialisation data provided by the calling functions: ConstructSourceL() and 
sl@0
   139
ConstructSinkL(). Creates a file server session and sets up file name. If there is a file name and 
sl@0
   140
it cannot be found this function leaves. If there is no file name the function leaves. Does not 
sl@0
   141
attempt to open the file or check whether the file exists.
sl@0
   142
sl@0
   143
If aInitData contains a TMMFFileHandleParams instead of TMMFFileParams, the source/sink is constructed from 
sl@0
   144
the file handle provided by the caller
sl@0
   145
sl@0
   146
@param  aInitData
sl@0
   147
        Initialisation data packaged in a TMMFFileParams or in a TMMFFileHandleParams (File Handle)
sl@0
   148
*/
sl@0
   149
void CMMFFile::ConstructL(const TDesC8& aInitData,TMMFileMode aFileMode)
sl@0
   150
	{
sl@0
   151
	User::LeaveIfError(iFsSession.Connect());
sl@0
   152
#ifdef __IPC_V2_PRESENT__
sl@0
   153
	// on IPCv2 we auto attach
sl@0
   154
	User::LeaveIfError(iFsSession.ShareAuto());
sl@0
   155
#else
sl@0
   156
	// on IPCv1 we use explicit - more efficient
sl@0
   157
	User::LeaveIfError(iFsSession.Share(RSessionBase::EExplicitAttach));
sl@0
   158
#endif
sl@0
   159
sl@0
   160
	User::LeaveIfError(iFsSession.ShareProtected());
sl@0
   161
	
sl@0
   162
	HBufC* filename = NULL; 
sl@0
   163
	
sl@0
   164
	iCAFParameters = new (ELeave) CCAFParameters;
sl@0
   165
	TBool drmContent = EFalse;
sl@0
   166
	RDesReadStream stream(aInitData);
sl@0
   167
	CleanupClosePushL(stream);
sl@0
   168
	
sl@0
   169
	TUid initUid = TUid::Uid(stream.ReadInt32L());
sl@0
   170
sl@0
   171
	if (initUid == KMMFileHandleSourceUid)
sl@0
   172
		{
sl@0
   173
		TPckgBuf<RFile*> fileptr;
sl@0
   174
		stream.ReadL(fileptr);
sl@0
   175
		
sl@0
   176
		iHandle.Duplicate(*fileptr());
sl@0
   177
sl@0
   178
		TInt length = stream.ReadInt32L();
sl@0
   179
		if (length>0)
sl@0
   180
			{
sl@0
   181
			iCAFParameters->iUniqueId = HBufC::NewL(length);
sl@0
   182
			TPtr16 ptr = iCAFParameters->iUniqueId->Des();
sl@0
   183
			stream.ReadL(ptr, length);
sl@0
   184
			}
sl@0
   185
		iFileHandle = ETrue;
sl@0
   186
sl@0
   187
		filename = HBufC::NewMaxLC(KMaxFileName);
sl@0
   188
		TPtr ptr = filename->Des();
sl@0
   189
		User::LeaveIfError(iHandle.FullName(ptr));
sl@0
   190
		drmContent = ETrue;
sl@0
   191
		
sl@0
   192
		iCAFParameters->iEnableUI = stream.ReadInt32L();
sl@0
   193
		}
sl@0
   194
		
sl@0
   195
	else if (initUid == KMMFileSourceUid)
sl@0
   196
		{
sl@0
   197
		TInt length = stream.ReadInt32L();
sl@0
   198
		filename = HBufC::NewMaxLC(length);
sl@0
   199
		TPtr ptr = filename->Des();
sl@0
   200
		stream.ReadL(ptr, length);
sl@0
   201
sl@0
   202
		length = stream.ReadInt32L();
sl@0
   203
		if (length>0)
sl@0
   204
			{
sl@0
   205
			iCAFParameters->iUniqueId = HBufC::NewMaxL(length);
sl@0
   206
			ptr.Set(iCAFParameters->iUniqueId->Des());
sl@0
   207
			stream.ReadL(ptr, length);
sl@0
   208
			}
sl@0
   209
		drmContent = ETrue;
sl@0
   210
		iCAFParameters->iEnableUI = stream.ReadInt32L();
sl@0
   211
		}
sl@0
   212
	else
sl@0
   213
		{
sl@0
   214
//		XXX If the UID is unknown we should reject, but  currently
sl@0
   215
//		code also used for older calls that just supply filename.
sl@0
   216
//		User::Leave(KErrNotSupported);
sl@0
   217
		}
sl@0
   218
	
sl@0
   219
	if ((filename == NULL) && aInitData.Length() == sizeof(TMMFFileHandleParams))
sl@0
   220
		{
sl@0
   221
		TMMFFileHandleParams params;
sl@0
   222
		TPckgC<TMMFFileHandleParams> config(params);
sl@0
   223
		config.Set(aInitData);
sl@0
   224
		params = config();
sl@0
   225
sl@0
   226
		
sl@0
   227
		if (params.iUid == KFileHandleUid)
sl@0
   228
			{
sl@0
   229
			User::LeaveIfError(iHandle.Duplicate(*params.iFile));
sl@0
   230
			TInt pos = 0;
sl@0
   231
			// make sure the duplicate handle is at the start of the file - the usage of the file handle really requires this
sl@0
   232
			User::LeaveIfError(iHandle.Seek(ESeekStart, pos));
sl@0
   233
			iFileHandle = ETrue;
sl@0
   234
			ASSERT(filename == NULL);
sl@0
   235
			filename = HBufC::NewMaxLC(KMaxFileName);
sl@0
   236
			TPtr ptr = filename->Des();
sl@0
   237
			User::LeaveIfError(iHandle.FullName(ptr));
sl@0
   238
			}
sl@0
   239
		}
sl@0
   240
sl@0
   241
	if (filename == NULL) // do old case as last resort
sl@0
   242
		{
sl@0
   243
		TMMFFileParams params;
sl@0
   244
		TPckgC<TMMFFileParams> config(params);
sl@0
   245
		config.Set(aInitData);
sl@0
   246
		params = config();
sl@0
   247
		
sl@0
   248
		filename = params.iPath.AllocLC();
sl@0
   249
		}
sl@0
   250
	
sl@0
   251
	ASSERT(filename != NULL);
sl@0
   252
	
sl@0
   253
	TParse parser ;
sl@0
   254
	User::LeaveIfError(parser.Set(*filename, NULL, NULL));
sl@0
   255
	CleanupStack::PopAndDestroy(2, &stream); //filename, stream
sl@0
   256
	if ( !( parser.NamePresent() ) && !( parser.ExtPresent() ) )
sl@0
   257
		{
sl@0
   258
		User::Leave( KErrBadName ) ;
sl@0
   259
		}
sl@0
   260
	
sl@0
   261
	iFullFileName.Copy( parser.FullName() ) ;	
sl@0
   262
	iFileName = parser.Name().AllocL() ;
sl@0
   263
	iFileExt = parser.Ext().AllocL() ;
sl@0
   264
	iFilePath = parser.Path().AllocL() ;
sl@0
   265
	iFileDrive = parser.Drive().AllocL() ;
sl@0
   266
	
sl@0
   267
	// in order to simulate old behaviour we are not passing error out
sl@0
   268
	// but will try to create Content again during PrimeL()
sl@0
   269
	if (drmContent && aFileMode==ESourceMode)
sl@0
   270
		{
sl@0
   271
		TInt contentError;
sl@0
   272
		if (iFileHandle)
sl@0
   273
			{
sl@0
   274
			TRAP(contentError, 
sl@0
   275
				iFile = CContentFile::NewL(iHandle, UniqueId(), iCAFParameters->iEnableUI);
sl@0
   276
				);
sl@0
   277
			}
sl@0
   278
		else
sl@0
   279
			{
sl@0
   280
			// Open for read-only access
sl@0
   281
			TRAP(contentError,
sl@0
   282
				iFile = CContentFile::NewL(iFsSession, iFullFileName, UniqueId(), EFileShareReadersOnly, iCAFParameters->iEnableUI);
sl@0
   283
			);
sl@0
   284
			}
sl@0
   285
		}
sl@0
   286
	}
sl@0
   287
	
sl@0
   288
sl@0
   289
/**
sl@0
   290
@deprecated - Replaced by CMMFFile::Data()
sl@0
   291
sl@0
   292
Returns an RFile handle to the current file.
sl@0
   293
sl@0
   294
If there is no current file, one is created. If the file exists then it is opened with read access 
sl@0
   295
if it is read only, write access otherwise. If the file does not exist then it is opened with
sl@0
   296
write access.
sl@0
   297
sl@0
   298
@leave KErrNotReady
sl@0
   299
       The file is not open.
sl@0
   300
sl@0
   301
@return A handle to the current file.
sl@0
   302
@see CMMFFile::Data()
sl@0
   303
*/
sl@0
   304
RFile& CMMFFile::FileL()
sl@0
   305
	{
sl@0
   306
	if (!iFile)
sl@0
   307
		User::Leave(KErrNotReady);
sl@0
   308
	if (iFileHandle)
sl@0
   309
		return iHandle;
sl@0
   310
	else
sl@0
   311
		return iFile->FileL();
sl@0
   312
	}
sl@0
   313
sl@0
   314
/** 
sl@0
   315
Returns the file name of the current file.
sl@0
   316
sl@0
   317
Note: This will give the wrong answer if the file is renamed!
sl@0
   318
sl@0
   319
@return The FileName (without extension).
sl@0
   320
*/
sl@0
   321
const TDesC& CMMFFile::FileName() const
sl@0
   322
	{
sl@0
   323
	return *iFileName ;
sl@0
   324
	}
sl@0
   325
sl@0
   326
/**
sl@0
   327
Returns the extension of the current file.
sl@0
   328
sl@0
   329
Note: This will give the wrong answer if the file is renamed!
sl@0
   330
sl@0
   331
@return The File Extension.
sl@0
   332
*/
sl@0
   333
const TDesC& CMMFFile::Extension() const 
sl@0
   334
	{
sl@0
   335
	return *iFileExt ;
sl@0
   336
	}
sl@0
   337
sl@0
   338
/** 
sl@0
   339
Returns the path of the current file.
sl@0
   340
sl@0
   341
Note: This will give the wrong answer if the file is renamed!
sl@0
   342
sl@0
   343
@return The FilePath (without filename and extension)
sl@0
   344
*/
sl@0
   345
const TDesC& CMMFFile::FilePath() const 
sl@0
   346
	{
sl@0
   347
	return *iFilePath ;
sl@0
   348
	}
sl@0
   349
sl@0
   350
/** 
sl@0
   351
Returns the drive on which the current file is located.
sl@0
   352
sl@0
   353
Note: This will give the wrong answer if the file is renamed!
sl@0
   354
sl@0
   355
@return The FileDrive (drive letter only, without path, filename and extension).
sl@0
   356
*/
sl@0
   357
const TDesC& CMMFFile::FileDrive() const 
sl@0
   358
	{
sl@0
   359
	return *iFileDrive ;
sl@0
   360
	}
sl@0
   361
sl@0
   362
/** 
sl@0
   363
Returns the full name of the current file.
sl@0
   364
sl@0
   365
Note: This will give the wrong answer if the file is renamed!
sl@0
   366
sl@0
   367
@return The file name (full filename including drive letter, without path, filename and extension).
sl@0
   368
*/
sl@0
   369
const TFileName CMMFFile::FullName() const
sl@0
   370
	{
sl@0
   371
	return iFullFileName;
sl@0
   372
	}
sl@0
   373
	
sl@0
   374
/** 
sl@0
   375
Returns the uniqueID associated with this content. If no uniqueID has been provided, a null
sl@0
   376
descriptor will be provided
sl@0
   377
sl@0
   378
@return The UniqueID
sl@0
   379
*/
sl@0
   380
const TDesC& CMMFFile::UniqueId() const
sl@0
   381
	{
sl@0
   382
	if (iCAFParameters->iUniqueId)
sl@0
   383
		return *(iCAFParameters->iUniqueId);
sl@0
   384
	else
sl@0
   385
		return KNullDesC;
sl@0
   386
	}
sl@0
   387
sl@0
   388
sl@0
   389
/**
sl@0
   390
Deletes the file.
sl@0
   391
sl@0
   392
Closes the currently open file, then deletes it. If the file source is accessing a file handle, 
sl@0
   393
the file is truncated to 0 bytes instead.
sl@0
   394
sl@0
   395
@return An error code indicating if the function call was successful. KErrNone on success, otherwise
sl@0
   396
        another of the system-wide error codes.
sl@0
   397
*/
sl@0
   398
TInt CMMFFile::Delete()				
sl@0
   399
	{
sl@0
   400
	TInt result = KErrNone;
sl@0
   401
	if (!iFileHandle)
sl@0
   402
		{
sl@0
   403
		delete iFile;
sl@0
   404
		iFile = NULL;
sl@0
   405
		iFileSize=-1;
sl@0
   406
		iPosition=0;
sl@0
   407
sl@0
   408
		result = iFsSession.Delete(iFullFileName);
sl@0
   409
		}
sl@0
   410
	else
sl@0
   411
		{
sl@0
   412
		iFileSize=-1;
sl@0
   413
		iPosition=0;
sl@0
   414
		
sl@0
   415
		if (iFile)
sl@0
   416
			{
sl@0
   417
			result = iFile->SetSize(0);
sl@0
   418
			}
sl@0
   419
		}
sl@0
   420
sl@0
   421
	return result;
sl@0
   422
	}
sl@0
   423
sl@0
   424
/** 
sl@0
   425
Sets the file size.
sl@0
   426
sl@0
   427
@param  aSize
sl@0
   428
        The size of the file.
sl@0
   429
sl@0
   430
@return An error code indicating if the function call was successful. KErrNone on success, otherwise
sl@0
   431
        another of the system-wide error codes.
sl@0
   432
*/
sl@0
   433
TInt CMMFFile::SetSize(TInt aSize)
sl@0
   434
	{
sl@0
   435
	if ( !iFile )
sl@0
   436
		return KErrNotReady;
sl@0
   437
	TInt err =  iFile->SetSize(aSize);
sl@0
   438
	if(err == KErrNone)
sl@0
   439
		iFileSize = aSize;
sl@0
   440
	else
sl@0
   441
		iFileSize = -1;
sl@0
   442
sl@0
   443
	return err;
sl@0
   444
	}
sl@0
   445
	
sl@0
   446
/**
sl@0
   447
Obtains a CTransferBufferCopy from iTransferBufferCopies that is
sl@0
   448
at least as big as that required.
sl@0
   449
sl@0
   450
There is no need to put the pointer returned by this method onto the CleanupStack
sl@0
   451
as it will have already been placed into iTransferBufferCopies.
sl@0
   452
sl@0
   453
@param  aMaxLength
sl@0
   454
        The size required.
sl@0
   455
sl@0
   456
@return A pointer to a valid CTransferBufferCopy.
sl@0
   457
*/
sl@0
   458
CTransferBufferCopy* CMMFFile::ObtainCopyOfTransferBufferL(TInt aMaxLength)
sl@0
   459
	{
sl@0
   460
	//find a free transfer buffer copy of the right size
sl@0
   461
	TInt firstFree = -1;
sl@0
   462
	CTransferBufferCopy* transBufCopyToUse = NULL;
sl@0
   463
sl@0
   464
	for(TInt cnt=0; cnt < iTransferBufferCopies.Count(); cnt++)
sl@0
   465
		{
sl@0
   466
		if(!iTransferBufferCopies[cnt]->InUse())
sl@0
   467
			{
sl@0
   468
			//record the first free entry, we may remove this
sl@0
   469
			//if entries in iTransferBufferCopies > KAcceptableTransferBufferCopiesSize
sl@0
   470
			if(firstFree == -1) 
sl@0
   471
				firstFree = cnt;
sl@0
   472
sl@0
   473
			if(iTransferBufferCopies[cnt]->MaxLength() >= aMaxLength)
sl@0
   474
				{
sl@0
   475
				transBufCopyToUse = iTransferBufferCopies[cnt];
sl@0
   476
sl@0
   477
				//Set the MaxLength. This will ensure that the copy acts the same as
sl@0
   478
				//the original Transfer buffer, eg. file server will throw KErrOverflow
sl@0
   479
				transBufCopyToUse->ReUse(aMaxLength);
sl@0
   480
				break;
sl@0
   481
				}
sl@0
   482
			}
sl@0
   483
		}
sl@0
   484
sl@0
   485
	//If we failed to find a suitable entry, we need to create a new one
sl@0
   486
	if(!transBufCopyToUse)
sl@0
   487
		{
sl@0
   488
		//Firstly, should we re-cycle an existing entry?
sl@0
   489
		//There must be entries in the array, a free entry must have been found,
sl@0
   490
		//the size of the array must be beyond the water mark where we want to start
sl@0
   491
		//cycling free entries.
sl@0
   492
		if((iTransferBufferCopies.Count() > 0) &&
sl@0
   493
			(firstFree != -1) &&
sl@0
   494
			(iTransferBufferCopies.Count() > KAcceptableTransferBufferCopiesSize))
sl@0
   495
			{
sl@0
   496
			delete iTransferBufferCopies[firstFree];
sl@0
   497
			iTransferBufferCopies.Remove(firstFree);
sl@0
   498
sl@0
   499
			transBufCopyToUse = CTransferBufferCopy::NewL(aMaxLength);
sl@0
   500
			CleanupStack::PushL(transBufCopyToUse);
sl@0
   501
			User::LeaveIfError(iTransferBufferCopies.Insert(transBufCopyToUse,firstFree));
sl@0
   502
				
sl@0
   503
			CleanupStack::Pop();
sl@0
   504
			}
sl@0
   505
		else
sl@0
   506
			{
sl@0
   507
#ifdef _DEBUG
sl@0
   508
			if(iTransferBufferCopies.Count() > KMaximumTransferBufferCopiesSize)
sl@0
   509
				{
sl@0
   510
				User::Panic(_L("iTransferBufferCopies grew too large in CMMFFile"),KErrTooBig);
sl@0
   511
				}
sl@0
   512
#endif
sl@0
   513
sl@0
   514
			transBufCopyToUse = CTransferBufferCopy::NewL(aMaxLength);
sl@0
   515
			CleanupStack::PushL(transBufCopyToUse);
sl@0
   516
			User::LeaveIfError(iTransferBufferCopies.Append(transBufCopyToUse));
sl@0
   517
sl@0
   518
			CleanupStack::Pop();
sl@0
   519
			}
sl@0
   520
		}
sl@0
   521
sl@0
   522
	return transBufCopyToUse;
sl@0
   523
	}
sl@0
   524
sl@0
   525
sl@0
   526
sl@0
   527
/** 
sl@0
   528
Loads aBuffer from iFile.
sl@0
   529
sl@0
   530
The file must already be open for reading. File read is asynchronous. CReadRequest is created to 
sl@0
   531
respond to completion.
sl@0
   532
sl@0
   533
@param  aBuffer
sl@0
   534
        The buffer to be filled from the file.
sl@0
   535
@param  aConsumer
sl@0
   536
        The data sink consumer of the buffer.
sl@0
   537
*/
sl@0
   538
void CMMFFile::FillBufferL( CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId /*aMediaId*/ )
sl@0
   539
	{
sl@0
   540
	// Requires that iFile is open for read.
sl@0
   541
	// Reads data from iFile into aBuffer
sl@0
   542
	if ((aConsumer == NULL) || (aBuffer == NULL))
sl@0
   543
		User::Leave(KErrArgument);
sl@0
   544
sl@0
   545
	if (!iFile || (iMmfFileEventHandler == NULL))
sl@0
   546
		User::Leave(KErrNotReady);
sl@0
   547
sl@0
   548
	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   549
		{
sl@0
   550
		CTransferBufferCopy* transBufCopy = NULL;
sl@0
   551
		CReadRequest* request = NULL;
sl@0
   552
sl@0
   553
		TDes8& aBufferDes = STATIC_CAST( CMMFDataBuffer*, aBuffer )->Data();
sl@0
   554
sl@0
   555
		TInt requestSize;
sl@0
   556
		if(aBuffer->RequestSize())
sl@0
   557
			requestSize = aBuffer->RequestSize();
sl@0
   558
		else
sl@0
   559
			requestSize = aBufferDes.MaxLength();
sl@0
   560
sl@0
   561
		//check whether buffer is safe to send to file server
sl@0
   562
		//if not, eg for a transfer buffer, then it needs to be copied
sl@0
   563
		if (!CMMFBuffer::IsFileServerSafe(aBuffer->Type()))
sl@0
   564
			{
sl@0
   565
			//NB: failure in this method will NOT cause transBufCopy to leak as it will be 
sl@0
   566
			//inserted into iTransferBufferCopies by ObtainCopyOfTransferBufferL.
sl@0
   567
			transBufCopy = ObtainCopyOfTransferBufferL(aBufferDes.MaxLength());
sl@0
   568
			request = new(ELeave) CReadRequest(STATIC_CAST(TAny*, aConsumer), aBuffer, transBufCopy, iPosition, Size(), iMmfFileEventHandler);
sl@0
   569
			}
sl@0
   570
		else
sl@0
   571
			{
sl@0
   572
			request = new(ELeave) CReadRequest(STATIC_CAST(TAny*, aConsumer), aBuffer, iPosition, Size(), iMmfFileEventHandler);
sl@0
   573
			}
sl@0
   574
sl@0
   575
		CleanupStack::PushL( request );
sl@0
   576
sl@0
   577
		StoreRequestL(request); // transfers ownership
sl@0
   578
		CleanupStack::Pop() ; // request
sl@0
   579
sl@0
   580
		iFile->Read(request->BufferDes(), requestSize, request->iStatus);
sl@0
   581
		iPosition += requestSize;
sl@0
   582
		
sl@0
   583
		if (iPosition >= iFileSize)
sl@0
   584
			{
sl@0
   585
			aBuffer->SetLastBuffer(ETrue);
sl@0
   586
			}
sl@0
   587
sl@0
   588
		request->SetActive();
sl@0
   589
		}
sl@0
   590
	else // if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   591
		User::Leave( KErrNotSupported ) ;
sl@0
   592
	}
sl@0
   593
sl@0
   594
/** 
sl@0
   595
Empties aBuffer into iFile. The file must be already open for writing.
sl@0
   596
sl@0
   597
@param  aBuffer
sl@0
   598
        The buffer to be written to the file.
sl@0
   599
@param  aSupplier
sl@0
   600
        The data source supplier of the buffer.
sl@0
   601
*/
sl@0
   602
void CMMFFile::EmptyBufferL( CMMFBuffer* aBuffer, MDataSource* aSupplier, TMediaId /*aMediaId*/ )
sl@0
   603
	{
sl@0
   604
	// Requires that iFile is open for write.
sl@0
   605
	// Writes data from iFile into aBuffer
sl@0
   606
	if ((aSupplier == NULL) || (aBuffer == NULL))
sl@0
   607
		User::Leave(KErrArgument);
sl@0
   608
sl@0
   609
	if (!iFile || (iMmfFileEventHandler == NULL))
sl@0
   610
		User::Leave(KErrNotReady);
sl@0
   611
sl@0
   612
	CTransferBufferCopy* transBufCopy = NULL;
sl@0
   613
	
sl@0
   614
	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   615
		{
sl@0
   616
		CWriteRequest* request = NULL;
sl@0
   617
		TDes8& aBufferDes = STATIC_CAST( CMMFDataBuffer*, aBuffer )->Data();
sl@0
   618
sl@0
   619
		//check whether buffer is safe to send to file server
sl@0
   620
		//if not, eg for a transfer buffer, then it needs to be copied
sl@0
   621
		if (!CMMFBuffer::IsFileServerSafe(aBuffer->Type()))
sl@0
   622
			{
sl@0
   623
			//Obtain a normal buffer to send to the file server
sl@0
   624
			//NB: failure in this method will NOT cause transBufCopy to leak as it will be 
sl@0
   625
			//inserted into iTransferBufferCopies by ObtainCopyOfTransferBufferL.
sl@0
   626
			transBufCopy = ObtainCopyOfTransferBufferL(aBufferDes.MaxLength());
sl@0
   627
sl@0
   628
			//Copy the data into the buffer we will send to the file server
sl@0
   629
			transBufCopy->Des().Copy(aBufferDes);
sl@0
   630
sl@0
   631
			request = new(ELeave) CWriteRequest(STATIC_CAST(TAny*, aSupplier), aBuffer, transBufCopy, iMmfFileEventHandler);
sl@0
   632
			}
sl@0
   633
		else
sl@0
   634
			{
sl@0
   635
			request = new(ELeave) CWriteRequest(STATIC_CAST(TAny*, aSupplier), aBuffer, iMmfFileEventHandler);
sl@0
   636
			}
sl@0
   637
sl@0
   638
		CleanupStack::PushL( request );
sl@0
   639
sl@0
   640
		StoreRequestL(request);  // transfers ownership
sl@0
   641
		CleanupStack::Pop(); // request
sl@0
   642
sl@0
   643
		iFile->Write(request->BufferDes(), request->BufferDes().Length(), request->iStatus);
sl@0
   644
		request->SetActive();
sl@0
   645
		}
sl@0
   646
	else  // if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   647
		{
sl@0
   648
		User::Leave( KErrNotSupported ) ;
sl@0
   649
		}
sl@0
   650
	}
sl@0
   651
sl@0
   652
/** 
sl@0
   653
Loads aLength number of bytes into aBuffer from specified point in iFile.
sl@0
   654
sl@0
   655
@param  aLength
sl@0
   656
        The number of bytes to be read into buffer.
sl@0
   657
@param  aBuffer
sl@0
   658
        The buffer to be filled from the file.
sl@0
   659
@param  aPosition
sl@0
   660
        The offset into the file at which to start reading.
sl@0
   661
@param  aConsumer
sl@0
   662
        The data sink consumer of the buffer.
sl@0
   663
*/
sl@0
   664
void CMMFFile::ReadBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer)
sl@0
   665
	{
sl@0
   666
	// Requires that iFile is open for read.
sl@0
   667
	// Reads data from iFile into aBuffer
sl@0
   668
	if ((aLength < 0) || (aPosition<0) || (aConsumer == NULL) || (aBuffer == NULL))
sl@0
   669
		User::Leave(KErrArgument);
sl@0
   670
sl@0
   671
	if (!iFile || (iMmfFileEventHandler == NULL))
sl@0
   672
		User::Leave(KErrNotReady);
sl@0
   673
sl@0
   674
	CTransferBufferCopy* transBufCopy = NULL;
sl@0
   675
sl@0
   676
	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   677
		{
sl@0
   678
		CReadRequest* request = NULL;
sl@0
   679
		TDes8& aBufferDes = STATIC_CAST( CMMFDataBuffer*, aBuffer )->Data();
sl@0
   680
		
sl@0
   681
		//check whether buffer is safe to send to file server
sl@0
   682
		//if not, eg for a transfer buffer, then it needs to be copied
sl@0
   683
		if (!CMMFBuffer::IsFileServerSafe(aBuffer->Type()))
sl@0
   684
			{
sl@0
   685
			//Obtain a normal buffer to send to the file server
sl@0
   686
			//NB: failure in this method will NOT cause transBufCopy to leak as it will be 
sl@0
   687
			//inserted into iTransferBufferCopies by ObtainCopyOfTransferBufferL.
sl@0
   688
			transBufCopy = ObtainCopyOfTransferBufferL(aBufferDes.MaxLength());
sl@0
   689
sl@0
   690
			request = new(ELeave) CReadRequest(STATIC_CAST(TAny*, aConsumer), aBuffer, transBufCopy, aPosition, Size(), iMmfFileEventHandler);
sl@0
   691
			}
sl@0
   692
		else
sl@0
   693
			{
sl@0
   694
			request = new(ELeave) CReadRequest(STATIC_CAST(TAny*, aConsumer), aBuffer, aPosition, Size(), iMmfFileEventHandler);
sl@0
   695
			}
sl@0
   696
sl@0
   697
		CleanupStack::PushL( request );
sl@0
   698
sl@0
   699
		StoreRequestL(request) ;  //transfers ownership
sl@0
   700
		CleanupStack::Pop() ; //request
sl@0
   701
sl@0
   702
		TInt err = iFile->Read(aPosition, request->BufferDes(), aLength, request->iStatus);
sl@0
   703
		if (err == KErrCANotSupported)
sl@0
   704
			{
sl@0
   705
			err = KErrNone;
sl@0
   706
			if (aPosition != iPosition)
sl@0
   707
				{
sl@0
   708
				err = iFile->Seek(ESeekStart, aPosition);
sl@0
   709
				}
sl@0
   710
			if (err==KErrNone)
sl@0
   711
				{
sl@0
   712
				iFile->Read(request->BufferDes(), aLength, request->iStatus);
sl@0
   713
				}
sl@0
   714
			}
sl@0
   715
		
sl@0
   716
		if (err != KErrNone)
sl@0
   717
			{
sl@0
   718
			TRequestStatus* status = &request->iStatus;
sl@0
   719
			User::RequestComplete(status, err);
sl@0
   720
			}
sl@0
   721
sl@0
   722
		iPosition = aPosition + aLength;
sl@0
   723
		
sl@0
   724
		if (iPosition >= iFileSize)
sl@0
   725
			{
sl@0
   726
			aBuffer->SetLastBuffer(ETrue);
sl@0
   727
			}
sl@0
   728
sl@0
   729
		request->SetActive();
sl@0
   730
		}
sl@0
   731
	else // if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   732
		User::Leave( KErrNotSupported ) ;
sl@0
   733
	}
sl@0
   734
	
sl@0
   735
	
sl@0
   736
/**
sl@0
   737
Loads aBuffer from specified point in iFile.
sl@0
   738
sl@0
   739
The file must already be open for reading.
sl@0
   740
sl@0
   741
@param  aBuffer
sl@0
   742
        The buffer to be filled from the file.
sl@0
   743
@param  aPosition
sl@0
   744
        The offset into file at which to start reading.
sl@0
   745
@param  aConsumer
sl@0
   746
        The data sink consumer of the buffer.
sl@0
   747
*/
sl@0
   748
void CMMFFile::ReadBufferL(CMMFBuffer* aBuffer, TInt aPosition, MDataSink* aConsumer)
sl@0
   749
	{
sl@0
   750
	// Requires that iFile is open for read.
sl@0
   751
	// Reads data from iFile into aBuffer
sl@0
   752
	if ((aPosition<0) || (aConsumer == NULL) || (aBuffer == NULL))
sl@0
   753
		User::Leave(KErrArgument);
sl@0
   754
sl@0
   755
	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   756
		{
sl@0
   757
		TInt requestSize;
sl@0
   758
		if(aBuffer->RequestSize())
sl@0
   759
			requestSize = aBuffer->RequestSize();
sl@0
   760
		else
sl@0
   761
			requestSize = STATIC_CAST( CMMFDataBuffer*, aBuffer )->Data().MaxLength();
sl@0
   762
sl@0
   763
		ReadBufferL(requestSize, aBuffer, aPosition, aConsumer);
sl@0
   764
		}
sl@0
   765
	else // if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   766
		User::Leave(KErrNotSupported);
sl@0
   767
	}
sl@0
   768
sl@0
   769
sl@0
   770
/**
sl@0
   771
Loads aBuffer from specified point in iFile.  Note that this is a synchronous read.
sl@0
   772
sl@0
   773
@param  aBuffer
sl@0
   774
        The buffer to be filled from the file.
sl@0
   775
@param  aPosition
sl@0
   776
        The offset into file at which to start reading.
sl@0
   777
*/
sl@0
   778
void CMMFFile::ReadBufferL( CMMFBuffer* aBuffer, TInt aPosition)
sl@0
   779
	{
sl@0
   780
	// Requires that iFile is open for read.
sl@0
   781
	// Reads data from iFile into aBuffer
sl@0
   782
	if ((aPosition<0) || (aBuffer == NULL))
sl@0
   783
		User::Leave(KErrArgument);
sl@0
   784
sl@0
   785
	if (!iFile)
sl@0
   786
		User::Leave(KErrNotReady);
sl@0
   787
sl@0
   788
	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   789
		{
sl@0
   790
		TDes8& aBufferDes = STATIC_CAST( CMMFDataBuffer*, aBuffer )->Data();
sl@0
   791
sl@0
   792
		TInt requestSize;
sl@0
   793
		if(aBuffer->RequestSize())
sl@0
   794
			requestSize = aBuffer->RequestSize();
sl@0
   795
		else
sl@0
   796
			requestSize = aBufferDes.MaxLength();
sl@0
   797
sl@0
   798
		//check whether buffer is safe to send to file server
sl@0
   799
		//if not, eg for a transfer buffer, then it needs to be copied
sl@0
   800
		if (!CMMFBuffer::IsFileServerSafe(aBuffer->Type()))
sl@0
   801
			{
sl@0
   802
			//NB: failure in this method will NOT cause transBufCopy to leak as it will be 
sl@0
   803
			//inserted into iTransferBufferCopies by ObtainCopyOfTransferBufferL.
sl@0
   804
			CTransferBufferCopy* transBufCopy = ObtainCopyOfTransferBufferL(aBufferDes.MaxLength());
sl@0
   805
sl@0
   806
			User::LeaveIfError(iFile->Seek(ESeekStart, aPosition));
sl@0
   807
			User::LeaveIfError(iFile->Read(transBufCopy->Des(), requestSize));
sl@0
   808
			aBufferDes.Copy(transBufCopy->Des().Left(aBufferDes.MaxLength()));
sl@0
   809
			}
sl@0
   810
		else
sl@0
   811
			{
sl@0
   812
			User::LeaveIfError(iFile->Seek(ESeekStart, aPosition));
sl@0
   813
			User::LeaveIfError(iFile->Read(aBufferDes, requestSize));
sl@0
   814
			}
sl@0
   815
sl@0
   816
		iPosition = aPosition + aBufferDes.Length();
sl@0
   817
		
sl@0
   818
		//check if the buffer is the last buffer and if so set the last buffer flag on the CMMFDataBuffer
sl@0
   819
		//NB: setting last buffer is the done by the formatter, but this is a hang over to account for 
sl@0
   820
		//existing formatters that may fail if this is removed.
sl@0
   821
		if (iPosition >= Size())
sl@0
   822
			{
sl@0
   823
			aBuffer->SetLastBuffer(ETrue);
sl@0
   824
			}
sl@0
   825
		}
sl@0
   826
	else  // if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   827
		User::Leave(KErrNotSupported); 
sl@0
   828
	}
sl@0
   829
sl@0
   830
/** 
sl@0
   831
Empties aLength bytes from aBuffer into iFile at specified location.
sl@0
   832
sl@0
   833
@param  aLength
sl@0
   834
        The number of bytes to be emptied from buffer.
sl@0
   835
@param  aBuffer
sl@0
   836
        The data buffer containing bytes to be written.
sl@0
   837
@param  aPosition
sl@0
   838
        The offset into file at which to start writing.
sl@0
   839
@param  aSupplier
sl@0
   840
        The data source to be notified when the write has been completed.
sl@0
   841
sl@0
   842
@leave  KErrNotReady 
sl@0
   843
        SinkPrimeL() and SinkThreadLogon() have not been called.
sl@0
   844
@leave  KErrArgument 
sl@0
   845
        aLength<0 or aPosition<0 or aSupplier is NULL.
sl@0
   846
@leave  KErrNotSupported 
sl@0
   847
        aBuffer is not a supported CMMFDataBuffer
sl@0
   848
*/
sl@0
   849
void CMMFFile::WriteBufferL(TInt aLength, CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier)
sl@0
   850
	{
sl@0
   851
	if ((aLength<0) || (aPosition<0) || (aSupplier == NULL) || (aBuffer == NULL))
sl@0
   852
		User::Leave(KErrArgument);
sl@0
   853
sl@0
   854
	if (!iFile || (iMmfFileEventHandler == NULL))
sl@0
   855
		User::Leave(KErrNotReady);
sl@0
   856
	
sl@0
   857
	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   858
		{
sl@0
   859
		CWriteRequest* request = NULL;
sl@0
   860
		TDes8& aBufferDes = STATIC_CAST( CMMFDataBuffer*, aBuffer )->Data();
sl@0
   861
sl@0
   862
		//check whether buffer is safe to send to file server
sl@0
   863
		//if not, eg for a transfer buffer, then it needs to be copied
sl@0
   864
		if (!CMMFBuffer::IsFileServerSafe(aBuffer->Type()))
sl@0
   865
			{
sl@0
   866
			//NB: failure in this method will NOT cause transBufCopy to leak as it will be 
sl@0
   867
			//inserted into iTransferBufferCopies by ObtainCopyOfTransferBufferL.
sl@0
   868
			CTransferBufferCopy* transBufCopy = ObtainCopyOfTransferBufferL(aBufferDes.MaxLength());
sl@0
   869
sl@0
   870
			transBufCopy->Des().Copy(aBufferDes);
sl@0
   871
sl@0
   872
			request = new(ELeave) CWriteRequest(STATIC_CAST(TAny*, aSupplier), aBuffer, transBufCopy, iMmfFileEventHandler);
sl@0
   873
			}
sl@0
   874
		else
sl@0
   875
			{
sl@0
   876
			request = new(ELeave) CWriteRequest(STATIC_CAST(TAny*, aSupplier), aBuffer, iMmfFileEventHandler);
sl@0
   877
			}
sl@0
   878
sl@0
   879
		CleanupStack::PushL( request );
sl@0
   880
sl@0
   881
		StoreRequestL(request);  // transfers ownership
sl@0
   882
		CleanupStack::Pop(); // request
sl@0
   883
sl@0
   884
		User::LeaveIfError(iFile->Seek(ESeekStart, aPosition));		
sl@0
   885
		iFile->Write(request->BufferDes(), aLength, request->iStatus);
sl@0
   886
		iFileSize = -1; //reset cached size
sl@0
   887
sl@0
   888
		request->SetActive();
sl@0
   889
		}
sl@0
   890
	else // if (!CMMFBuffer::IsFileServerSafe(aBuffer->Type()))
sl@0
   891
		{
sl@0
   892
		//write bitmap to file
sl@0
   893
		User::Leave(KErrNotSupported);
sl@0
   894
		}
sl@0
   895
	}
sl@0
   896
sl@0
   897
/**
sl@0
   898
Empties aBuffer into iFile at the specified location.
sl@0
   899
sl@0
   900
@param  aBuffer
sl@0
   901
        The data buffer containing bytes to be written.
sl@0
   902
@param  aPosition
sl@0
   903
        The offset into file at which to start writing.
sl@0
   904
@param  aSupplier
sl@0
   905
        The data source to be notified when the write has been completed.
sl@0
   906
sl@0
   907
@leave  KErrNotReady 
sl@0
   908
        SinkPrimeL() and SinkThreadLogon() have not been called.
sl@0
   909
@leave  KErrArgument 
sl@0
   910
        aSupplier is NULL.
sl@0
   911
@leave  KErrNotSupported 
sl@0
   912
        The aBuffer is not of type KMMFDataBuffer.
sl@0
   913
*/
sl@0
   914
void CMMFFile::WriteBufferL( CMMFBuffer* aBuffer, TInt aPosition, MDataSource* aSupplier)
sl@0
   915
	{
sl@0
   916
	// Requires that iFile is open for write.
sl@0
   917
	// Writes data from iFile into aBuffer
sl@0
   918
	if ((aPosition<0) || (aSupplier == NULL) || (aBuffer == NULL))
sl@0
   919
		User::Leave(KErrArgument);
sl@0
   920
sl@0
   921
	if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   922
		{
sl@0
   923
		TUint requestSize = STATIC_CAST( CMMFDataBuffer*, aBuffer )->Data().Length();
sl@0
   924
sl@0
   925
		WriteBufferL(requestSize, aBuffer, aPosition, aSupplier);
sl@0
   926
		}
sl@0
   927
	else  // if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   928
		{
sl@0
   929
		//write bitmap to file
sl@0
   930
		User::Leave( KErrNotSupported ) ;
sl@0
   931
		}
sl@0
   932
	}
sl@0
   933
sl@0
   934
/**
sl@0
   935
Empties aBuffer into iFile at specified location.  Note that this is a synchronous write.
sl@0
   936
sl@0
   937
@param  aBuffer
sl@0
   938
        The data buffer containing bytes to be written.
sl@0
   939
@param  aPosition
sl@0
   940
        The offset into file at which to start writing.
sl@0
   941
sl@0
   942
@return The error code from RFile.
sl@0
   943
*/
sl@0
   944
void CMMFFile::WriteBufferL( CMMFBuffer* aBuffer, TInt aPosition ) 
sl@0
   945
	{
sl@0
   946
	if ((aPosition<0) || (aBuffer == NULL))
sl@0
   947
		User::Leave(KErrArgument);
sl@0
   948
sl@0
   949
	if (!iFile)
sl@0
   950
		User::Leave(KErrNotReady);
sl@0
   951
sl@0
   952
	TInt err(KErrNone) ;
sl@0
   953
sl@0
   954
	//check whether buffer is safe to send to file server
sl@0
   955
	//if not, eg for a transfer buffer, then it needs to be copied
sl@0
   956
	if ((!CMMFBuffer::IsFileServerSafe(aBuffer->Type()))
sl@0
   957
		&& (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type())))
sl@0
   958
		{
sl@0
   959
		TDes8& aBufferDes = STATIC_CAST( CMMFDataBuffer*, aBuffer )->Data();
sl@0
   960
sl@0
   961
		//NB: failure in this method will NOT cause transBufCopy to leak as it will be 
sl@0
   962
		//inserted into iTransferBufferCopies by ObtainCopyOfTransferBufferL.
sl@0
   963
		CTransferBufferCopy* transBufCopy = ObtainCopyOfTransferBufferL(aBufferDes.MaxLength());
sl@0
   964
sl@0
   965
		transBufCopy->Des().Copy(aBufferDes);
sl@0
   966
		err = iFile->Seek(ESeekStart, aPosition);
sl@0
   967
		if (err==KErrNone)
sl@0
   968
			err = iFile->Write(transBufCopy->Des(),transBufCopy->Des().Length()); 
sl@0
   969
		iFileSize = -1; //reset cached size
sl@0
   970
		}
sl@0
   971
	else if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   972
		{
sl@0
   973
		TDes8& aBufferDes = STATIC_CAST( CMMFDataBuffer*, aBuffer )->Data();
sl@0
   974
sl@0
   975
		err = iFile->Seek(ESeekStart, aPosition);
sl@0
   976
		if (err==KErrNone)
sl@0
   977
			err = iFile->Write(aBufferDes, aBufferDes.Length()); 
sl@0
   978
		iFileSize = -1; //reset cached size
sl@0
   979
		}
sl@0
   980
	else // if (CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))
sl@0
   981
		{
sl@0
   982
		User::Leave(KErrNotSupported);
sl@0
   983
		}
sl@0
   984
sl@0
   985
	User::LeaveIfError(err);
sl@0
   986
	}
sl@0
   987
sl@0
   988
/**
sl@0
   989
Gets the number of free bytes in the device's file system.
sl@0
   990
sl@0
   991
@return The number of free bytes.
sl@0
   992
*/
sl@0
   993
TInt64 CMMFFile::BytesFree()
sl@0
   994
	{
sl@0
   995
	TInt driveNumber = KDefaultDrive;
sl@0
   996
	
sl@0
   997
	if (FileDrive().Length() > 0)
sl@0
   998
 		{
sl@0
   999
 		TChar driveLetter = FileDrive()[0];
sl@0
  1000
 		RFs::CharToDrive(driveLetter, driveNumber);
sl@0
  1001
 		}
sl@0
  1002
	
sl@0
  1003
	TVolumeInfo volInfo;
sl@0
  1004
	if (iFsSession.Volume(volInfo, driveNumber) == KErrNone)
sl@0
  1005
		{
sl@0
  1006
		return volInfo.iFree;
sl@0
  1007
		}
sl@0
  1008
	return TInt64(0);
sl@0
  1009
	}
sl@0
  1010
sl@0
  1011
/** 
sl@0
  1012
Returns the size of the file in bytes.
sl@0
  1013
sl@0
  1014
Note: This is not the maximum length.
sl@0
  1015
sl@0
  1016
@return The size of the file in bytes.
sl@0
  1017
*/
sl@0
  1018
TInt CMMFFile::Size()
sl@0
  1019
	{
sl@0
  1020
	TInt size = 0;
sl@0
  1021
	TInt err = KErrNone;
sl@0
  1022
	TBool fileOpened = EFalse;
sl@0
  1023
sl@0
  1024
	if(iFileSize != -1)
sl@0
  1025
		return iFileSize;
sl@0
  1026
sl@0
  1027
	if (!iFile)
sl@0
  1028
		{
sl@0
  1029
		// Open the file. We only need read access, so SourcePrimeL will open the file with read flag
sl@0
  1030
		TRAP(err, SourcePrimeL());
sl@0
  1031
		if (iFile)
sl@0
  1032
			fileOpened = ETrue;
sl@0
  1033
		}
sl@0
  1034
	if (err == KErrNone)
sl@0
  1035
	    {
sl@0
  1036
	    __ASSERT_DEBUG(iFile != NULL,Panic(EMMFFileHandleNULL));
sl@0
  1037
		err = iFile->Size(size);
sl@0
  1038
	    }
sl@0
  1039
	if (err)
sl@0
  1040
		{
sl@0
  1041
		size = 0;
sl@0
  1042
		iFileSize = -1; //reset cached size
sl@0
  1043
		}
sl@0
  1044
	else 
sl@0
  1045
		iFileSize = size; //cache the filesize
sl@0
  1046
sl@0
  1047
	if (fileOpened)
sl@0
  1048
		{
sl@0
  1049
		__ASSERT_DEBUG(iFile != NULL,Panic(EMMFFileHandleNULL));
sl@0
  1050
		delete iFile;
sl@0
  1051
		iFile = NULL;
sl@0
  1052
		iFileSize = -1;
sl@0
  1053
		}
sl@0
  1054
sl@0
  1055
	return size;
sl@0
  1056
	}
sl@0
  1057
sl@0
  1058
/**
sl@0
  1059
Source thread logon.
sl@0
  1060
sl@0
  1061
Shares fsSession between threads
sl@0
  1062
sl@0
  1063
@param  aEventHandler
sl@0
  1064
        This is an MAsyncEventHandler to handle asynchronous events that occur during the
sl@0
  1065
        transfer of multimedia data.
sl@0
  1066
sl@0
  1067
@return An error code indicating if the function call was successful. KErrNone on success, otherwise
sl@0
  1068
        another of the system-wide error codes.
sl@0
  1069
*/
sl@0
  1070
TInt CMMFFile::SourceThreadLogon(MAsyncEventHandler& aEventHandler)
sl@0
  1071
	{
sl@0
  1072
	iEventHandler = &aEventHandler;
sl@0
  1073
	if(!iMmfFileEventHandler)
sl@0
  1074
		{
sl@0
  1075
		iMmfFileEventHandler = new CMMFFileAsyncEventHandler(this);
sl@0
  1076
		if(!iMmfFileEventHandler)
sl@0
  1077
			return KErrNoMemory;
sl@0
  1078
		}
sl@0
  1079
#ifdef __IPC_V2_PRESENT__
sl@0
  1080
	return KErrNone; // nothing to do
sl@0
  1081
#else
sl@0
  1082
	return iFsSession.Attach();
sl@0
  1083
#endif // __HIDE_IPC_V1__
sl@0
  1084
	}
sl@0
  1085
sl@0
  1086
/** 
sl@0
  1087
Logs off source thread.
sl@0
  1088
*/
sl@0
  1089
void CMMFFile::SourceThreadLogoff()
sl@0
  1090
	{
sl@0
  1091
	delete iMmfFileEventHandler;
sl@0
  1092
	iMmfFileEventHandler = NULL;
sl@0
  1093
	iEventHandler = NULL;
sl@0
  1094
	}
sl@0
  1095
sl@0
  1096
sl@0
  1097
/**
sl@0
  1098
Sink thread logon.
sl@0
  1099
sl@0
  1100
Shares fsSession between threads.
sl@0
  1101
sl@0
  1102
@param  aEventHandler
sl@0
  1103
        This is an MAsyncEventHandler to handle asynchronous events that occur during the
sl@0
  1104
        transfer of multimedia data.
sl@0
  1105
sl@0
  1106
@return An error code indicating if the function call was successful. KErrNone on success, otherwise
sl@0
  1107
        another of the system-wide error codes.
sl@0
  1108
*/
sl@0
  1109
TInt CMMFFile::SinkThreadLogon(MAsyncEventHandler& aEventHandler)
sl@0
  1110
	{
sl@0
  1111
	iEventHandler = &aEventHandler;
sl@0
  1112
	if(!iMmfFileEventHandler)
sl@0
  1113
		{
sl@0
  1114
		iMmfFileEventHandler = new CMMFFileAsyncEventHandler(this);
sl@0
  1115
		if(!iMmfFileEventHandler)
sl@0
  1116
			return KErrNoMemory;
sl@0
  1117
		}
sl@0
  1118
#ifdef __IPC_V2_PRESENT__
sl@0
  1119
	return KErrNone;
sl@0
  1120
#else
sl@0
  1121
	return iFsSession.Attach();
sl@0
  1122
#endif // __HIDE_IPC_V1__
sl@0
  1123
	}
sl@0
  1124
sl@0
  1125
/** 
sl@0
  1126
Sink thread log off.
sl@0
  1127
*/
sl@0
  1128
void CMMFFile::SinkThreadLogoff() 
sl@0
  1129
	{
sl@0
  1130
	delete iMmfFileEventHandler;
sl@0
  1131
	iMmfFileEventHandler = NULL;
sl@0
  1132
	iEventHandler = NULL;
sl@0
  1133
	}
sl@0
  1134
sl@0
  1135
/**
sl@0
  1136
Stores a request in an array.
sl@0
  1137
sl@0
  1138
CReadWriteRequests are stored in the array iRequests.
sl@0
  1139
This function takes ownership and places the request in the array.
sl@0
  1140
It also checks the array for completed requests and removes them.
sl@0
  1141
sl@0
  1142
@param  aRequest
sl@0
  1143
        The request to store.
sl@0
  1144
*/
sl@0
  1145
void CMMFFile::StoreRequestL( CReadWriteRequest* aRequest )
sl@0
  1146
	{
sl@0
  1147
	// add aRequest to iRequests
sl@0
  1148
	User::LeaveIfError( iRequests.Append( aRequest ) ) ;
sl@0
  1149
sl@0
  1150
	// Clear out any completed requests
sl@0
  1151
	for ( TInt ii = 0 ; ii < iRequests.Count() ; ii++ )
sl@0
  1152
		{
sl@0
  1153
		if (iRequests[ii]->Completed())
sl@0
  1154
			{
sl@0
  1155
			CReadWriteRequest* request = iRequests[ii];
sl@0
  1156
			delete request;
sl@0
  1157
sl@0
  1158
			iRequests.Remove(ii);
sl@0
  1159
			ii--;
sl@0
  1160
			}
sl@0
  1161
		}
sl@0
  1162
	}
sl@0
  1163
sl@0
  1164
sl@0
  1165
/**
sl@0
  1166
Cancels outstanding requests.
sl@0
  1167
sl@0
  1168
CReadWriteRequests are stored in the array iRequests.
sl@0
  1169
This function cancels any outstanding requests and removes them
sl@0
  1170
from iRequests.
sl@0
  1171
*/
sl@0
  1172
void CMMFFile::CancelRequests()
sl@0
  1173
	{
sl@0
  1174
	// Clear out any completed requests
sl@0
  1175
	for ( TInt ii = 0 ; ii < iRequests.Count() ; ii++ )
sl@0
  1176
		{
sl@0
  1177
		CReadWriteRequest* request = iRequests[ii];
sl@0
  1178
		delete request;
sl@0
  1179
		iRequests.Remove(ii);
sl@0
  1180
		ii--;
sl@0
  1181
		}
sl@0
  1182
	}
sl@0
  1183
sl@0
  1184
sl@0
  1185
sl@0
  1186
/**
sl@0
  1187
Returns the data type as a fourCC code of CMMFFile as a data source.
sl@0
  1188
sl@0
  1189
@return The data type fourCC code.
sl@0
  1190
*/
sl@0
  1191
TFourCC CMMFFile::SourceDataTypeCode(TMediaId /*aMediaId*/) 
sl@0
  1192
	{
sl@0
  1193
	return  iSourceFourCC ;
sl@0
  1194
	}
sl@0
  1195
sl@0
  1196
/**
sl@0
  1197
Returns the data type as a fourCC code of CMMFFile as a data sink.
sl@0
  1198
sl@0
  1199
@return The data type fourCC code
sl@0
  1200
*/
sl@0
  1201
TFourCC CMMFFile::SinkDataTypeCode(TMediaId /*aMediaId*/) 
sl@0
  1202
	{
sl@0
  1203
	return  iSinkFourCC ;
sl@0
  1204
	}
sl@0
  1205
sl@0
  1206
sl@0
  1207
/**
sl@0
  1208
CMMFFile as a source is always passive so this function is not supported.
sl@0
  1209
sl@0
  1210
@param  aBuffer
sl@0
  1211
        The emptied buffer.
sl@0
  1212
*/
sl@0
  1213
void CMMFFile::BufferEmptiedL(CMMFBuffer* /* aBuffer */)
sl@0
  1214
	{
sl@0
  1215
	Panic(EMMFFilePanicBufferEmptiedLNotSupported);
sl@0
  1216
	}
sl@0
  1217
sl@0
  1218
/**
sl@0
  1219
Tests whether a source buffer can be created.
sl@0
  1220
sl@0
  1221
@return	A boolean indicating if if CMMFFile can create its own buffer. EFalse if CMMFFile cannot 
sl@0
  1222
        create it's own buffer.
sl@0
  1223
*/
sl@0
  1224
TBool CMMFFile::CanCreateSourceBuffer()
sl@0
  1225
	{
sl@0
  1226
	return EFalse ;
sl@0
  1227
	}
sl@0
  1228
sl@0
  1229
/**
sl@0
  1230
Creates a source buffer.
sl@0
  1231
sl@0
  1232
@param  aMediaId
sl@0
  1233
        The Media ID.
sl@0
  1234
@param  aReference
sl@0
  1235
        A boolean indicating if MDataSource owns the buffer. ETrue if it does, EFalse if the caller
sl@0
  1236
        owns the buffer.
sl@0
  1237
sl@0
  1238
@return	NULL as a CMMFFile cannot create it's own buffer
sl@0
  1239
*/
sl@0
  1240
CMMFBuffer* CMMFFile::CreateSourceBufferL( TMediaId /*aMediaId*/ , TBool& /*aReference*/)
sl@0
  1241
	{
sl@0
  1242
	User::Leave(KErrNotSupported);
sl@0
  1243
	return NULL ;
sl@0
  1244
	}
sl@0
  1245
sl@0
  1246
/**
sl@0
  1247
CMMFFile as a sink is always passive so this function is not supported.
sl@0
  1248
sl@0
  1249
@param  aBuffer
sl@0
  1250
        The buffer.
sl@0
  1251
*/
sl@0
  1252
void CMMFFile::BufferFilledL(CMMFBuffer* /* aBuffer */)
sl@0
  1253
	{
sl@0
  1254
	Panic(EMMFFilePanicBufferFilledLNotSupported);
sl@0
  1255
	}
sl@0
  1256
sl@0
  1257
/**
sl@0
  1258
Tests whether a sink buffer can be created.
sl@0
  1259
sl@0
  1260
@return	A boolean indicating if the sink buffer can be created. EFalse if CMMFFile cannot create 
sl@0
  1261
        it's own buffer
sl@0
  1262
*/
sl@0
  1263
TBool CMMFFile::CanCreateSinkBuffer() 
sl@0
  1264
	{
sl@0
  1265
	return EFalse ;
sl@0
  1266
	}
sl@0
  1267
sl@0
  1268
/**
sl@0
  1269
Creates a sink buffer.
sl@0
  1270
sl@0
  1271
@param  aMediaId
sl@0
  1272
        The Media ID.
sl@0
  1273
@param  aReference 
sl@0
  1274
        A boolean indicating if MDataSource owns the buffer. ETrue if MDataSource owns the buffer,
sl@0
  1275
        EFalse if the caller owns the buffer.
sl@0
  1276
sl@0
  1277
@return	NULL as a CMMFFile cannot create it's own buffer
sl@0
  1278
*/
sl@0
  1279
CMMFBuffer* CMMFFile::CreateSinkBufferL(TMediaId /*aMediaId*/ , TBool& /*aReference*/) 
sl@0
  1280
	{
sl@0
  1281
	User::Leave(KErrNotSupported);
sl@0
  1282
	return NULL ;
sl@0
  1283
	}
sl@0
  1284
sl@0
  1285
/**
sl@0
  1286
Primes the source.
sl@0
  1287
sl@0
  1288
When used as a source, the file prime opens the file as read only.
sl@0
  1289
*/
sl@0
  1290
void CMMFFile::SourcePrimeL()
sl@0
  1291
	{
sl@0
  1292
	// don't reopen file if already open
sl@0
  1293
	if (!iFile)
sl@0
  1294
		{
sl@0
  1295
		if (iFileHandle)
sl@0
  1296
			{
sl@0
  1297
			iFile = CContentFile::NewL(iHandle, UniqueId(), iCAFParameters->iEnableUI);
sl@0
  1298
			}
sl@0
  1299
		else
sl@0
  1300
			{
sl@0
  1301
			// Open for read-only access
sl@0
  1302
			iFile = CContentFile::NewL(iFsSession, iFullFileName, UniqueId(), EFileShareReadersOnly, iCAFParameters->iEnableUI);
sl@0
  1303
			}
sl@0
  1304
		}
sl@0
  1305
	}
sl@0
  1306
sl@0
  1307
/**
sl@0
  1308
Primes the sink.
sl@0
  1309
sl@0
  1310
When used as a sink, the file prime opens the file for read/write access.
sl@0
  1311
*/
sl@0
  1312
void CMMFFile::SinkPrimeL() 
sl@0
  1313
	{
sl@0
  1314
	// don't reopen file if already open
sl@0
  1315
	if (!iFile)
sl@0
  1316
		{
sl@0
  1317
		if (iFileHandle)
sl@0
  1318
			iFile = CF32File::NewL(iHandle);
sl@0
  1319
		else
sl@0
  1320
			iFile = CF32File::NewL(iFsSession, iFullFileName, EFileRead | EFileWrite);
sl@0
  1321
		}
sl@0
  1322
		iSinkNotStopped = ETrue;
sl@0
  1323
	}
sl@0
  1324
sl@0
  1325
/**
sl@0
  1326
Stops the file source. When stopping close the file. If the source is a file handle, the position is reset, but the 
sl@0
  1327
file handle remains open.
sl@0
  1328
*/
sl@0
  1329
void CMMFFile::SourceStopL()
sl@0
  1330
	{
sl@0
  1331
	TInt pos = 0;
sl@0
  1332
sl@0
  1333
	CancelRequests();
sl@0
  1334
	
sl@0
  1335
	// It is possible the file could have disappeared at this point (MMC/SD Card)
sl@0
  1336
	//
sl@0
  1337
	if (!iFile)
sl@0
  1338
		{
sl@0
  1339
		iPosition=pos;
sl@0
  1340
		return;
sl@0
  1341
		}
sl@0
  1342
sl@0
  1343
	if (!iFileHandle && !iFile->IsProtected())
sl@0
  1344
		{
sl@0
  1345
		delete iFile;
sl@0
  1346
		iFile = NULL;
sl@0
  1347
		iFileSize = -1;
sl@0
  1348
		}
sl@0
  1349
	else
sl@0
  1350
		{
sl@0
  1351
		User::LeaveIfError(iFile->Seek(ESeekStart, pos));
sl@0
  1352
		}
sl@0
  1353
	iPosition=pos;
sl@0
  1354
	}
sl@0
  1355
sl@0
  1356
/**
sl@0
  1357
Stops the file sink. 
sl@0
  1358
sl@0
  1359
When stopping close the file. When the file sink is a file handle, the position is reset, but the file handle
sl@0
  1360
remains open
sl@0
  1361
*/
sl@0
  1362
void CMMFFile::SinkStopL()
sl@0
  1363
	{
sl@0
  1364
	iFileSize = -1;
sl@0
  1365
	iPosition=0;
sl@0
  1366
sl@0
  1367
	CancelRequests();
sl@0
  1368
	iSinkNotStopped = EFalse;
sl@0
  1369
	if (!iFileHandle)
sl@0
  1370
		{		
sl@0
  1371
		delete iFile;
sl@0
  1372
		iFile = NULL;
sl@0
  1373
		}
sl@0
  1374
	else
sl@0
  1375
		{
sl@0
  1376
		TInt pos = 0;
sl@0
  1377
		User::LeaveIfError(iFile->Seek(ESeekStart, pos));
sl@0
  1378
		}
sl@0
  1379
	}
sl@0
  1380
sl@0
  1381
/**
sl@0
  1382
Pauses the file source
sl@0
  1383
*/
sl@0
  1384
void CMMFFile::SourcePauseL()
sl@0
  1385
	{
sl@0
  1386
	CancelRequests();
sl@0
  1387
	}
sl@0
  1388
sl@0
  1389
/**
sl@0
  1390
Returns a boolean indicating if the sink has been stopped.
sl@0
  1391
sl@0
  1392
@return A boolean indicating if the sink has stopped.
sl@0
  1393
 */
sl@0
  1394
TBool CMMFFile::SinkStopped()
sl@0
  1395
	{
sl@0
  1396
	if(iSinkNotStopped == EFalse)
sl@0
  1397
		return ETrue;
sl@0
  1398
	else
sl@0
  1399
		return EFalse;
sl@0
  1400
	}
sl@0
  1401
sl@0
  1402
/**
sl@0
  1403
Evaluates a given intent against the rights associated with the file.
sl@0
  1404
sl@0
  1405
The rights are not updated by this function call.
sl@0
  1406
sl@0
  1407
@param  aIntent
sl@0
  1408
        The intent to evaluate.
sl@0
  1409
sl@0
  1410
@return An error code indicating if the function call was successful. KErrNone on success, otherwise
sl@0
  1411
        another of the system-wide error codes.
sl@0
  1412
*/
sl@0
  1413
TInt CMMFFile::EvaluateIntent(ContentAccess::TIntent aIntent) const
sl@0
  1414
	{
sl@0
  1415
	if (iFile==NULL)
sl@0
  1416
		{
sl@0
  1417
		return KErrNotReady;
sl@0
  1418
		}
sl@0
  1419
sl@0
  1420
	return iFile->EvaluateIntent(aIntent);
sl@0
  1421
	}
sl@0
  1422
sl@0
  1423
/**
sl@0
  1424
Evaluates and executes a given intent against the rights associated with the file.
sl@0
  1425
sl@0
  1426
The rights object is updated after calling this function.
sl@0
  1427
sl@0
  1428
@param  aIntent
sl@0
  1429
        The intent to evaluate.
sl@0
  1430
sl@0
  1431
@return An error code indicating if the function call was successful. KErrNone on success, otherwise
sl@0
  1432
        another of the system-wide error codes.
sl@0
  1433
*/
sl@0
  1434
TInt CMMFFile::ExecuteIntent(ContentAccess::TIntent aIntent)
sl@0
  1435
	{
sl@0
  1436
	if (iFile==NULL)
sl@0
  1437
		{
sl@0
  1438
		return KErrNotReady;
sl@0
  1439
		}
sl@0
  1440
sl@0
  1441
	return iFile->ExecuteIntent(aIntent);
sl@0
  1442
	}
sl@0
  1443
sl@0
  1444
/**
sl@0
  1445
Returns whether the file is protected.
sl@0
  1446
sl@0
  1447
@return A boolean indicating if the file is protected. ETrue if the file is protected.
sl@0
  1448
*/
sl@0
  1449
TBool CMMFFile::IsProtectedL() const
sl@0
  1450
	{
sl@0
  1451
	if (iFile==NULL)
sl@0
  1452
		{
sl@0
  1453
		User::Leave(KErrNotReady);
sl@0
  1454
		}
sl@0
  1455
sl@0
  1456
	return iFile->IsProtected();
sl@0
  1457
	}
sl@0
  1458
sl@0
  1459
TInt CMMFFile::SetAgentProperty(ContentAccess::TAgentProperty aProperty, TInt aValue)
sl@0
  1460
	{
sl@0
  1461
	if (iFile==NULL)
sl@0
  1462
		{
sl@0
  1463
		return KErrNotReady;
sl@0
  1464
		}
sl@0
  1465
sl@0
  1466
	return iFile->SetAgentProperty(aProperty, aValue);
sl@0
  1467
	}
sl@0
  1468
sl@0
  1469
/*
sl@0
  1470
 *	Returns ETrue if the request can safely be deleted.
sl@0
  1471
 */
sl@0
  1472
TBool CReadWriteRequest::Completed() 
sl@0
  1473
	{
sl@0
  1474
	return iCompleted ;
sl@0
  1475
	}
sl@0
  1476
sl@0
  1477
/*
sl@0
  1478
 *	Returns the data member of CMMFDataBuffer or CMMFTransferBuffer (as TPtr8)
sl@0
  1479
 *  
sl@0
  1480
 */
sl@0
  1481
TDes8& CReadWriteRequest::BufferDes()
sl@0
  1482
	{
sl@0
  1483
	if(iTransferBufferCopy)
sl@0
  1484
		return iTransferBufferCopy->Des();
sl@0
  1485
	else
sl@0
  1486
		{
sl@0
  1487
		//reset iBufferDes in case iBuffer has changed...
sl@0
  1488
		iBufferDes = &(STATIC_CAST(CMMFDataBuffer*, iBuffer)->Data());
sl@0
  1489
		return *iBufferDes;
sl@0
  1490
		}
sl@0
  1491
	}
sl@0
  1492
	
sl@0
  1493
const TDesC8& CReadWriteRequest::BufferDesC()
sl@0
  1494
	{
sl@0
  1495
	if(iTransferBufferCopy)
sl@0
  1496
		return iTransferBufferCopy->Des();
sl@0
  1497
	else
sl@0
  1498
		return BufferDes();
sl@0
  1499
	}
sl@0
  1500
sl@0
  1501
sl@0
  1502
/*
sl@0
  1503
 *	Destructor.
sl@0
  1504
 */
sl@0
  1505
CReadWriteRequest::~CReadWriteRequest() 
sl@0
  1506
	{
sl@0
  1507
	Cancel();
sl@0
  1508
	if(iTransferBufferCopy)
sl@0
  1509
		iTransferBufferCopy->SetInUse(EFalse);
sl@0
  1510
	}
sl@0
  1511
sl@0
  1512
/*
sl@0
  1513
 *	Allows owning class access to SetActive()
sl@0
  1514
 */
sl@0
  1515
void CReadWriteRequest::SetActive() 
sl@0
  1516
	{
sl@0
  1517
	CActive::SetActive() ;
sl@0
  1518
	}
sl@0
  1519
sl@0
  1520
/*
sl@0
  1521
 *  For the moment at least...    Canceled requests may be deleted
sl@0
  1522
 */
sl@0
  1523
void CReadWriteRequest::DoCancel() 
sl@0
  1524
	{
sl@0
  1525
	iCompleted = ETrue ;
sl@0
  1526
	}
sl@0
  1527
sl@0
  1528
/*
sl@0
  1529
 *	Called when errors in RunL force Leave.  For the moment just mark the request deletable
sl@0
  1530
 */
sl@0
  1531
TInt CReadWriteRequest::RunError( TInt aError ) 
sl@0
  1532
	{
sl@0
  1533
	//RunL can leave.
sl@0
  1534
	iCompleted = ETrue ;
sl@0
  1535
	iError = aError; //keep this error internally for now
sl@0
  1536
	return KErrNone ;
sl@0
  1537
	}
sl@0
  1538
sl@0
  1539
/*
sl@0
  1540
 *	On completion of read request call back to the MDataSink
sl@0
  1541
 */
sl@0
  1542
void CReadRequest::RunL() 
sl@0
  1543
	{
sl@0
  1544
	if (iStatus != KErrNone)
sl@0
  1545
		{
sl@0
  1546
		TMMFEvent event(KMMFErrorCategoryControllerGeneralError, iStatus.Int());
sl@0
  1547
		iEventHandler->SendEventToClient(event);
sl@0
  1548
		}
sl@0
  1549
	else
sl@0
  1550
		{
sl@0
  1551
		//Copy the data from the normal buffer into the Transfer buffer
sl@0
  1552
		if(iTransferBufferCopy)
sl@0
  1553
			{
sl@0
  1554
			//must specify the size here as the dest may be smaller than the source.
sl@0
  1555
			TDes8& destDesc = STATIC_CAST(CMMFDataBuffer*, iBuffer)->Data();
sl@0
  1556
			destDesc.Copy(iTransferBufferCopy->Des().Left(destDesc.MaxLength()));
sl@0
  1557
sl@0
  1558
			iTransferBufferCopy->SetInUse(EFalse);
sl@0
  1559
			}
sl@0
  1560
sl@0
  1561
		// removed checking EOF from here, it should be checked in CMMFFile
sl@0
  1562
sl@0
  1563
		REINTERPRET_CAST(MDataSink*, iSinkOrSource)->BufferFilledL(iBuffer) ; // callback to MDataSource/Sink
sl@0
  1564
		}
sl@0
  1565
	
sl@0
  1566
	iCompleted = ETrue ;
sl@0
  1567
	}
sl@0
  1568
sl@0
  1569
/* 
sl@0
  1570
 *  On completion of write request call back to the MDataSource
sl@0
  1571
 */
sl@0
  1572
void CWriteRequest::RunL() 
sl@0
  1573
	{
sl@0
  1574
	if(iTransferBufferCopy)
sl@0
  1575
		iTransferBufferCopy->SetInUse(EFalse);
sl@0
  1576
sl@0
  1577
	if (iStatus != KErrNone)
sl@0
  1578
		{
sl@0
  1579
		TMMFEvent event(KMMFErrorCategoryControllerGeneralError, iStatus.Int());
sl@0
  1580
		iEventHandler->SendEventToClient(event);
sl@0
  1581
		}
sl@0
  1582
	else
sl@0
  1583
		REINTERPRET_CAST(MDataSource*, iSinkOrSource)->BufferEmptiedL(iBuffer) ; // callback to MDataSource/Sink
sl@0
  1584
sl@0
  1585
	iCompleted = ETrue ;
sl@0
  1586
	}
sl@0
  1587
sl@0
  1588
CMMFFile::CMMFFileAsyncEventHandler::CMMFFileAsyncEventHandler(CMMFFile* aParent)
sl@0
  1589
	{
sl@0
  1590
	iParent = aParent;
sl@0
  1591
	}
sl@0
  1592
sl@0
  1593
CMMFFile::CMMFFileAsyncEventHandler::~CMMFFileAsyncEventHandler()
sl@0
  1594
	{
sl@0
  1595
	}
sl@0
  1596
sl@0
  1597
TInt CMMFFile::CMMFFileAsyncEventHandler::SendEventToClient(const TMMFEvent& aEvent)
sl@0
  1598
	{
sl@0
  1599
	if(aEvent.iErrorCode == KErrNotReady)//i.e. MMC removed while recording
sl@0
  1600
		{
sl@0
  1601
		TRAPD(err, iParent->SinkStopL() );
sl@0
  1602
		if (err != KErrNone)
sl@0
  1603
			{
sl@0
  1604
			return err;	
sl@0
  1605
			}
sl@0
  1606
		}
sl@0
  1607
	return iParent->iEventHandler->SendEventToClient(aEvent);
sl@0
  1608
	}
sl@0
  1609
sl@0
  1610
/**
sl@0
  1611
Returns access to internal CData property
sl@0
  1612
sl@0
  1613
@param aData
sl@0
  1614
       On return, set to the internal CData property used to access file for reading.
sl@0
  1615
sl@0
  1616
Returns:
sl@0
  1617
  * KErrNotReady if the file is not open/data object has not been created. 
sl@0
  1618
  * KErrNotSupported if not supported (e.g. on data sink)
sl@0
  1619
sl@0
  1620
@return Standard error code
sl@0
  1621
*/
sl@0
  1622
TInt CMMFFile::Data(ContentAccess::CData*& aData)
sl@0
  1623
	{
sl@0
  1624
	if (!iFile)
sl@0
  1625
		{
sl@0
  1626
		return KErrNotReady;
sl@0
  1627
		}
sl@0
  1628
	else
sl@0
  1629
		{
sl@0
  1630
		return iFile->Data(aData);
sl@0
  1631
		}
sl@0
  1632
	}
sl@0
  1633