xml/xmldomandxpath/src/xmlengineserializer/xmlengserializerxop.cpp
changeset 0 e35f40988205
equal deleted inserted replaced
-1:000000000000 0:e35f40988205
       
     1 // Copyright (c) 2006-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 // Implementation of XOP serializer
       
    15 //
       
    16 
       
    17 #include <e32math.h>
       
    18 #include <badesca.h>
       
    19 
       
    20 #include "xmlengserializerxop.h"
       
    21 #include <xml/dom/xmlengerrors.h>
       
    22 #include <xml/dom/xmlengdom.h>
       
    23 #include "xmlengdomdefs.h"
       
    24 #include <xml/dom/xmlengnode.h>
       
    25 #include <xml/dom/xmlengdatacontainer.h>
       
    26 #include <xml/dom/xmlengbinarycontainer.h>
       
    27 #include <stdapis/libxml2/libxml2_tree.h>
       
    28 #include "xmlengxopfileoutputstream.h"
       
    29 #include "xmlengxopproxyoutputstream.h"
       
    30 #include <xml/dom/xmlengserializeerrors.h>
       
    31 
       
    32 #include <bsul/clientmessage.h>
       
    33 
       
    34 _LIT8(KStartTag, "<");
       
    35 // _LIT8(KCloseTag, "/>");
       
    36 _LIT8(KXOPInclude, "xop:Include xmlns:xop=\"http://www.w3.org/2004/08/xop/include\"");
       
    37 _LIT8(KXOPDocumentStart, "MIME-Version: 1.0\nContent-Type: Multipart/Related;boundary=MIME_boundary;\ntype=\"application/xop+xml\";\nstart=\"<root@nokia.com>\";\n\n");
       
    38 _LIT8(KMimeRoot, "--MIME_boundary\nContent-ID: <root@nokia.com>\n\n");    
       
    39 _LIT8(KMimeHeaderStart, "\n\n--MIME_boundary\n");
       
    40 _LIT8(KMimeHeaderContentType, "Content-Type: ");
       
    41 _LIT8(KMimeHeaderContentIdStart, "Content-ID: <");
       
    42 _LIT8(KMimeHeaderContentIdEnd, ">\n");
       
    43 // _LIT8(KMimeHeaderEnd, "\n\n");  
       
    44 _LIT8(KXOPDocumentEnd, "\n--MIME_boundary--");
       
    45 _LIT8(KInclude, "Include");
       
    46 _LIT8(KXOPUri, "http://www.w3.org/2004/08/xop/include");
       
    47 _LIT8(KNewLine, "\n");
       
    48 _LIT8(KColon, ":");
       
    49 _LIT8(KHrefStart, " href=\"cid:");
       
    50 _LIT8(KHrefEnd, "\"/>");
       
    51 
       
    52 // --------------------------------------------------------------------------------------
       
    53 // Constructor
       
    54 // --------------------------------------------------------------------------------------
       
    55 //
       
    56 EXPORT_C CXmlEngSerializerXOP* CXmlEngSerializerXOP::NewL( TBool aCleanXOPInfoset )
       
    57 	{
       
    58 	CXmlEngSerializerXOP* serializerXop = new (ELeave) CXmlEngSerializerXOP( aCleanXOPInfoset );
       
    59 	CleanupStack::PushL( serializerXop ); 
       
    60 	serializerXop->ConstructL();
       
    61 	CleanupStack::Pop(); //serializerXop
       
    62 	return serializerXop;
       
    63 	}
       
    64 
       
    65 // --------------------------------------------------------------------------------------
       
    66 // Serializes TXmlEngNode
       
    67 // --------------------------------------------------------------------------------------
       
    68 //
       
    69 TInt CXmlEngSerializerXOP::SerializeL(const TXmlEngNode aRoot)
       
    70     {
       
    71     TXmlEngSerializationOptions* defPtr = NULL;
       
    72     TXmlEngSerializationOptions def = TXmlEngSerializationOptions();
       
    73     if(iSerializationOptions )
       
    74     	{
       
    75     	defPtr = iSerializationOptions;
       
    76     	}
       
    77     else
       
    78         {
       
    79         defPtr = &def;
       
    80         }
       
    81 
       
    82 	switch(iSerializationOutput)
       
    83 		{
       
    84 		case ESerializeToFile:
       
    85 			{
       
    86 		    if (!iOutFileName)
       
    87 		        {
       
    88 		        User::Leave(KXmlEngErrNoParameters);
       
    89 		        } 			
       
    90 			return SerializeL(iOutFileName->Des(), aRoot, *defPtr);
       
    91 			}
       
    92 		case ESerializeToBuffer:
       
    93 			{
       
    94 			return SerializeL(*iBuffer, aRoot, *defPtr);
       
    95 			}
       
    96 		case ESerializeToStream:
       
    97 			{
       
    98 			TXmlEngSXOPProxyOutputStream stream = TXmlEngSXOPProxyOutputStream(*iOutputStream);
       
    99 			return StreamSerializeL(stream, aRoot, *defPtr); 
       
   100 			}
       
   101 		default: 
       
   102 			{
       
   103 			User::Leave(KErrNotSupported);
       
   104 			} 
       
   105 		}
       
   106 	return 0;
       
   107     }
       
   108 // --------------------------------------------------------------------------------------
       
   109 // Serializes TXmlEngNode to file
       
   110 // --------------------------------------------------------------------------------------
       
   111 //
       
   112 TInt CXmlEngSerializerXOP::SerializeL(const TDesC& aFileName,
       
   113                                    const TXmlEngNode aRoot,
       
   114                                    const TXmlEngSerializationOptions& aOptions)
       
   115     {
       
   116 	iRFs.Close();
       
   117 	User::LeaveIfError(iRFs.Connect());
       
   118 	return SerializeL(iRFs, aFileName, aRoot, aOptions);  
       
   119     }
       
   120 
       
   121 // --------------------------------------------------------------------------------------
       
   122 // Serializes TXmlEngNode to file
       
   123 // --------------------------------------------------------------------------------------
       
   124 //
       
   125 TInt CXmlEngSerializerXOP::SerializeL(RFs& aRFs,
       
   126 								   const TDesC& aFileName, 
       
   127 								   const TXmlEngNode aRoot,									
       
   128 	 						  	   const TXmlEngSerializationOptions& aOptions)
       
   129     { 
       
   130 	User::LeaveIfError( iOutputFile.Replace(aRFs, aFileName, EFileWrite) );    
       
   131  	TXmlEngSXOPFileOutputStream fileStream = TXmlEngSXOPFileOutputStream(iOutputFile, aRFs);
       
   132 	return StreamSerializeL(fileStream, aRoot, aOptions);  
       
   133     }
       
   134 
       
   135 // --------------------------------------------------------------------------------------
       
   136 // Serializes TXmlEngNode to a given type of stream (file or stream)
       
   137 // --------------------------------------------------------------------------------------
       
   138 //
       
   139 TInt CXmlEngSerializerXOP::StreamSerializeL(MXmlEngSXOPOutputStream& aOutputStream, 
       
   140 											const TXmlEngNode aRoot,
       
   141 											const TXmlEngSerializationOptions& aOptions)
       
   142     {
       
   143 	LeaveIfXopIncludeL(aRoot);
       
   144     iDataContainerArray.Reset();
       
   145     if(aOptions.iDataSerializer)
       
   146     	{
       
   147     	return aRoot.OwnerDocument().SaveL(aOutputStream, aRoot, aOptions);
       
   148     	}
       
   149 
       
   150 	iTmpOutputStream = &aOutputStream;
       
   151 	iDataWritten = 0;
       
   152 
       
   153 	if( !iCleanXOPInfoset )		
       
   154 		{
       
   155 		BufferedWriteL(KXOPDocumentStart, ETrue);
       
   156 		BufferedWriteL(KMimeRoot, ETrue);					
       
   157 		}
       
   158 	    	
       
   159 	TXmlEngSerializationOptions opt = aOptions;
       
   160 	opt.iDataSerializer = this;
       
   161 
       
   162 	iDataWritten += aRoot.OwnerDocument().SaveL(aOutputStream, aRoot, opt);
       
   163 
       
   164 	if( !iCleanXOPInfoset )		
       
   165 		{  
       
   166 		for( TInt i = 0; i < iDataContainerArray.Count(); i++ )	
       
   167 			{	
       
   168 			BufferedWriteL(KMimeHeaderStart);
       
   169 			TPtrC8 contentTypeStr;
       
   170 			if(GetContentTypeValue(iDataContainerArray[i], contentTypeStr))
       
   171 				{	
       
   172 				BufferedWriteL(KMimeHeaderContentType);
       
   173 				BufferedWriteL(contentTypeStr);
       
   174 				BufferedWriteL(KNewLine);
       
   175 				}
       
   176 			BufferedWriteL(KMimeHeaderContentIdStart);
       
   177 			BufferedWriteL(iDataContainerArray[i].Cid());
       
   178 			BufferedWriteL(KMimeHeaderContentIdEnd);
       
   179 			BufferedWriteL(KNewLine);
       
   180 			switch(iDataContainerArray[i].NodeType())
       
   181 				{
       
   182 				case TXmlEngNode::EBinaryContainer:
       
   183 					{
       
   184 					if(opt.iOptions & TXmlEngSerializationOptions::KOptionDecodeBinaryContainers)	
       
   185 						{
       
   186 						HBufC8* decodedData = CreateDecodedBufLC(
       
   187 							iDataContainerArray[i].AsBinaryContainer().Contents());
       
   188 						BufferedWriteL(decodedData->Des());
       
   189 						CleanupStack::PopAndDestroy(); //decodedData
       
   190 						}
       
   191 					else
       
   192 						{
       
   193 						BufferedWriteL(iDataContainerArray[i].AsBinaryContainer().Contents());														
       
   194 						}
       
   195 					break;
       
   196 					}
       
   197 				case TXmlEngNode::EChunkContainer:
       
   198 					{
       
   199 					TPtrC8 data = TPtrC8(
       
   200 						((RChunk&)iDataContainerArray[i].AsChunkContainer().Chunk()).Base()
       
   201 						+ iDataContainerArray[i].AsChunkContainer().ChunkOffset(),
       
   202 						iDataContainerArray[i].AsChunkContainer().Size());
       
   203 					if(opt.iOptions & TXmlEngSerializationOptions::KOptionDecodeBinaryContainers)	
       
   204 						{						
       
   205 						HBufC8* decodedData = CreateDecodedBufLC(data);					
       
   206 						BufferedWriteL(decodedData->Des());
       
   207 						CleanupStack::PopAndDestroy(); //decodedData
       
   208 						}
       
   209 					else
       
   210 						{
       
   211 						BufferedWriteL(data);
       
   212 						}
       
   213 					break;
       
   214 					}
       
   215 				case TXmlEngNode::EFileContainer:
       
   216 					{
       
   217 					TInt size = iDataContainerArray[i].AsFileContainer().Size();
       
   218 					HBufC8* data = HBufC8::NewLC(size);
       
   219 					TPtr8 dataPtr = data->Des();
       
   220 					iDataContainerArray[i].AsFileContainer().File().Read(dataPtr, size);
       
   221 					if(opt.iOptions & TXmlEngSerializationOptions::KOptionDecodeBinaryContainers )	
       
   222 						{
       
   223 						HBufC8* decodedData = CreateDecodedBufLC(dataPtr);
       
   224 						BufferedWriteL(decodedData->Des());
       
   225 						CleanupStack::PopAndDestroy(); //decodedData							
       
   226 						}
       
   227 					else
       
   228 						{
       
   229 						BufferedWriteL(dataPtr);
       
   230 						}
       
   231 					CleanupStack::PopAndDestroy(); //data					
       
   232 					break;
       
   233 					}														
       
   234 				}			
       
   235 			}
       
   236 		BufferedWriteL(KXOPDocumentEnd);
       
   237 		} //if( !iCleanXOPInfoset )	
       
   238 	CommitWriteL();	
       
   239 	return iDataWritten;
       
   240     }     
       
   241 
       
   242 // --------------------------------------------------------------------------------------
       
   243 // Serializes TXmlEngNode to buffer
       
   244 // --------------------------------------------------------------------------------------
       
   245 //
       
   246 TInt CXmlEngSerializerXOP::SerializeL( RBuf8& aBuffer, 
       
   247                                     const TXmlEngNode aRoot, 
       
   248 									const TXmlEngSerializationOptions& aOptions )
       
   249     {
       
   250     if(aBuffer.Length())
       
   251         {
       
   252         aBuffer.Close();
       
   253         }
       
   254 	LeaveIfXopIncludeL(aRoot);
       
   255     iDataContainerArray.Reset();	    
       
   256     if(aOptions.iDataSerializer)
       
   257     	{
       
   258     	return CXmlEngSerializer::SerializeL(aBuffer, aRoot, aOptions);
       
   259     	}    
       
   260     	
       
   261 	TXmlEngSerializationOptions opt = aOptions;
       
   262 	opt.iDataSerializer = this;
       
   263 			
       
   264 	RBuf8 xopDocument;
       
   265 	CleanupClosePushL(xopDocument);
       
   266 	aRoot.OwnerDocument().SaveL(xopDocument, aRoot, opt);
       
   267 
       
   268 	if( iCleanXOPInfoset )		
       
   269 		{
       
   270 		if(xopDocument.Size() > aBuffer.MaxSize())
       
   271 		    {
       
   272 		    aBuffer.ReAllocL( xopDocument.Size() );
       
   273 		    }
       
   274 		aBuffer.Append(xopDocument);		
       
   275 		}
       
   276 	else		
       
   277 		{    
       
   278 	    // adjust buffer size
       
   279 		TInt bufSize = KXOPDocumentStart().Size() 
       
   280 					+ KMimeRoot().Size() 
       
   281 					+ xopDocument.Size()
       
   282 					+ KXOPDocumentEnd().Size();
       
   283 		for(TInt j = 0; j < iDataContainerArray.Count(); j++)	
       
   284 			{
       
   285 			TPtrC8 contentTypeStr;
       
   286 			if(GetContentTypeValue(iDataContainerArray[j], contentTypeStr))
       
   287 				{
       
   288 				bufSize += KMimeHeaderContentType().Size() 
       
   289 						+ contentTypeStr.Size() 
       
   290 						+ KNewLine().Size();					
       
   291 				}
       
   292 			bufSize += KMimeHeaderStart().Size() 
       
   293 					+ KMimeHeaderContentIdStart().Size()
       
   294 					+ iDataContainerArray[j].Cid().Length()
       
   295 					+ KMimeHeaderContentIdEnd().Size()
       
   296 					+ KNewLine().Size()
       
   297 					+ iDataContainerArray[j].Size(); 
       
   298 			}
       
   299 		if (bufSize > aBuffer.MaxSize())
       
   300 		    {
       
   301 		    aBuffer.ReAllocL( bufSize );
       
   302 		    }
       
   303 		    
       
   304 		// write to buffer
       
   305 		aBuffer.Append(KXOPDocumentStart());
       
   306 		aBuffer.Append(KMimeRoot());
       
   307 		aBuffer.Append(xopDocument);
       
   308 		for(TInt i = 0; i < iDataContainerArray.Count(); i++)	
       
   309 			{
       
   310 			aBuffer.Append(KMimeHeaderStart);
       
   311 			TPtrC8 contentTypeStr;
       
   312 			if(GetContentTypeValue(iDataContainerArray[i], contentTypeStr))
       
   313 				{	
       
   314 				aBuffer.Append(KMimeHeaderContentType);
       
   315 				aBuffer.Append(contentTypeStr);
       
   316 				aBuffer.Append(KNewLine);
       
   317 				}
       
   318 			aBuffer.Append(KMimeHeaderContentIdStart);				
       
   319 			aBuffer.Append(iDataContainerArray[i].Cid());
       
   320 			aBuffer.Append(KMimeHeaderContentIdEnd);
       
   321 			aBuffer.Append(KNewLine);	
       
   322 			switch(iDataContainerArray[i].NodeType())
       
   323 				{
       
   324 				case TXmlEngNode::EBinaryContainer:
       
   325 					{
       
   326 					if(opt.iOptions & TXmlEngSerializationOptions::KOptionDecodeBinaryContainers )	
       
   327 						{						
       
   328 						HBufC8* decodedData = CreateDecodedBufLC(iDataContainerArray[i].AsBinaryContainer().Contents());
       
   329 						aBuffer.Append(decodedData->Des());
       
   330 						CleanupStack::PopAndDestroy(); //decodedData
       
   331 						}
       
   332 					else
       
   333 						{
       
   334 						aBuffer.Append(iDataContainerArray[i].AsBinaryContainer().Contents());							
       
   335 						}
       
   336 					break;
       
   337 					}
       
   338 				case TXmlEngNode::EChunkContainer:
       
   339 					{
       
   340 					TPtrC8 data = TPtrC8(
       
   341 						((RChunk&)iDataContainerArray[i].AsChunkContainer().Chunk()).Base()
       
   342 						+ iDataContainerArray[i].AsChunkContainer().ChunkOffset(),
       
   343 						iDataContainerArray[i].AsChunkContainer().Size());
       
   344 					if(opt.iOptions & TXmlEngSerializationOptions::KOptionDecodeBinaryContainers )	
       
   345 						{							
       
   346 						HBufC8* decodedData = CreateDecodedBufLC(data); 
       
   347 						aBuffer.Append(decodedData->Des());
       
   348 						CleanupStack::PopAndDestroy(); //decodedData
       
   349 						}
       
   350 					else
       
   351 						{
       
   352 						aBuffer.Append(data);							
       
   353 						}
       
   354 					break;
       
   355 					}
       
   356 				case TXmlEngNode::EFileContainer:
       
   357 					{
       
   358 					TInt size = iDataContainerArray[i].AsFileContainer().Size();
       
   359 					HBufC8* data = HBufC8::NewLC(size);
       
   360 					TPtr8 dataPtr = data->Des();
       
   361 					iDataContainerArray[i].AsFileContainer().File().Read(dataPtr, size);
       
   362 					if(opt.iOptions & TXmlEngSerializationOptions::KOptionDecodeBinaryContainers )	
       
   363 						{
       
   364 						HBufC8* decodedData = CreateDecodedBufLC(dataPtr); 
       
   365 						aBuffer.Append(decodedData->Des());
       
   366 						CleanupStack::PopAndDestroy(); //decodedData							
       
   367 						}
       
   368 					else
       
   369 						{
       
   370 						aBuffer.Append(dataPtr);
       
   371 						}
       
   372 					CleanupStack::PopAndDestroy(); //data
       
   373 					break;
       
   374 					}														
       
   375 				}						
       
   376 			}
       
   377 		aBuffer.Append(KXOPDocumentEnd);
       
   378 		}
       
   379 	CleanupStack::PopAndDestroy(); //xopDocument
       
   380 	return aBuffer.Size(); 
       
   381     }
       
   382       
       
   383 // --------------------------------------------------------------------------------------
       
   384 // Determines how binary data should be serialized
       
   385 // --------------------------------------------------------------------------------------
       
   386 //
       
   387 TPtrC8 CXmlEngSerializerXOP::SerializeDataL(TXmlEngNode aNode)
       
   388     {
       
   389 	User::LeaveIfError(iDataContainerArray.Append(aNode.AsDataContainer()));
       
   390 	iXopStubPtr->Zero();
       
   391 	iXopStubPtr->Append(KStartTag);
       
   392 	TXmlEngNamespace xopNs = aNode.AsElement().LookupNamespaceByUriL(KXOPUri);
       
   393 	if(xopNs.IsNull())
       
   394 		{
       
   395 		iXopStubPtr->Append(KXOPInclude);
       
   396 		}
       
   397 	else
       
   398 		{
       
   399 		iXopStubPtr->Append(xopNs.Prefix());
       
   400 		iXopStubPtr->Append(KColon);
       
   401 		iXopStubPtr->Append(KInclude);
       
   402 		}
       
   403 	iXopStubPtr->Append(KHrefStart);	
       
   404 	iXopStubPtr->Append(aNode.AsDataContainer().Cid());
       
   405 	iXopStubPtr->Append(KHrefEnd);
       
   406 	iXopStubPtr->ZeroTerminate();
       
   407 	return *iXopStubPtr;
       
   408     }
       
   409    
       
   410 // --------------------------------------------------------------------------------------
       
   411 // Constructor
       
   412 // --------------------------------------------------------------------------------------
       
   413 //
       
   414 CXmlEngSerializerXOP::CXmlEngSerializerXOP( TBool aCleanXOPInfoset ) : 
       
   415 	iCleanXOPInfoset(aCleanXOPInfoset)
       
   416     {   
       
   417     }
       
   418 
       
   419 // --------------------------------------------------------------------------------------
       
   420 // Second phase constructor
       
   421 // --------------------------------------------------------------------------------------
       
   422 //
       
   423 void CXmlEngSerializerXOP::ConstructL()
       
   424     { 
       
   425     //create stub buffer
       
   426     iXopStub = HBufC8::NewL(KXopStubMaxSize);
       
   427     iXopStubPtr = new ( ELeave ) TPtr8(iXopStub->Des());
       
   428     //create output buffer
       
   429     iOutputBuffer = HBufC8::NewL(KInitBufferSize);
       
   430     iOutputBufferPtr = new ( ELeave ) TPtr8(iOutputBuffer->Des());
       
   431 
       
   432     }
       
   433         
       
   434 // --------------------------------------------------------------------------------------
       
   435 // Destructor
       
   436 // --------------------------------------------------------------------------------------
       
   437 //
       
   438 CXmlEngSerializerXOP::~CXmlEngSerializerXOP()
       
   439     {
       
   440 	iDataContainerArray.Close();
       
   441 	iRFs.Close();
       
   442    	delete iXopStub;	
       
   443     delete iXopStubPtr;	
       
   444    	delete iOutputBuffer;	
       
   445    	delete iOutputBufferPtr;
       
   446     }
       
   447 
       
   448 // --------------------------------------------------------------------------------------
       
   449 // Leaves if a DOM tree contains 'Include' elements from XOP 
       
   450 // namespace 'http://www.w3.org/2004/08/xop/include'
       
   451 // --------------------------------------------------------------------------------------
       
   452 //
       
   453 void CXmlEngSerializerXOP::LeaveIfXopIncludeL(TXmlEngNode aRoot)
       
   454 	{
       
   455 	if(aRoot.NodeType() == XML_DOCUMENT_NODE)
       
   456 		{
       
   457 	    if(HasXopInclude(aRoot.OwnerDocument().DocumentElement()))
       
   458 	    	{
       
   459 	    	User::Leave(KXmlEngErrBadInfoset);
       
   460 	    	}		
       
   461 		}
       
   462 	else if(HasXopInclude(aRoot))
       
   463 	    {
       
   464 	    User::Leave(KXmlEngErrBadInfoset);
       
   465 	    }	
       
   466 	}
       
   467 
       
   468 // --------------------------------------------------------------------------------------
       
   469 // Verifies if a DOM tree contains 'Include' elements from XOP 
       
   470 // namespace 'http://www.w3.org/2004/08/xop/include'
       
   471 // --------------------------------------------------------------------------------------
       
   472 //
       
   473 TBool CXmlEngSerializerXOP::HasXopInclude(TXmlEngNode aRoot)
       
   474 	{
       
   475 	if(aRoot.NodeType() == XML_ELEMENT_NODE)
       
   476 		{
       
   477 		if(	aRoot.NamespaceDeclaration().NotNull() && 
       
   478 			aRoot.Name().Compare(KInclude) == 0 && 
       
   479 			aRoot.NamespaceUri().Compare(KXOPUri) == 0 )
       
   480 			{
       
   481 			return ETrue;
       
   482 			}
       
   483 		if(aRoot.HasChildNodes())
       
   484 			{
       
   485 			RXmlEngNodeList<TXmlEngNode> childList;
       
   486 			aRoot.GetChildNodes(childList);
       
   487 			while(childList.HasNext())
       
   488 				{
       
   489 				if(HasXopInclude(childList.Next()))
       
   490 					return ETrue;				
       
   491 				} 
       
   492 			}
       
   493 		}
       
   494 	return EFalse;
       
   495 	}
       
   496 	
       
   497 // --------------------------------------------------------------------------------------
       
   498 // Verifies if container's parent node has xmlmime:contentType 
       
   499 // attribute information item. If found, the function returns ETrue 
       
   500 // and xmlmime:contentType attribute value. Otherwise, function
       
   501 // returns EFalse and aContentType is undefined.
       
   502 // --------------------------------------------------------------------------------------
       
   503 //
       
   504 TBool CXmlEngSerializerXOP::GetContentTypeValue(TXmlEngDataContainer aContainer, TPtrC8& aContentType)
       
   505 	{
       
   506 	_LIT8(KMimeNsUri, "http://www.w3.org/2004/11/xmlmime");
       
   507 	_LIT8(KContentTypeName, "contentType");
       
   508 	
       
   509 	TXmlEngElement parent = aContainer.ParentNode().AsElement();
       
   510 	if(parent.HasAttributes())
       
   511 		{
       
   512 		RXmlEngNodeList<TXmlEngAttr> attrList;
       
   513 		parent.GetAttributes(attrList);
       
   514 		for(TInt i = 0; i < attrList.Count(); i++)
       
   515 			{
       
   516 			TXmlEngAttr attr = attrList.Next();
       
   517 			if(attr.Name().Compare(KContentTypeName) == 0 
       
   518 				&& attr.NamespaceUri().Compare(KMimeNsUri) == 0)
       
   519 				{
       
   520 				aContentType.Set(attr.Value());
       
   521 				return ETrue;
       
   522 				}
       
   523 			}
       
   524 		}
       
   525 	return EFalse;
       
   526 	}
       
   527 
       
   528 // --------------------------------------------------------------------------------------
       
   529 // Decodes input data from base64 to binary octets and creates
       
   530 // heap buffer with the decoded data. The buffer is pushed on the cleanup stack.
       
   531 // --------------------------------------------------------------------------------------
       
   532 //
       
   533 HBufC8* CXmlEngSerializerXOP::CreateDecodedBufLC(TPtrC8 aEncodedData)
       
   534 	{
       
   535 	// The decoded length of base64 is about half (use same) encoded length
       
   536 	HBufC8* decodedData = HBufC8::NewLC(aEncodedData.Size());
       
   537 	TPtr8 decodedDataPtr = decodedData->Des();
       
   538 	// Decode the base64 Content-Transfer-Encoding
       
   539 	using namespace BSUL;
       
   540 	Base64Codec::Decode(aEncodedData, decodedDataPtr);
       
   541 	if(decodedDataPtr.Length() == 0)
       
   542 		{
       
   543 		User::Leave(KXmlEngErrDecodingFailed);
       
   544 		}
       
   545 	return decodedData;	
       
   546 	}
       
   547 
       
   548 // --------------------------------------------------------------------------------------
       
   549 // Appends given string to output buffer. If the serializer's 
       
   550 // output type is file, the output buffer is released to the output stream 
       
   551 // after reaching a specified threshold and the output buffer is cleared.
       
   552 // --------------------------------------------------------------------------------------
       
   553 //
       
   554 void CXmlEngSerializerXOP::BufferedWriteL(const TDesC8& aString, TBool aFlush)
       
   555 	{
       
   556 	if(aFlush)
       
   557 		{
       
   558 		if(iOutputBufferPtr->Size() > 0)
       
   559 			{
       
   560 			if( iTmpOutputStream->Write(iOutputBuffer->Des()) == -1)
       
   561 				{
       
   562 				User::Leave(iTmpOutputStream->CheckError());
       
   563 				}
       
   564 			iOutputBufferPtr->Delete(0, iOutputBufferPtr->Size());							
       
   565 			}
       
   566 		if( iTmpOutputStream->Write(aString) == -1)
       
   567 			{
       
   568 			User::Leave(iTmpOutputStream->CheckError());
       
   569 			}												
       
   570 		iDataWritten += aString.Size();
       
   571 		return;			
       
   572 		}
       
   573 
       
   574 	// first, check if data is in the buffer and added string will not fit
       
   575 	// -> flush buffer
       
   576 	if(iOutputBufferPtr->Size() > 0 &&
       
   577 	   iOutputBufferPtr->Size() + aString.Size() > iOutputBufferPtr->MaxSize())
       
   578 		{
       
   579 		if( iTmpOutputStream->Write(iOutputBuffer->Des()) == -1)
       
   580 			{
       
   581 			User::Leave(iTmpOutputStream->CheckError());
       
   582 			}
       
   583 		iOutputBufferPtr->Delete(0, iOutputBufferPtr->Size());
       
   584 		}
       
   585 	// if string alone doesn't fit in the buffer -> save string
       
   586 	if(aString.Size() > iOutputBufferPtr->MaxSize())
       
   587 		{
       
   588 		if( iTmpOutputStream->Write(aString) == -1)
       
   589 			{
       
   590 			User::Leave(iTmpOutputStream->CheckError());
       
   591 			}
       
   592 		}
       
   593 	// if string fits into the buffer -> append it
       
   594 	else
       
   595 		{
       
   596 		iOutputBufferPtr->Append(aString);
       
   597 		}
       
   598 	iDataWritten += aString.Size();					
       
   599 	}
       
   600 
       
   601 // --------------------------------------------------------------------------------------
       
   602 // Flushes the output buffer and closes the stream
       
   603 // --------------------------------------------------------------------------------------
       
   604 //
       
   605 void CXmlEngSerializerXOP::CommitWriteL()
       
   606 	{
       
   607 	// release cached data to the output stream
       
   608 	if(iOutputBufferPtr->Size() > 0)		
       
   609 		{
       
   610 		User::LeaveIfError(iTmpOutputStream->Write(iOutputBuffer->Des()));
       
   611 		iOutputBufferPtr->Delete(0, iOutputBufferPtr->MaxSize());	
       
   612 		}
       
   613 	iTmpOutputStream->CloseAll();	
       
   614 	}
       
   615 
       
   616     
       
   617 // --------------------------------------------------------------------------------------
       
   618 // Generates random CID
       
   619 // --------------------------------------------------------------------------------------
       
   620 //
       
   621 void CXmlEngSerializerXOP::GenerateRandomCid(TDes8& aCid)
       
   622     {
       
   623     _LIT8(KAt, "@");
       
   624     //generate random CID as <randomNumber>@<homeTime>
       
   625 	TTime now;
       
   626 	now.HomeTime();
       
   627 	TInt64 homeTime = now.Int64();
       
   628 	TUint32 randomNumber = Math::Random();
       
   629 	aCid.AppendNum(randomNumber);
       
   630 	aCid.Append(KAt);
       
   631 	aCid.AppendNum(now.Int64());
       
   632     }
       
   633 
       
   634 // --------------------------------------------------------------------------------------
       
   635 // Sets callback for text nodes in serialization options
       
   636 // --------------------------------------------------------------------------------------
       
   637 //
       
   638 void CXmlEngSerializerXOP::SetCallbackL( TXmlEngSerializationOptions& /* aOptions */)
       
   639     {/*
       
   640   	aOptions.iSerializationCallback = (void*)XOPSerializationCallback;
       
   641 	aOptions.iHandler = this;*/
       
   642     }