messagingfw/msgsrvnstore/server/src/MCLOPERT.CPP
changeset 0 8e480a14352b
equal deleted inserted replaced
-1:000000000000 0:8e480a14352b
       
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <s32std.h>
       
    17 
       
    18 #include "MSVAPI.H"
       
    19 #include "MSVCOP.H"
       
    20 #include "MSVPANIC.H"
       
    21 #include <tmsvsystemprogress.h>
       
    22 
       
    23 //**********************************
       
    24 // CMsvOperation
       
    25 //**********************************
       
    26 
       
    27 EXPORT_C CMsvOperation::CMsvOperation(CMsvSession& aMsvSession, TInt aPriority, TRequestStatus& aObserverRequestStatus)
       
    28 : CActive(aPriority), iObserverRequestStatus(aObserverRequestStatus), iMsvSession(aMsvSession)
       
    29 //
       
    30 //
       
    31 //
       
    32 /** Constructor. This is called by MTM implementers from the derived class constructor. 
       
    33 
       
    34 CMsvOperation-derived objects are not created by message client applications. The constructor uses the 
       
    35 CMsvSession object to obtain a ID for the operation. This ID can be accessed by clients through Id(). 
       
    36 
       
    37 aPriority is the priority used by the active object. Typically, this is EPriorityStandard.
       
    38 
       
    39 aObserverRequestStatus is the asynchronous status object of an active object provided by the caller. 
       
    40 The derived class is required to signal the caller through this when the operation completes. 
       
    41 It is stored by the constructor in the iObserverRequestStatus member.
       
    42 @param aMsvSession Session object 
       
    43 @param aPriority Active object priority 
       
    44 @param aObserverRequestStatus  Request status of operation observer
       
    45  */
       
    46 	{
       
    47 	__DECLARE_NAME(_S("CMsvOperation"));
       
    48 	iId = iMsvSession.OperationId();
       
    49 	}
       
    50 
       
    51 
       
    52 EXPORT_C CMsvOperation::~CMsvOperation()
       
    53 /** Destructor.
       
    54 
       
    55 This base class function takes no action. Derived classes should implement 
       
    56 a destructor to do the clean up tasks that they require. Minimally, they should 
       
    57 call Cancel() to cancel any outstanding request. */
       
    58 	{}
       
    59 
       
    60 EXPORT_C const TDesC8& CMsvOperation::FinalProgress()
       
    61 /** Gets information about a completed operation. 
       
    62 
       
    63 Unlike ProgressL(), this is guaranteed to provide status information reflecting 
       
    64 the outcome of a completed operation.
       
    65 
       
    66 Requirements:
       
    67 
       
    68 The default implementation of this function returns the result from ProgressL(). 
       
    69 If the operation is active or ProgressL() leaves, a panic occurs. 
       
    70 
       
    71 A derived class should implement the function to meet the requirement to provide 
       
    72 appropriate final status information. Typically, on active object completion, 
       
    73 it will store progress information in a private member, and return that stored 
       
    74 information from this function.
       
    75 
       
    76 @return Descriptor holding progress information
       
    77 @panic MSGS 285 Operation is active
       
    78 @panic MSGS 286 Could not get final progress information, as ProgressL() left.
       
    79 */
       
    80 	{	
       
    81 	__ASSERT_ALWAYS(!IsActive(), PanicServer(EMsvActiveInFinalProgress));
       
    82 	const TDesC8* progress = &KNullDesC8();
       
    83 	TRAPD(leave, progress = &ProgressL());
       
    84 	__ASSERT_ALWAYS(leave == KErrNone, PanicServer(EMsvFinalProgressFailed));
       
    85 	return *progress;
       
    86 	}
       
    87 
       
    88 EXPORT_C TUid CMsvOperation::Mtm() const
       
    89 /** Gets the UID of the MTM associated with the operation.
       
    90 
       
    91 This UID can be used to determine the appropriate method of getting information 
       
    92 from a progress descriptor. 
       
    93 
       
    94 The default implementation returns iMtm.
       
    95 
       
    96 @return The UID of the MTM associated with the operation 
       
    97 @see ProgressL() */
       
    98  	{
       
    99  	return iMtm;
       
   100  	} 
       
   101 
       
   102 /** This call leads to calling SystemProgress() in the server to populate the
       
   103 TMsvSystemProgress structure.
       
   104 @param aOutSysProg The TMsvSystemProgress structure to be populated by the server
       
   105 @return the error of the Extension_ method call
       
   106 */
       
   107 EXPORT_C TInt CMsvOperation::SystemProgress(TMsvSystemProgress& aOutSysProg)
       
   108 	{
       
   109 	TAny* ptrNull = NULL;
       
   110 	return Extension_(KUIDMsgMsvSystemProgress, ptrNull, &aOutSysProg);
       
   111 	}
       
   112 
       
   113 /** The extension method provides a polymorphic behaviour to call the correct
       
   114 SystemProgress function.
       
   115 @param aExtensionId The Uid passed in as KUIDMsgMsvSystemProgress to obtain the
       
   116 System Progress.
       
   117 @return KErrExtensionNotSupported retuned if no Extension_ function is overriddden
       
   118 by the derived class.
       
   119 */
       
   120 EXPORT_C TInt CMsvOperation::Extension_(TUint aExtensionId, TAny *&a0, TAny *a1)	
       
   121 	{
       
   122 	TInt ret = KErrNone;
       
   123 	switch(aExtensionId)
       
   124 		{
       
   125 		case KUIDMsgMsvSystemProgress:
       
   126 			{
       
   127 			ret = KErrExtensionNotSupported;
       
   128 			}
       
   129 			break;
       
   130 		default:
       
   131 			{
       
   132 		// Chain to base class
       
   133 			ret = CActive::Extension_(aExtensionId, a0, a1);
       
   134 			}
       
   135 			break;
       
   136 		}
       
   137 	return ret;
       
   138 	}
       
   139 
       
   140 //**********************************
       
   141 // CMsvEntryOperation
       
   142 //**********************************
       
   143 
       
   144 CMsvEntryOperation* CMsvEntryOperation::NewL(CMsvSession& aMsvSession, TRequestStatus& aObserverRequestStatus)
       
   145 //
       
   146 //
       
   147 //
       
   148 	{
       
   149 	CMsvEntryOperation* self = CMsvEntryOperation::NewLC(aMsvSession, aObserverRequestStatus);
       
   150 	CleanupStack::Pop();
       
   151 	return self;
       
   152 	}
       
   153 
       
   154 CMsvEntryOperation* CMsvEntryOperation::NewLC(CMsvSession& aMsvSession, TRequestStatus& aObserverRequestStatus)
       
   155 //
       
   156 //
       
   157 //
       
   158 	{
       
   159 	CMsvEntryOperation* self = new(ELeave) CMsvEntryOperation(aMsvSession, aObserverRequestStatus);
       
   160 	CleanupStack::PushL(self);
       
   161 	self->ConstructL();
       
   162 	return self;
       
   163 	}
       
   164 
       
   165 
       
   166 CMsvEntryOperation::CMsvEntryOperation(CMsvSession& aMsvSession, TRequestStatus& aObserverRequestStatus)
       
   167 : CMsvOperation(aMsvSession, EPriorityStandard, aObserverRequestStatus)
       
   168 //
       
   169 //
       
   170 //
       
   171 	{
       
   172 	__DECLARE_NAME(_S("CMsvEntryOperation"));
       
   173 	}
       
   174 
       
   175 
       
   176 CMsvEntryOperation::~CMsvEntryOperation()
       
   177 //
       
   178 //
       
   179 //
       
   180 	{
       
   181 	Cancel();
       
   182 	delete iProgress;
       
   183 	}
       
   184 
       
   185 
       
   186 void CMsvEntryOperation::ConstructL()
       
   187 //
       
   188 //
       
   189 //
       
   190 	{
       
   191 	iProgress = HBufC8::NewL(KMsvProgressBufferLength);
       
   192 	CActiveScheduler::Add(this);
       
   193 	}
       
   194 
       
   195 
       
   196 
       
   197 void CMsvEntryOperation::DoCancel()
       
   198 //
       
   199 //
       
   200 //
       
   201 	{
       
   202 	TPtr8 des = iProgress->Des();
       
   203 	iMsvSession.Session().CancelOperation(Id(), des); // error ignored
       
   204 
       
   205 	// signal the observer that the operation has completed
       
   206 	TRequestStatus* status = &iObserverRequestStatus;
       
   207 	User::RequestComplete(status, KErrCancel);
       
   208 	}
       
   209 
       
   210 
       
   211 void CMsvEntryOperation::RunL()
       
   212 //
       
   213 //
       
   214 //
       
   215 	{
       
   216 	// get the final Msv system progress from the server
       
   217 	iErrorGetSystemProgress = iMsvSession.Session().OperationSystemProgress(Id(), iSystemProgress);
       
   218 	
       
   219 	// get the final progress from the server
       
   220 	TPtr8 des = iProgress->Des();
       
   221 	TInt length=des.Length();
       
   222 	TInt error = iMsvSession.Session().OperationCompletion(Id(), des); 
       
   223 	if (error)
       
   224 		des.SetLength(length);
       
   225 
       
   226 	// signal the observer that the operation has completed
       
   227 	TRequestStatus* status = &iObserverRequestStatus;
       
   228 
       
   229 	// If there is no operation then complete with our status
       
   230 	// Otherwise complete with the operation completion error
       
   231 
       
   232 	if (error == KErrNotFound && iStatus.Int())
       
   233 		User::RequestComplete(status, iStatus.Int());
       
   234 	else
       
   235 		User::RequestComplete(status, error ? error : iStatus.Int());
       
   236 	}
       
   237 
       
   238 const TDesC8& CMsvEntryOperation::ProgressL()
       
   239 //
       
   240 //
       
   241 //
       
   242 	{
       
   243 	if (IsActive())
       
   244 		{
       
   245 		TPtr8 des = iProgress->Des();
       
   246 		User::LeaveIfError(iMsvSession.Session().OperationProgress(Id(), des));
       
   247 		}
       
   248 	return *iProgress;
       
   249 	}
       
   250 
       
   251 /** The extension method provides a polymorphic behaviour to get the TMsvSystemProgress
       
   252 structure in one of the Operations.
       
   253 @param aExtensionId The Uid passed in as KUIDMsgMsvSystemProgress to obtain the
       
   254 System Progress.
       
   255 @return error from the call of DoGetSystemProgress() method.
       
   256 */
       
   257 EXPORT_C TInt CMsvEntryOperation::Extension_(TUint aExtensionId, TAny *&a0, TAny *a1)
       
   258 	{
       
   259 	if (aExtensionId == KUIDMsgMsvSystemProgress)
       
   260 		{
       
   261 		TMsvSystemProgress* systemProgress = reinterpret_cast<TMsvSystemProgress*>(a1);
       
   262 		return DoGetSystemProgress(*systemProgress);
       
   263 		}
       
   264 	
       
   265 	// Chain to base class
       
   266 	return CMsvOperation::Extension_(aExtensionId, a0, a1);
       
   267 	}
       
   268 
       
   269 /** This function calls the session which eventually goes to SystemProgress() in the server
       
   270 to populate the TMsvSystemProgress structure.
       
   271 @param aOutSysProg The TMsvSystemProgress structure to be populated by the server
       
   272 @return the error from the SystemProgress() call.
       
   273 */
       
   274 TInt CMsvEntryOperation::DoGetSystemProgress(TMsvSystemProgress& aOutSysProg)
       
   275 	{
       
   276 	TInt err = KErrNone;
       
   277 	// use RMsvSession
       
   278 	if (IsActive())
       
   279 		{
       
   280 		err = iMsvSession.Session().OperationSystemProgress(Id(), aOutSysProg);
       
   281 		}
       
   282 	else
       
   283 		{
       
   284 		aOutSysProg = iSystemProgress;
       
   285 		err = iErrorGetSystemProgress;
       
   286 		}
       
   287 	return err;
       
   288 	}
       
   289 
       
   290 const TDesC8& CMsvEntryOperation::FinalProgress()
       
   291 	{
       
   292 	__ASSERT_ALWAYS(!IsActive(), PanicServer(EMsvActiveInFinalProgress));
       
   293 	return *iProgress;
       
   294 	}
       
   295 
       
   296 
       
   297 void CMsvEntryOperation::Start()
       
   298 //
       
   299 //
       
   300 //
       
   301 	{
       
   302 	iObserverRequestStatus=KRequestPending;
       
   303 	SetActive();
       
   304 	}
       
   305 
       
   306 //**********************************
       
   307 // CMsvOperationWait
       
   308 //**********************************
       
   309 
       
   310 // static 
       
   311 /** Allocates and constructs a new CMsvOperationWait object.
       
   312 
       
   313 The new object is added to the active scheduler and left on
       
   314 the cleanup stack.
       
   315 
       
   316 @param aPriority Active object priority. It has a default value of 
       
   317 EPriorityStandard.
       
   318 @return New CMsvOperationWait object
       
   319 @leave KErrNoMemory
       
   320 */
       
   321 EXPORT_C CMsvOperationWait* CMsvOperationWait::NewLC(TInt aPriority)
       
   322 	{
       
   323 	CMsvOperationWait* self = new (ELeave) CMsvOperationWait(aPriority);
       
   324 	CleanupStack::PushL(self);
       
   325 	return self;
       
   326 	}
       
   327 
       
   328 /** Constructor.
       
   329 
       
   330 @param aPriority Active object priority
       
   331 */
       
   332 CMsvOperationWait::CMsvOperationWait(TInt aPriority)
       
   333 : CActive(aPriority)
       
   334 	{
       
   335 	CActiveScheduler::Add(this);
       
   336 	}
       
   337 
       
   338 /** Destructor.
       
   339 
       
   340 Any active request on the object is cancelled.
       
   341 */
       
   342 EXPORT_C CMsvOperationWait::~CMsvOperationWait()
       
   343 	{
       
   344 	Cancel();
       
   345 	}
       
   346 
       
   347 /** Sets the object to be active.
       
   348 
       
   349 */
       
   350 EXPORT_C void CMsvOperationWait::Start()
       
   351 	{
       
   352 	iStatus = KRequestPending;
       
   353 	SetActive();
       
   354 	}
       
   355 
       
   356 /** Handles a request completion event.
       
   357 
       
   358 The function stops the current active scheduler.
       
   359 
       
   360 @see CActive::RunL()
       
   361 */
       
   362 void CMsvOperationWait::RunL()
       
   363 	{
       
   364 	CActiveScheduler::Stop();
       
   365 	}
       
   366 
       
   367 /** Implements cancellation of an outstanding request.
       
   368 
       
   369 @see CActive::DoCancel()
       
   370 */
       
   371 void CMsvOperationWait::DoCancel()
       
   372 	{
       
   373 	TRequestStatus* s=&iStatus;
       
   374 	User::RequestComplete(s, KErrCancel);
       
   375 	}
       
   376 
       
   377 
       
   378 //**********************************
       
   379 // CMsvOperationActiveSchedulerWait
       
   380 //**********************************
       
   381 
       
   382 // static 
       
   383 /** Allocates and constructs a new CMsvOperationActiveSchedulerWait object.
       
   384 
       
   385 The new object is added to the active scheduler and left on
       
   386 the cleanup stack.
       
   387 
       
   388 @param aPriority Active object priority. It has a default value of 
       
   389 EPriorityStandard.
       
   390 @return New CMsvOperationActiveSchedulerWait object
       
   391 @leave KErrNoMemory
       
   392 */
       
   393 EXPORT_C CMsvOperationActiveSchedulerWait* CMsvOperationActiveSchedulerWait::NewLC(TInt aPriority)
       
   394 	{
       
   395 	CMsvOperationActiveSchedulerWait* self = new (ELeave) CMsvOperationActiveSchedulerWait(aPriority);
       
   396 	CleanupStack::PushL(self);
       
   397 	return self;
       
   398 	}
       
   399 
       
   400 /** Constructor.
       
   401 
       
   402 @param aPriority Active object priority
       
   403 */
       
   404 CMsvOperationActiveSchedulerWait::CMsvOperationActiveSchedulerWait(TInt aPriority)
       
   405 : CActive(aPriority)
       
   406 	{
       
   407 	CActiveScheduler::Add(this);
       
   408 	}
       
   409 
       
   410 /** Destructor.
       
   411 
       
   412 Any active request on the object is cancelled.
       
   413 */
       
   414 EXPORT_C CMsvOperationActiveSchedulerWait::~CMsvOperationActiveSchedulerWait()
       
   415 	{
       
   416 	Cancel();
       
   417 	}
       
   418 
       
   419 /** Sets the object to be active, and wait until the request is completed.
       
   420 */
       
   421 EXPORT_C void CMsvOperationActiveSchedulerWait::Start()
       
   422 	{
       
   423 	SetActive();
       
   424 	iActiveSchedulerWait.Start();	//Re-enter the active scheduler--execution halts here until RunL is called
       
   425 	}
       
   426 
       
   427 /** Handles a request completion event.
       
   428 
       
   429 The function stops the object waiting, and allows the program to resume execution after the Start() function call.
       
   430 
       
   431 @see CActive::RunL()
       
   432 */
       
   433 void CMsvOperationActiveSchedulerWait::RunL()
       
   434 	{
       
   435 	iActiveSchedulerWait.AsyncStop();	//Exit current scheduler loop, resuming execution of the Start() function
       
   436 	}
       
   437 
       
   438 /** Implements cancellation of an outstanding request.
       
   439 
       
   440 @see CActive::DoCancel()
       
   441 */
       
   442 void CMsvOperationActiveSchedulerWait::DoCancel()
       
   443 	{
       
   444 	TRequestStatus* s=&iStatus;
       
   445 	User::RequestComplete(s, KErrCancel);
       
   446 	}
       
   447 
       
   448 //**********************************
       
   449 // CMsvCompletedOperation
       
   450 //**********************************
       
   451 
       
   452 // static
       
   453 /** Allocates and constructs a new CMsvCompletedOperation object.
       
   454 
       
   455 The new object is added to the active scheduler and its asynchronous request 
       
   456 immediately set to complete.
       
   457 
       
   458 @param aSession Message Server session to use
       
   459 @param aMtm The UID of the MTM associated with the operation. 
       
   460 @param aProgress Operation progress information buffer. This is copied by the object.
       
   461 @param aService The ID of the service that is associated with this operation. 
       
   462 @param aObserverRequestStatus Request status of the operation observer. This 
       
   463 observer is signalled that the operation is complete. 
       
   464 @param aError Error code with which to complete the request. Use KErrNone to 
       
   465 indicate that the operation completed successfully. 
       
   466 
       
   467 @return New CMsvOperationActiveSchedulerWait object
       
   468 @leave KErrNoMemory
       
   469 */
       
   470 EXPORT_C CMsvCompletedOperation* CMsvCompletedOperation::NewL(CMsvSession& aSession, TUid aMtm, const TDesC8& aProgress, TMsvId aService, TRequestStatus& aObserverRequestStatus, TInt aError)
       
   471 	{
       
   472 	CMsvCompletedOperation* self = new (ELeave) CMsvCompletedOperation(aSession, aObserverRequestStatus);
       
   473 	CleanupStack::PushL(self);
       
   474 	self->ConstructL(aMtm, aError, aProgress, aService);
       
   475 	CleanupStack::Pop();
       
   476 	return self;
       
   477 	}
       
   478 
       
   479 CMsvCompletedOperation::CMsvCompletedOperation(CMsvSession& aSession, TRequestStatus& aObserverRequestStatus)
       
   480 : CMsvOperation(aSession, EPriorityStandard, aObserverRequestStatus) 
       
   481 	{
       
   482 	__DECLARE_NAME(_S("CMsvCompletedOperation"));
       
   483 	}
       
   484 
       
   485 /** Destructor.
       
   486 
       
   487 Any active request on the object is cancelled.
       
   488 */
       
   489 EXPORT_C CMsvCompletedOperation::~CMsvCompletedOperation()
       
   490 	{
       
   491 	Cancel();
       
   492 	delete iProgress;
       
   493 	}
       
   494 
       
   495 void CMsvCompletedOperation::ConstructL(TUid aMtm, TInt aError, const TDesC8& aProgress, TMsvId aService)
       
   496 	{
       
   497 	iProgress = HBufC8::NewL(aProgress.Length());
       
   498 	*iProgress = aProgress;
       
   499 	iMtm=aMtm;
       
   500 	iService=aService;
       
   501 	//
       
   502 	CActiveScheduler::Add(this);
       
   503 	iStatus = KRequestPending;
       
   504 	SetActive();
       
   505 	//
       
   506 	TRequestStatus* pstat=&iStatus;
       
   507 	User::RequestComplete(pstat, aError);
       
   508 	iObserverRequestStatus = KRequestPending;
       
   509 	}
       
   510 
       
   511 /** Gets information on the progress of the operation.
       
   512 
       
   513 For a CMsvCompletedOperation, the progress information returned by 
       
   514 ProgressL() and FinalProgress() is the same, and is the progress 
       
   515 information set in the NewL() function. 
       
   516  
       
   517 @return Descriptor holding progress information.
       
   518 @see CMsvOperation::ProgressL()
       
   519 */
       
   520 const TDesC8& CMsvCompletedOperation::ProgressL()
       
   521 	{
       
   522 	return *iProgress;
       
   523 	}
       
   524 
       
   525 /** Gets information about a completed operation. 
       
   526 @return Descriptor holding progress information.
       
   527 @see CMsvOperation::FinalProgress()
       
   528 */
       
   529 const TDesC8& CMsvCompletedOperation::FinalProgress()
       
   530 	{
       
   531 	__ASSERT_ALWAYS(!IsActive(), PanicServer(EMsvActiveInFinalProgress));
       
   532 	return *iProgress;
       
   533 	}
       
   534 
       
   535 void CMsvCompletedOperation::DoCancel()
       
   536 	{
       
   537 	TRequestStatus* pstat=&iObserverRequestStatus;
       
   538 	User::RequestComplete(pstat, iStatus.Int());
       
   539 	}
       
   540 
       
   541 void CMsvCompletedOperation::RunL()
       
   542 	{
       
   543 	TRequestStatus* pstat=&iObserverRequestStatus;
       
   544 	User::RequestComplete(pstat, iStatus.Int());
       
   545 	}
       
   546 
       
   547 
       
   548 //**********************************
       
   549 // CMsvSendOperation
       
   550 //**********************************
       
   551 
       
   552 /** Constructor.
       
   553 
       
   554 @param aSession Message Server session to use
       
   555 @param aObserverRequestStatus Request status of the operation observer. This 
       
   556 
       
   557 @return New CMsvSendOperation object
       
   558 @leave KErrNoMemory
       
   559 */
       
   560 EXPORT_C CMsvSendOperation::CMsvSendOperation(CMsvSession& aMsvSession, TRequestStatus& aObserverRequestStatus) :
       
   561 	CMsvOperation(aMsvSession, CActive::EPriorityStandard, aObserverRequestStatus)
       
   562 	{
       
   563 	iObserverRequestStatus = KRequestPending;
       
   564 	CActiveScheduler::Add(this);
       
   565 	}
       
   566 	
       
   567 /** 
       
   568 Takes ownership of a CMsvOperation object that is set to complete iStatus of this object.
       
   569 This implementation does not leave.
       
   570 
       
   571 @param anOperation CMsvOperation object
       
   572 */
       
   573 EXPORT_C void CMsvSendOperation::Start(CMsvOperation* aOperation)
       
   574 	{
       
   575 	iOperation = aOperation;
       
   576 	iMtm = iOperation->Mtm();
       
   577 	iService = iOperation->Service();
       
   578 	SetActive();
       
   579 	}
       
   580 	
       
   581 /** Destructor.
       
   582 
       
   583 Any active request on the object is cancelled.
       
   584 */
       
   585 EXPORT_C CMsvSendOperation::~CMsvSendOperation()
       
   586 	{
       
   587 	Cancel();
       
   588 	delete iOperation;
       
   589 	}
       
   590 
       
   591 /** Gets progress information about the current send operation
       
   592 
       
   593 Returns the translated progress for the current send operation. Calls the underlying
       
   594 ProgressL function to obtain the native progress then calls TranslateProgressL to 
       
   595 translate the native progress into standard send progress. 
       
   596 
       
   597 @return Descriptor holding progress information
       
   598 */
       
   599 EXPORT_C const TDesC8& CMsvSendOperation::ProgressL()
       
   600 	{ 
       
   601 	return TranslateProgress(iOperation->ProgressL()); 
       
   602 	}
       
   603 
       
   604 /** Gets information about a completed operation. 
       
   605 
       
   606 Returns the translated progress for the current send operation. Calls the sending 
       
   607 operation's FinalProgress function to obtain the native progress then calls 
       
   608 TranslateProgressL to translate the native progress into standard send progress. 
       
   609 
       
   610 @return Descriptor holding progress information
       
   611 */
       
   612 EXPORT_C const TDesC8& CMsvSendOperation::FinalProgress()
       
   613 	{ 
       
   614 	return TranslateProgress(iOperation->FinalProgress()); 
       
   615 	}
       
   616 
       
   617 /** 
       
   618 Called when this operation is cancelled and is active. It in turn cancels the
       
   619 sending operation and completes iObserverRequestStatus with KErrCancel. 
       
   620 */
       
   621 EXPORT_C void CMsvSendOperation::DoCancel()
       
   622 	{
       
   623 	iOperation->Cancel();
       
   624 	Complete(KErrCancel);
       
   625 	}
       
   626 
       
   627 /**
       
   628 Called on completion of sending operation. Completes iObserverRequestStatus
       
   629 with the sending operation's status. This RunL does not leave. 
       
   630 */
       
   631 EXPORT_C void CMsvSendOperation::RunL()
       
   632 	{
       
   633 	iProgress().iError = iStatus.Int();
       
   634 	Complete(iStatus.Int());
       
   635 	}
       
   636 
       
   637 void CMsvSendOperation::Complete(TInt anError)
       
   638 	{
       
   639 	TRequestStatus* stat = &iObserverRequestStatus;
       
   640 	User::RequestComplete(stat, anError);
       
   641 	}
       
   642