webservices/wshttpchanneltransportplugin/src/senmultiparttxnstate.cpp
changeset 0 62f9d29f7211
equal deleted inserted replaced
-1:000000000000 0:62f9d29f7211
       
     1 /*
       
     2 * Copyright (c) 2002-2005 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:        
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 // INCLUDE FILES
       
    26 #include <http.h>
       
    27 
       
    28 #include "senmultiparttxnstate.h"
       
    29 #include "senhttpchannel.h"
       
    30 #include "sendebug.h"
       
    31 #include "senlogger.h"
       
    32 
       
    33 
       
    34 // =========================== MEMBER FUNCTIONS ===============================
       
    35 
       
    36 // ----------------------------------------------------------------------------
       
    37 // CSenMultiPartTxnState::CSenMultiPartTxnState
       
    38 // C++ default constructor can NOT contain any code, that
       
    39 // might leave.
       
    40 // ----------------------------------------------------------------------------
       
    41 //
       
    42 CSenMultiPartTxnState::CSenMultiPartTxnState(MSenResponseObserver& aObserver)
       
    43     : CSenTxnState(aObserver),
       
    44    	  iRootCid(NULL),
       
    45 	  iMimeBoundaryOut(NULL),
       
    46 	  iMimeBoundaryIn(NULL),
       
    47 	  iMimeBoundaryEndIn(NULL),
       
    48   	  iPartDataOut(1),
       
    49  	  iLastPartOut(EFalse),
       
    50    	  iPartDataIn(1),
       
    51  	  iLastPartIn(EFalse),
       
    52  	  iCurPart(EFalse),
       
    53  	  iBinaryDataEnd(ETrue),
       
    54  	  iChecked(EFalse),
       
    55  	  iBinaryDataPart(NULL),
       
    56  	  iBinaryDataParts(NULL),
       
    57  	  iBinaryDataRest(NULL),
       
    58  	  iFirst(ETrue)
       
    59     {
       
    60     }
       
    61     
       
    62 
       
    63     
       
    64 CSenMultiPartTxnState::~CSenMultiPartTxnState()
       
    65 	{
       
    66 	iMessage = NULL;
       
    67 	iBinaryDataList.Close();
       
    68 	iRootCid.Close();
       
    69 	iMimeBoundaryOut.Close();
       
    70 	iMimeBoundaryIn.Close();
       
    71 	iMimeBoundaryEndIn.Close();
       
    72     iCurrentPart.Close();
       
    73     iSoapAction.Close();
       
    74     iXopEnvelopeResponse.Close();
       
    75     iBlobHeader.Close();
       
    76     
       
    77     for(TUint i(0); i < iFileNames.Count(); ++i) // iFileNames.Count() equals iCids.Count()
       
    78         {
       
    79         iFileNames[i].Close();
       
    80         iCids[i].Close();
       
    81         }
       
    82     iFileNames.Close();
       
    83     iCids.Close();
       
    84 	}
       
    85 
       
    86 
       
    87 
       
    88 // ---------------------------------------------------------------------
       
    89 // calculates number of parts in BLOB (every part = 10KB) 
       
    90 // and how many bytes there are in the last part
       
    91 //----------------------------------------------------------------------
       
    92 //
       
    93 void CSenMultiPartTxnState::SizeBinaryData(TUint aIndex)
       
    94     {
       
    95     TUint size = iBinaryDataList[aIndex].Size();
       
    96     iBinaryDataParts = size/KTenKBytes;
       
    97     iBinaryDataRest = size%KTenKBytes;
       
    98     if (iBinaryDataParts > 0)
       
    99         {
       
   100         iBinaryDataEnd = EFalse;
       
   101         }
       
   102     }
       
   103 
       
   104 // ---------------------------------------------------------------------
       
   105 // creates header for Blob in Request
       
   106 // ---------------------------------------------------------------------
       
   107 //    
       
   108 void CSenMultiPartTxnState::BlobHeaderL()
       
   109 	{
       
   110 	// iCurrentPart == header, binary part
       
   111 	RBuf8 boundaryStart;
       
   112 	boundaryStart.CleanupClosePushL();
       
   113 	SenMultiPartUtils::BoundaryLineStartL(iMimeBoundaryOut, boundaryStart);	
       
   114 
       
   115 	TUint index = (iPartDataOut - 3)/2;
       
   116     			
       
   117 	RBuf8 headerBinaryData;
       
   118 	headerBinaryData.CleanupClosePushL();
       
   119    	SenMultiPartUtils::HeaderBinaryDataL(index, iBinaryDataList, headerBinaryData);
       
   120 
       
   121 	iCurrentPart.ReAllocL(2*KNewLine().Length()+boundaryStart.Length()+headerBinaryData.Length());
       
   122 	iCurrentPart.Append(KNewLine);
       
   123 	iCurrentPart.Append(KNewLine);
       
   124 	iCurrentPart.Append(boundaryStart);
       
   125 	iCurrentPart.Append(headerBinaryData);
       
   126 	CleanupStack::PopAndDestroy(&headerBinaryData); 
       
   127 	CleanupStack::PopAndDestroy(&boundaryStart);  
       
   128     TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMultiPartTxnState::GetNextDataPart - aDataPart (header, binary part):")));
       
   129 	iCurPart = ETrue;
       
   130 	}
       
   131 
       
   132 // ---------------------------------------------------------------------
       
   133 // for case if Blob is kept in a file 
       
   134 // this function passes Blob from a file part by part (every part = 10KB)
       
   135 // in Request
       
   136 // ---------------------------------------------------------------------
       
   137 //    
       
   138 void CSenMultiPartTxnState::FileContainerL(TUint aIndex)
       
   139     {
       
   140     if (!iChecked)
       
   141         {
       
   142     	SizeBinaryData(aIndex);
       
   143     	iChecked = ETrue;
       
   144     	}
       
   145     if (iBinaryDataPart < iBinaryDataParts) 
       
   146         {
       
   147         SenMultiPartUtils::FileDataPartL(iBinaryDataPart, aIndex, iBinaryDataList, iCurrentPart);
       
   148         }
       
   149     else if (iBinaryDataRest != 0)
       
   150         {
       
   151         SenMultiPartUtils::FileDataRestL(iBinaryDataParts, iBinaryDataRest, aIndex, iBinaryDataList, iCurrentPart);
       
   152         iBinaryDataEnd = ETrue;
       
   153         }
       
   154     iCurPart = ETrue;    
       
   155     }
       
   156 
       
   157 // ---------------------------------------------------------------------
       
   158 // creates the last part (MimeBoundaryEnd) in Request
       
   159 // ---------------------------------------------------------------------
       
   160 //    
       
   161 void CSenMultiPartTxnState::XopEndL()
       
   162 	{
       
   163 	// iCurrentPart == XOP end
       
   164 	SenMultiPartUtils::BoundaryLineEndL(iMimeBoundaryOut, iCurrentPart);	
       
   165     TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMultiPartTxnState::GetNextDataPart - aDataPart (boundary end):")));
       
   166 	iCurPart = ETrue;
       
   167 	iLastPartOut = ETrue;
       
   168 	}
       
   169 
       
   170 // ----------------------------------------------------------------------------
       
   171 // CSenMultiPartTxnState::GetNextDataPart
       
   172 // Implementation of the pure virtual method from MHTTPDataSupplier
       
   173 // ----------------------------------------------------------------------------
       
   174 //
       
   175 TBool CSenMultiPartTxnState::GetNextDataPart(TPtrC8& aDataPart)
       
   176     {
       
   177     TBool lastPart(EFalse);
       
   178     TRAP_IGNORE(lastPart = GetNextDataPartL(aDataPart));
       
   179     return lastPart;
       
   180     }
       
   181 
       
   182 // ----------------------------------------------------------------------------
       
   183 // CSenMultiPartTxnState::ReleaseData
       
   184 // Implementation of the pure virtual method from MHTTPDataSupplier
       
   185 // ----------------------------------------------------------------------------
       
   186 //
       
   187 void CSenMultiPartTxnState::ReleaseData()
       
   188 	{
       
   189     TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMultiPartTxnState::ReleaseData")));
       
   190     iCurPart = EFalse;
       
   191     iCurrentPart.Close();
       
   192 	if (!iLastPartOut)
       
   193 		{
       
   194 		// Notify HTTP of more data available immediately
       
   195 		TRAP_IGNORE(Transaction().NotifyNewRequestBodyPartL());
       
   196 		if (iBinaryDataEnd)
       
   197 		    {
       
   198     		iPartDataOut++;
       
   199 		    iChecked = EFalse;
       
   200 		    iBinaryDataPart = 0;
       
   201 		    }
       
   202 		else 
       
   203 		    {
       
   204 		    ++iBinaryDataPart;
       
   205 		    }    
       
   206 		}
       
   207 	}
       
   208 
       
   209 // ----------------------------------------------------------------------------
       
   210 // CSenMultiPartTxnState::OverallDataSize
       
   211 // Implementation of the pure virtual method from MHTTPDataSupplier
       
   212 // ----------------------------------------------------------------------------
       
   213 //
       
   214 TInt CSenMultiPartTxnState::OverallDataSize()
       
   215     {
       
   216 	return KErrNotFound;
       
   217     }
       
   218 
       
   219 
       
   220 // ----------------------------------------------------------------------------
       
   221 // CSenMultiPartTxnState::Reset
       
   222 // Implementation of the pure virtual method from MHTTPDataSupplier
       
   223 // ----------------------------------------------------------------------------
       
   224 //
       
   225 TInt CSenMultiPartTxnState::Reset()
       
   226     {
       
   227     TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMultiPartTxnState::Reset")));
       
   228 	return KErrNone;
       
   229     }
       
   230 
       
   231 // ---------------------------------------------------------------------------
       
   232 // parses Response from server (MultiPart message) and extracts MimeBoundary part
       
   233 // and MimeBoundaryEnd part
       
   234 // ---------------------------------------------------------------------------
       
   235 //
       
   236 void CSenMultiPartTxnState::MimeBoundaryInL(TPtrC8& aDataPartPtr, TInt& aOffset, TInt& aOffset1)
       
   237     {
       
   238     _LIT8(KDDash,"--");
       
   239     aOffset = aDataPartPtr.Find(KDDash); 	//CodeScannerWarnings
       
   240     if (aOffset == KErrNotFound)
       
   241         {
       
   242         User::Panic(KMultiPartResponseBodyInvalidPanicText, SenMultiPartUtils::EMultiPartResponseBodyInvalid);
       
   243         }
       
   244     aDataPartPtr.Set(aDataPartPtr.Right(aDataPartPtr.Length()-aOffset));
       
   245     aOffset = aDataPartPtr.Find(_L8("\r\n")); 
       
   246 
       
   247     iMimeBoundaryIn.ReAllocL(aOffset);
       
   248     iMimeBoundaryIn.Copy(aDataPartPtr.Left(aOffset));
       
   249 
       
   250     iMimeBoundaryEndIn.ReAllocL(aOffset+2);
       
   251     iMimeBoundaryEndIn.Append(iMimeBoundaryIn);
       
   252     iMimeBoundaryEndIn.Append(KDDash);
       
   253         
       
   254     aDataPartPtr.Set(aDataPartPtr.Right(aDataPartPtr.Length()-aOffset-2));
       
   255 
       
   256     aOffset = aDataPartPtr.Find(_L8("\r\n\r\n"));
       
   257     aOffset1 = aDataPartPtr.Find(iMimeBoundaryEndIn);
       
   258     if (aOffset1 != KErrNotFound)
       
   259         {
       
   260         iLastPartIn = ETrue;
       
   261         }
       
   262     if (aOffset != KErrNotFound) 
       
   263         {
       
   264         aDataPartPtr.Set(aDataPartPtr.Right(aDataPartPtr.Length()-aOffset-4));
       
   265         iPartDataIn++;
       
   266         }
       
   267     }
       
   268 
       
   269 // ---------------------------------------------------------------------------
       
   270 // parses Response from server (MultiPart message) and extracts XopEnvelope part
       
   271 // ---------------------------------------------------------------------------
       
   272 //
       
   273 void CSenMultiPartTxnState::XopEnvelopeResponseL(TPtrC8& aDataPartPtr, TInt& aOffset, TInt& aOffset1)    
       
   274     {
       
   275     aOffset = aDataPartPtr.Find(iMimeBoundaryIn);
       
   276     aOffset1 = aDataPartPtr.Find(iMimeBoundaryEndIn);
       
   277     if (aOffset1 != KErrNotFound)
       
   278         {
       
   279         iLastPartIn = ETrue; 
       
   280         }
       
   281     if (aOffset == KErrNotFound) 
       
   282         {
       
   283         iXopEnvelopeResponse.ReAllocL(iXopEnvelopeResponse.Length()+aDataPartPtr.Length());
       
   284         iXopEnvelopeResponse.Append(aDataPartPtr);
       
   285         }
       
   286     else
       
   287         {
       
   288         iXopEnvelopeResponse.ReAllocL(iXopEnvelopeResponse.Length()+aOffset-4);
       
   289         iXopEnvelopeResponse.Append(aDataPartPtr.Left(aOffset-4));
       
   290         aDataPartPtr.Set(aDataPartPtr.Right(aDataPartPtr.Length()-aOffset));
       
   291         iPartDataIn++;
       
   292         iObserver->FileProgress(iId, ETrue, ETrue,
       
   293                     iXopEnvelopeResponse, iXopEnvelopeResponse.Length());    
       
   294         }
       
   295     }
       
   296 
       
   297 // ---------------------------------------------------------------------------
       
   298 // parses Response from server (MultiPart message) and extracts header of Blob part
       
   299 // ---------------------------------------------------------------------------
       
   300 //
       
   301 void CSenMultiPartTxnState::BlobHeaderResponseL(TPtrC8& aDataPartPtr, TInt& aOffset, TInt& aOffset1) 
       
   302     {
       
   303     aOffset = aDataPartPtr.Find(_L8("\r\n\r\n"));
       
   304     aOffset1 = aDataPartPtr.Find(iMimeBoundaryEndIn);
       
   305     
       
   306     if (aOffset1 != KErrNotFound)
       
   307         {
       
   308         iLastPartIn = ETrue;
       
   309         }
       
   310     if (aOffset == KErrNotFound)
       
   311         {
       
   312         iBlobHeader.ReAllocL(iBlobHeader.Length()+aDataPartPtr.Length());
       
   313         iBlobHeader.Append(aDataPartPtr);
       
   314         }
       
   315     else
       
   316         {
       
   317         iBlobHeader.ReAllocL(iBlobHeader.Length()+aOffset);
       
   318         iBlobHeader.Append(aDataPartPtr.Left(aOffset));
       
   319 
       
   320         // extract cids
       
   321         SenMultiPartUtils::CidL(iBlobHeader, iCids);
       
   322 
       
   323         iBlobHeader.Close();
       
   324         
       
   325         aDataPartPtr.Set(aDataPartPtr.Right(aDataPartPtr.Length()-aOffset-4));
       
   326         iPartDataIn++;
       
   327         }
       
   328     }  
       
   329     
       
   330 // ---------------------------------------------------------------------------
       
   331 // parses Response from server (MultiPart message) and extracts Blob part
       
   332 // puts it in the file
       
   333 // ---------------------------------------------------------------------------
       
   334 //
       
   335 void CSenMultiPartTxnState::BlobResponseL(TPtrC8& aDataPartPtr, TInt& aOffset, TInt& aOffset1)
       
   336     {
       
   337     TInt size(0);
       
   338     aOffset = aDataPartPtr.Find(iMimeBoundaryIn);
       
   339     aOffset1 = aDataPartPtr.Find(iMimeBoundaryEndIn);
       
   340     if (aOffset1 != KErrNotFound)
       
   341         {
       
   342         iLastPartIn = ETrue;
       
   343         }
       
   344     TUint index = (iPartDataIn-4)/2;
       
   345 
       
   346     if (aOffset == KErrNotFound)
       
   347         {
       
   348         size = SenMultiPartUtils::SetFileL(index, iFirst, aDataPartPtr, iFileNames);
       
   349         iFirst = EFalse;
       
   350         }
       
   351     else
       
   352         {
       
   353         TPtrC8 blobPartPtr;
       
   354         blobPartPtr.Set(aDataPartPtr.Left(aOffset-4));
       
   355         size = SenMultiPartUtils::SetFileL(index, iFirst, blobPartPtr, iFileNames);
       
   356         aDataPartPtr.Set(aDataPartPtr.Right(aDataPartPtr.Length()-aOffset));
       
   357         iFirst = ETrue;
       
   358         iPartDataIn++;
       
   359         }
       
   360     iObserver->FileProgress(iId, ETrue, EFalse, iCids[index], size); 
       
   361     }      
       
   362 
       
   363 // ---------------------------------------------------------------------------
       
   364 // parses Response from server (MultiPart message) 
       
   365 // ---------------------------------------------------------------------------
       
   366 //
       
   367 void CSenMultiPartTxnState::ParseMultiPartResponseL(TDesC8& aDataPart)
       
   368     {
       
   369     TPtrC8 dataPartPtr;
       
   370 	dataPartPtr.Set(aDataPart);
       
   371 
       
   372     TInt offset(0);
       
   373     TInt offset1(-1);
       
   374     if (!iLastPartIn)
       
   375         {
       
   376         while ((dataPartPtr.Length()) && (offset != offset1))
       
   377             {
       
   378             if (iPartDataIn == 1)
       
   379 	            {
       
   380 	            MimeBoundaryInL(dataPartPtr, offset, offset1);
       
   381 	            }
       
   382 	        else if (iPartDataIn == 2)
       
   383    		        {
       
   384    		        XopEnvelopeResponseL(dataPartPtr, offset, offset1);
       
   385 	            }
       
   386 	        else if ((iPartDataIn > 2) && (iPartDataIn%2 != 0))
       
   387 	            {
       
   388    		        BlobHeaderResponseL(dataPartPtr, offset, offset1);
       
   389   		        }
       
   390    	        else if ((iPartDataIn > 2) && (iPartDataIn%2 == 0))
       
   391    		        {
       
   392    		        BlobResponseL(dataPartPtr, offset, offset1);
       
   393    		        }
       
   394             }
       
   395         }
       
   396      }
       
   397 
       
   398 // -----------------------------------------------------------------------------
       
   399 // added HttpTransportProperties about Cids of Blobs and File namess, 
       
   400 // where Blobs are kept
       
   401 // and passes transport properties and XopEnvelope to an observer
       
   402 //------------------------------------------------------------------------------
       
   403 //
       
   404 void CSenMultiPartTxnState::ResponseReceivedL(const SenMultiPartUtils::TMultiPartContentType& aMultiPartContentType)
       
   405     {
       
   406     TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenMultiPartTxnState(%d)::ResponseReceivedL"), iId));
       
   407     TLSLOG_L(KSenHttpChannelLogChannelBase , KMaxLogLevel,"iXopEnvelopeResponse:");
       
   408     TLSLOG_ALL(KSenHttpChannelLogChannelBase , KMaxLogLevel,(iXopEnvelopeResponse));
       
   409 
       
   410 
       
   411     if(iXopEnvelopeResponse.Length())
       
   412         {
       
   413 		CSenHttpTransportProperties* pHttpProperties = CSenHttpTransportProperties::NewLC();
       
   414 															
       
   415 		pHttpProperties->SetDownloadFolderL(KDownloadFolder);
       
   416 		for (TUint i=0; i < iCids.Count(); ++i)
       
   417 			{
       
   418 			pHttpProperties->SetFileAttachmentL(iCids[i], iFileNames[i]);
       
   419 			}
       
   420         HBufC8* pResponse = iXopEnvelopeResponse.AllocL();
       
   421         // delete allocated body
       
   422         iXopEnvelopeResponse.Close();  
       
   423         iObserver->ResponseReceivedL(iId, &aMultiPartContentType, pResponse, pHttpProperties);
       
   424        	CleanupStack::PopAndDestroy(pHttpProperties);
       
   425         }
       
   426     else
       
   427         {
       
   428         TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"Fatal: NULL response received in MultiPartTxnState!");
       
   429         // delete allocated body
       
   430         iXopEnvelopeResponse.Close();  
       
   431         }
       
   432 
       
   433     }
       
   434 // ---------------------------------------------------------------------
       
   435 // creates header for SoapEnvelope in Request
       
   436 // ---------------------------------------------------------------------
       
   437 //    
       
   438 void CSenMultiPartTxnState::MessageHeaderL()
       
   439     {
       
   440     RBuf8 boundaryStart;
       
   441     boundaryStart.CleanupClosePushL();
       
   442 
       
   443     // Note: BoundaryLineStart re-allocates (and first de-allocates) boundaryStart
       
   444     SenMultiPartUtils::BoundaryLineStartL(iMimeBoundaryOut, boundaryStart);	
       
   445 
       
   446     RBuf8 headerRoot;
       
   447     headerRoot.CleanupClosePushL();
       
   448 
       
   449     // Note: HeaderRootL re-allocates (and first de-allocates) iRootCid
       
   450     SenMultiPartUtils::HeaderRootL(iMessage, iRootCid, headerRoot);
       
   451     		
       
   452     // iCurrentPart == header root:
       
   453     iCurrentPart.ReAllocL(boundaryStart.Length()+headerRoot.Length());
       
   454     iCurrentPart.Append(boundaryStart);
       
   455     iCurrentPart.Append(headerRoot);
       
   456     CleanupStack::PopAndDestroy(&headerRoot); 
       
   457     CleanupStack::PopAndDestroy(&boundaryStart); 
       
   458     TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMultiPartTxnState::MessageHeaderL")));
       
   459     iCurPart = ETrue; 
       
   460     }
       
   461 
       
   462 // ---------------------------------------------------------------------
       
   463 // creates SoapEnvelope in Request
       
   464 // ---------------------------------------------------------------------
       
   465 //    
       
   466 void CSenMultiPartTxnState::MessageL()
       
   467     {
       
   468     }
       
   469 
       
   470 
       
   471 // ----------------------------------------------------------------------------
       
   472 // creates Request for MultiPart message in MultiPart format 
       
   473 // should be used to send MultiPart message through HTTP Channel
       
   474 // ----------------------------------------------------------------------------
       
   475 //
       
   476 TBool CSenMultiPartTxnState::GetNextDataPartL(TPtrC8& aDataPart)
       
   477     {
       
   478     TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMtomTxnState::GetNextDataPart")));
       
   479 
       
   480 	if(!HasRequestBody())
       
   481 		{
       
   482 		iLastPartOut = ETrue;
       
   483 		iPartDataOut = 0;
       
   484 		}	
       
   485 	else 
       
   486 	    {
       
   487 	    if(!iCurPart) // Note: this is zero only when new part is requested
       
   488       		{
       
   489     		if ((iPartDataOut == 1) && (iPartDataOut < iCountDataParts))
       
   490     		    {
       
   491     		    MessageHeaderL(); // First part of MultiPart message = header of SoapEnvelope
       
   492     		    }
       
   493     		else if ((iPartDataOut == 2) && (iPartDataOut < iCountDataParts))
       
   494     		    {
       
   495     		    MessageL(); // Second part of MultiPart message = SoapEnvelope
       
   496     		    }
       
   497     		else if ((iPartDataOut > 2) && (iPartDataOut%2 != 0) && (iPartDataOut < iCountDataParts))
       
   498     		    {
       
   499     		    BlobHeaderL(); // Third and then all odd parts = headers of Blobs 
       
   500     		    }
       
   501     		else if ((iPartDataOut > 2) && (iPartDataOut%2 == 0) && (iPartDataOut < iCountDataParts))
       
   502     			{
       
   503     			TUint index = (iPartDataOut - 4)/2;
       
   504     			
       
   505     			switch (iBinaryDataList[index].NodeType()) // Fourth and then all even parts = Blobs
       
   506 		            {
       
   507      		        case TXmlEngNode::EChunkContainer: // blob is kept in Chunk
       
   508     			        {
       
   509     		            TInt offset = iBinaryDataList[index].AsChunkContainer().ChunkOffset();
       
   510    			            aDataPart.Set(iBinaryDataList[index].AsChunkContainer().Chunk().Base()+offset,iBinaryDataList[index].Size());
       
   511      		            TLSLOG_ALL(KSenHttpChannelLogChannelBase , KMaxLogLevel,aDataPart); 
       
   512     		            iBinaryDataEnd = ETrue;
       
   513      		            return iLastPartOut;
       
   514     			        }
       
   515  	
       
   516  		            case TXmlEngNode::EFileContainer: // blob is kept in File
       
   517    			            {
       
   518                         FileContainerL(index);
       
   519     			        break;
       
   520     			        }
       
   521       	
       
   522  	                case TXmlEngNode::EBinaryContainer: // blob is kept as binary data
       
   523     			        {
       
   524 	     		        aDataPart.Set(iBinaryDataList[index].AsBinaryContainer().Contents()); 
       
   525 	     		        return iLastPartOut;
       
   526     			        }
       
   527     	
       
   528  	            	default:
       
   529  			            {
       
   530                     	User::Panic(KMultiPartBlobContainerTypeInvalidPanicText, 
       
   531                     	            SenMultiPartUtils::EMultiPartBlobContainerTypeInvalid); 			            }
       
   532  		                }
       
   533 
       
   534      			TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenMtomTxnState::GetNextDataPart - aDataPart (binary data)"))); 
       
   535                 if (iBinaryDataPart)
       
   536                     {
       
   537                     iObserver->FileProgress(iId, EFalse, EFalse,
       
   538                                 iBinaryDataList[index].Cid(), iBinaryDataPart*KTenKBytes);
       
   539                     }
       
   540     			}
       
   541     		else if (iPartDataOut == iCountDataParts)
       
   542     		    {
       
   543     		    TUint index = (iPartDataOut - 4)/2;
       
   544     		    XopEndL(); // The last part of MultiPart message = MimeBoundaryEnd
       
   545     		    if ((iPartDataOut > 2) && (iPartDataOut%2 == 0))
       
   546     		        {
       
   547     		        iObserver->FileProgress(iId, EFalse, EFalse,
       
   548                                 iBinaryDataList[index].Cid(), iBinaryDataList[index].Size());
       
   549     		        }
       
   550         		    
       
   551     		    }
       
   552     		} // on first call, allocate the current part
       
   553 	    aDataPart.Set(iCurrentPart); // .. otherwise, just re-use it
       
   554         TLSLOG_ALL(KSenHttpChannelLogChannelBase , KMaxLogLevel,aDataPart); 
       
   555         }
       
   556 	return iLastPartOut;	
       
   557     }
       
   558 
       
   559 //  End of File