webservices/wsframework/src/senmultipartutils.cpp
changeset 0 62f9d29f7211
equal deleted inserted replaced
-1:000000000000 0:62f9d29f7211
       
     1 /*
       
     2 * Copyright (c) 2006 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:        Preparation XOP message for HTTP transmission in case 
       
    15 *				 of request	and extracting BLOBs from XOP message responsed 
       
    16 *				 through HTTP channel in case of response
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 
       
    26 
       
    27 #include "senmultipartutils.h"
       
    28 
       
    29 
       
    30 
       
    31 // ======== MEMBER FUNCTIONS ========
       
    32 
       
    33 // ---------------------------------------------------------------------------
       
    34 // Serializes SoapEnvelope message in XOP message
       
    35 // ---------------------------------------------------------------------------
       
    36 //
       
    37 EXPORT_C void SenMultiPartUtils::SerializeMessageL(CSenFragmentBase& aMessage, 
       
    38                                                 RBuf8& aMultiPartMessage,
       
    39                                                 TXmlEngSerializerType aType)
       
    40     {
       
    41 	__ASSERT_ALWAYS(&aMessage, 
       
    42 	                User::Panic(KMultiPartNoRequestMessagePanicText, EMultiPartNoRequestMessage));
       
    43 	RSenDocument doc = aMessage.AsDocumentL();
       
    44     CXmlEngSerializer* serializer = CXmlEngSerializer::NewL(aType);
       
    45 	__ASSERT_ALWAYS(serializer, User::Panic(KMultiPartPanicText, KErrNotFound));
       
    46     CleanupStack::PushL(serializer);
       
    47     TXmlEngSerializationOptions options(TXmlEngSerializationOptions::KOptionIndent & TXmlEngSerializationOptions::KOptionOmitXMLDeclaration);
       
    48     serializer->SetOutput(aMultiPartMessage);	
       
    49     serializer->SetSerializationOptions(options);
       
    50     serializer->SerializeL(doc);
       
    51     CleanupStack::PopAndDestroy(serializer);
       
    52     }
       
    53 
       
    54 // ---------------------------------------------------------------------------
       
    55 // Generates random content-ID for header of XOP message and for headers of BLOBs 
       
    56 // as randomNumber@homeTime
       
    57 // @param aRootCid is ReAlloc'd, which means that any existing data is freed
       
    58 // prior the generated root cid is assinged to that buffer.
       
    59 // ---------------------------------------------------------------------------
       
    60 //
       
    61 EXPORT_C void SenMultiPartUtils::GenerateRandomRootCidL(RBuf8& aRootCid)
       
    62     {
       
    63     _LIT8(KAt, "@");
       
    64 	TTime now;
       
    65 	now.HomeTime();
       
    66 	TInt64 homeTime = now.Int64();
       
    67 	TInt64 randomNumber = Math::Random();
       
    68 	aRootCid.ReAllocL(32+KAt().Length());
       
    69 	aRootCid.AppendNum(randomNumber);
       
    70 	aRootCid.Append(KAt);
       
    71 	aRootCid.AppendNum(homeTime);
       
    72     }
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 // Generates random boundary for mime header as randomNumber
       
    76 // @param aBoundary is ReAlloc'd, which means that any existing data is freed
       
    77 // prior the generated root cid is assinged to that buffer.
       
    78 // ---------------------------------------------------------------------------
       
    79 //
       
    80 EXPORT_C void SenMultiPartUtils::GenerateRandomBoundaryL(RBuf8& aBoundary)
       
    81     {
       
    82   	TInt64 randomNumber = Math::Random();
       
    83   	aBoundary.ReAllocL(16);
       
    84 	aBoundary.AppendNum(randomNumber);
       
    85     }
       
    86 
       
    87 // ---------------------------------------------------------------------------
       
    88 // Generates MimeBoundary to separate mime parts of the message
       
    89 // as --randomNumber
       
    90 // ---------------------------------------------------------------------------
       
    91 //
       
    92 EXPORT_C void SenMultiPartUtils::BoundaryLineStartL(const RBuf8& aBoundary, RBuf8& aBoundaryStart)
       
    93 	{
       
    94 	aBoundaryStart.ReAllocL(KNewLine().Length()+KDush().Length()+aBoundary.Length());
       
    95 	aBoundaryStart.Append(KDush);
       
    96 	aBoundaryStart.Append(aBoundary);
       
    97 	aBoundaryStart.Append(KNewLine);
       
    98 	}
       
    99 
       
   100 // ---------------------------------------------------------------------------
       
   101 // Generates MimeBoundaryEnd to end the multipart message (MultiPart message)
       
   102 // as --randomNumber--
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 EXPORT_C void SenMultiPartUtils::BoundaryLineEndL(const RBuf8& aBoundary, RBuf8& aBoundaryEnd)
       
   106 	{
       
   107 	aBoundaryEnd.ReAllocL(3*KNewLine().Length()+2*KDush().Length()+aBoundary.Length());
       
   108 	aBoundaryEnd.Append(KNewLine);
       
   109 	aBoundaryEnd.Append(KNewLine);
       
   110 	aBoundaryEnd.Append(KDush);
       
   111 	aBoundaryEnd.Append(aBoundary);
       
   112 	aBoundaryEnd.Append(KDush);
       
   113 	aBoundaryEnd.Append(KNewLine);
       
   114 	}
       
   115          
       
   116 // ---------------------------------------------------------------------------
       
   117 // Creates header for root of XOP message or other multiPart message
       
   118 // The header sould be the next:
       
   119 //
       
   120 // Content-Type: application/xop+xml;
       
   121 // charset=UTF-8; 
       
   122 // type="text/xml" (for SOAP 1.1) or "application/soap+xml" (for SOAP 1.2)
       
   123 // Content-Transfer-Encoding: 8bit
       
   124 // Content-ID: <randomNumber@homeTime>
       
   125 //
       
   126 // where "Content-ID" is the same as "start" in Header of Outer Package
       
   127 // ---------------------------------------------------------------------------
       
   128 //
       
   129 EXPORT_C void SenMultiPartUtils::HeaderRootL(MSenMessage* aMessage,
       
   130 										const RBuf8& aRootCid, RBuf8& aHeaderRoot)
       
   131 	{
       
   132 	
       
   133 	if( aMessage->IsSafeToCast(MSenMessage::ESoapEnvelope2 ))
       
   134 	    {
       
   135 	    CSenSoapEnvelope2* pSoapEnvelope2 = (CSenSoapEnvelope2*)aMessage;
       
   136     	switch (pSoapEnvelope2->SoapVersion())
       
   137     		{
       
   138      		case ESOAP11:
       
   139     			{
       
   140     			aHeaderRoot.ReAllocL(KMultiPartHeaderRootStart11().Length()+KMultiPartHeaderRootEnd().Length()+aRootCid.Length());
       
   141     			aHeaderRoot.Append(KMultiPartHeaderRootStart11);
       
   142     			break;
       
   143     			}
       
   144     		case ESOAP12:
       
   145     			{
       
   146     			aHeaderRoot.ReAllocL(KMultiPartHeaderRootStart12().Length()+KMultiPartHeaderRootEnd().Length()+aRootCid.Length());
       
   147     			aHeaderRoot.Append(KMultiPartHeaderRootStart12);		
       
   148     			break;
       
   149     			}
       
   150     		default:
       
   151     			{
       
   152     			User::Panic(KMultiPartSoapVersionInvalidPanicText, EMultiPartSoapVersionInvalid);
       
   153     			}			
       
   154     		}
       
   155 	    }
       
   156 	else if( aMessage->IsSafeToCast(MSenMessage::EAtomMessage ))
       
   157 	    {
       
   158 		aHeaderRoot.ReAllocL(KMultiPartAtomHeaderRootStart().Length()+KMultiPartHeaderRootEnd().Length()+aRootCid.Length());
       
   159 		aHeaderRoot.Append(KMultiPartAtomHeaderRootStart);
       
   160 	    }
       
   161 	aHeaderRoot.Append(aRootCid);
       
   162 	aHeaderRoot.Append(KMultiPartHeaderRootEnd);
       
   163 	}
       
   164 	
       
   165 // ---------------------------------------------------------------------------
       
   166 // Creates  the header for binary data[aIndex] of XOP message
       
   167 // The header sould be the next:
       
   168 //
       
   169 // --MIME_boundary
       
   170 // Content-Type: image/png (for images) or some other type for other BLOBs
       
   171 // Content-Transfer-Encoding: binary
       
   172 // Content-ID: <randomNumber@homeTime>
       
   173 //
       
   174 // ---------------------------------------------------------------------------
       
   175 //
       
   176 EXPORT_C void SenMultiPartUtils::HeaderBinaryDataL(TUint aIndex, 
       
   177 										      RArray<TXmlEngDataContainer>& aBinaryDataList,
       
   178 			 					     	      RBuf8& aHeaderBinaryData)
       
   179 	{
       
   180 	__ASSERT_ALWAYS(aBinaryDataList.Count(), User::Panic(KMultiPartNoBlobsPanicText, EMultiPartNoBlobs)); 
       
   181 	__ASSERT_ALWAYS((aIndex < aBinaryDataList.Count()), User::Panic(KMultiPartPanicText, KErrArgument));	    
       
   182 	
       
   183 	TPtrC8 cid = aBinaryDataList[aIndex].Cid();
       
   184 	
       
   185 	RXmlEngNodeList<TXmlEngAttr> attributes; // to take value of "ContentType" attribute
       
   186 	aBinaryDataList[aIndex].ParentNode().AsElement().GetAttributes(attributes);
       
   187 	CleanupClosePushL(attributes);
       
   188 
       
   189 	RBuf8 contentType;
       
   190 	CleanupClosePushL(contentType);
       
   191 	while (attributes.HasNext())
       
   192 		{
       
   193 		TXmlEngAttr attr = attributes.Next();
       
   194 		if (attr.Name() == KMultiPartContentTypeName)
       
   195 			{
       
   196 			contentType.ReAllocL(attr.Value().Length());
       
   197 			contentType.Copy(attr.Value()); 
       
   198 			break;
       
   199 			}
       
   200 		}
       
   201     if (contentType == KNullDesC8)
       
   202         {
       
   203         contentType.ReAllocL(KMultiPartDefaultBinaryContentTypeValue().Length());
       
   204         contentType.Copy(KMultiPartDefaultBinaryContentTypeValue);
       
   205         }
       
   206 
       
   207 	
       
   208 	aHeaderBinaryData.ReAllocL(KMultiPartHeaderBinaryDataContentType().Length()+
       
   209 							   KMultiPartHeaderBinaryDataContentID().Length()+
       
   210 							   KMultiPartHeaderBinaryDataEnd().Length()+
       
   211 							   contentType.Length()+
       
   212 							   cid.Length());
       
   213 	aHeaderBinaryData.Append(KMultiPartHeaderBinaryDataContentType);
       
   214 	aHeaderBinaryData.Append(contentType);
       
   215 	aHeaderBinaryData.Append(KMultiPartHeaderBinaryDataContentID);
       
   216 	aHeaderBinaryData.Append(cid);
       
   217 	aHeaderBinaryData.Append(KMultiPartHeaderBinaryDataEnd);
       
   218 
       
   219 	CleanupStack::PopAndDestroy(&contentType);
       
   220 	CleanupStack::PopAndDestroy(&attributes);
       
   221 	}
       
   222 
       
   223 // ---------------------------------------------------------------------------
       
   224 // Extracts a part of BLOB (10KB) from a file
       
   225 // ---------------------------------------------------------------------------
       
   226 //
       
   227 EXPORT_C void SenMultiPartUtils::FileDataPartL(TUint aPart, TUint aIndex, 
       
   228 									      RArray<TXmlEngDataContainer>& aBinaryDataList,
       
   229 						       		      RBuf8& aBinaryData)
       
   230 	{
       
   231 	__ASSERT_ALWAYS(aBinaryDataList.Count(), User::Panic(KMultiPartNoBlobsPanicText, EMultiPartNoBlobs)); 
       
   232 	__ASSERT_ALWAYS((aIndex < aBinaryDataList.Count()), User::Panic(KMultiPartPanicText, KErrArgument));	    
       
   233 	
       
   234    	aBinaryData.ReAllocL(KTenKBytes);
       
   235 
       
   236 	RFile& file = aBinaryDataList[aIndex].AsFileContainer().File();
       
   237 	file.Flush();
       
   238 	file.Read(aPart*KTenKBytes, aBinaryData, KTenKBytes);
       
   239 	}
       
   240 
       
   241 // ---------------------------------------------------------------------------
       
   242 // Extracts the rest of BLOB (less than 10KB) from a file
       
   243 // ---------------------------------------------------------------------------
       
   244 //	
       
   245 EXPORT_C void SenMultiPartUtils::FileDataRestL(TUint aParts, TUint aRest, TUint aIndex, 
       
   246 									      RArray<TXmlEngDataContainer>& aBinaryDataList,
       
   247 						       		      RBuf8& aBinaryData)
       
   248 	{
       
   249 	__ASSERT_ALWAYS(aBinaryDataList.Count(), User::Panic(KMultiPartNoBlobsPanicText, EMultiPartNoBlobs)); 
       
   250 	__ASSERT_ALWAYS((aIndex < aBinaryDataList.Count()), User::Panic(KMultiPartPanicText, KErrArgument));	    
       
   251 
       
   252    	aBinaryData.ReAllocL(aRest);
       
   253 	RFile& file = aBinaryDataList[aIndex].AsFileContainer().File();
       
   254 	file.Flush();
       
   255 	file.Read(aParts*KTenKBytes, aBinaryData, aRest);
       
   256 	}
       
   257 
       
   258 // ---------------------------------------------------------------------------
       
   259 // Extracts CIDs of BLOBs from response MultiPart message
       
   260 // ---------------------------------------------------------------------------
       
   261 //	
       
   262 EXPORT_C void SenMultiPartUtils::CidL(const RBuf8& aBlobHeader, RArray<RBuf8>& aCids)
       
   263 	{
       
   264     _LIT8(KContentIDName, "Content-ID: <");
       
   265     _LIT8(KGreaterThan,">");
       
   266 	TInt offset = aBlobHeader.Find(KContentIDName);
       
   267 	if (offset == KErrNotFound)
       
   268 		{
       
   269 		User::Panic(KMultiPartNoCidPanicText, EMultiPartNoCid);
       
   270 		}
       
   271 	TPtrC8 blobHeaderPtr; // to extract BLOB header from Response message
       
   272 	blobHeaderPtr.Set(aBlobHeader.Right(aBlobHeader.Length()-offset-KContentIDName().Length()));
       
   273 		
       
   274 	offset = blobHeaderPtr.Find(KGreaterThan);//CodeScannerWarning
       
   275 	if (offset == KErrNotFound)
       
   276 		{
       
   277 		User::Panic(KMultiPartCidInvalidPanicText, EMultiPartCidInvalid);
       
   278 		}
       
   279 	RBuf8 cid; // CID of the BLOB
       
   280 	cid.ReAllocL(offset);		
       
   281 	cid.Copy(blobHeaderPtr.Left(offset));
       
   282 	aCids.AppendL(cid); // collects CIDs of all BLOBs
       
   283 	}	
       
   284 
       
   285 // ---------------------------------------------------------------------------
       
   286 // Generates the file name for BLOB of response MultiPart message 
       
   287 // and collects it in array of file names for the all BLOBs
       
   288 // ---------------------------------------------------------------------------
       
   289 //	
       
   290 void SenMultiPartUtils::FileNameL(TUint aIndex, RArray<RBuf8>& aFileNames)
       
   291 	{
       
   292 	RBuf8 fileName;
       
   293 	fileName.ReAllocL(KFileName().Length()+7);
       
   294 	fileName.Append(KFileName);
       
   295 	fileName.AppendNum(aIndex);
       
   296 	aFileNames.Append(fileName);
       
   297 	}
       
   298 
       
   299 // ---------------------------------------------------------------------------
       
   300 // Extracts BLOB from response MultiPart message and writes it in a file
       
   301 // ---------------------------------------------------------------------------
       
   302 //	
       
   303 EXPORT_C TInt SenMultiPartUtils::SetFileL(TUint aIndex, TBool aFirst, TDesC8& aBlob, 
       
   304 						             RArray<RBuf8>& aFileNames)
       
   305 	{
       
   306 	RFs rfs;
       
   307 	RFile file;
       
   308 
       
   309     User::LeaveIfError(rfs.Connect());
       
   310 	CleanupClosePushL(rfs);	
       
   311 	TInt retVal = rfs.ShareProtected();
       
   312     CleanupClosePushL(file);
       
   313     
       
   314     TInt sizeFile = 0;
       
   315     RBuf fileName; //fileName is necessary to convert from 8bites(aFileNames[aIndex]) to 16
       
   316     CleanupClosePushL(fileName);
       
   317     if (aFirst) // check if is it the first part of a BLOB to write in a file
       
   318         {
       
   319         FileNameL(aIndex, aFileNames); // generates the new file
       
   320         fileName.ReAllocL(aFileNames[aIndex].Length());
       
   321         fileName.Copy(aFileNames[aIndex]);
       
   322         User::LeaveIfError(file.Replace(rfs, fileName, EFileWrite)); // replases the old one to the new one
       
   323         }
       
   324     else // if it's not the first part of BLOB then only open the existing file and write a BLOB part in it 
       
   325         {
       
   326         fileName.ReAllocL(aFileNames[aIndex].Length());
       
   327         fileName.Copy(aFileNames[aIndex]);
       
   328         User::LeaveIfError(file.Open(rfs, fileName, EFileWrite));
       
   329         }
       
   330   
       
   331     file.Size(sizeFile);
       
   332 	User::LeaveIfError(file.Write(sizeFile, aBlob, aBlob.Length()));
       
   333     
       
   334     file.Flush();
       
   335     file.Close();
       
   336 
       
   337     User::LeaveIfError(file.Open(rfs, fileName, EFileRead));
       
   338     
       
   339     //fileName.Close();
       
   340     CleanupStack::PopAndDestroy(&fileName);
       
   341     CleanupStack::PopAndDestroy(&file);
       
   342 	CleanupStack::PopAndDestroy(&rfs);
       
   343 	return (sizeFile+aBlob.Length());
       
   344 	}
       
   345 
       
   346 // End of file
       
   347