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