xml/xmldomandxpath/src/xmlengineserializer/xmlengserializerxop.cpp
changeset 0 e35f40988205
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xml/xmldomandxpath/src/xmlengineserializer/xmlengserializerxop.cpp	Thu Dec 17 09:29:21 2009 +0200
@@ -0,0 +1,642 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Implementation of XOP serializer
+//
+
+#include <e32math.h>
+#include <badesca.h>
+
+#include "xmlengserializerxop.h"
+#include <xml/dom/xmlengerrors.h>
+#include <xml/dom/xmlengdom.h>
+#include "xmlengdomdefs.h"
+#include <xml/dom/xmlengnode.h>
+#include <xml/dom/xmlengdatacontainer.h>
+#include <xml/dom/xmlengbinarycontainer.h>
+#include <stdapis/libxml2/libxml2_tree.h>
+#include "xmlengxopfileoutputstream.h"
+#include "xmlengxopproxyoutputstream.h"
+#include <xml/dom/xmlengserializeerrors.h>
+
+#include <bsul/clientmessage.h>
+
+_LIT8(KStartTag, "<");
+// _LIT8(KCloseTag, "/>");
+_LIT8(KXOPInclude, "xop:Include xmlns:xop=\"http://www.w3.org/2004/08/xop/include\"");
+_LIT8(KXOPDocumentStart, "MIME-Version: 1.0\nContent-Type: Multipart/Related;boundary=MIME_boundary;\ntype=\"application/xop+xml\";\nstart=\"<root@nokia.com>\";\n\n");
+_LIT8(KMimeRoot, "--MIME_boundary\nContent-ID: <root@nokia.com>\n\n");    
+_LIT8(KMimeHeaderStart, "\n\n--MIME_boundary\n");
+_LIT8(KMimeHeaderContentType, "Content-Type: ");
+_LIT8(KMimeHeaderContentIdStart, "Content-ID: <");
+_LIT8(KMimeHeaderContentIdEnd, ">\n");
+// _LIT8(KMimeHeaderEnd, "\n\n");  
+_LIT8(KXOPDocumentEnd, "\n--MIME_boundary--");
+_LIT8(KInclude, "Include");
+_LIT8(KXOPUri, "http://www.w3.org/2004/08/xop/include");
+_LIT8(KNewLine, "\n");
+_LIT8(KColon, ":");
+_LIT8(KHrefStart, " href=\"cid:");
+_LIT8(KHrefEnd, "\"/>");
+
+// --------------------------------------------------------------------------------------
+// Constructor
+// --------------------------------------------------------------------------------------
+//
+EXPORT_C CXmlEngSerializerXOP* CXmlEngSerializerXOP::NewL( TBool aCleanXOPInfoset )
+	{
+	CXmlEngSerializerXOP* serializerXop = new (ELeave) CXmlEngSerializerXOP( aCleanXOPInfoset );
+	CleanupStack::PushL( serializerXop ); 
+	serializerXop->ConstructL();
+	CleanupStack::Pop(); //serializerXop
+	return serializerXop;
+	}
+
+// --------------------------------------------------------------------------------------
+// Serializes TXmlEngNode
+// --------------------------------------------------------------------------------------
+//
+TInt CXmlEngSerializerXOP::SerializeL(const TXmlEngNode aRoot)
+    {
+    TXmlEngSerializationOptions* defPtr = NULL;
+    TXmlEngSerializationOptions def = TXmlEngSerializationOptions();
+    if(iSerializationOptions )
+    	{
+    	defPtr = iSerializationOptions;
+    	}
+    else
+        {
+        defPtr = &def;
+        }
+
+	switch(iSerializationOutput)
+		{
+		case ESerializeToFile:
+			{
+		    if (!iOutFileName)
+		        {
+		        User::Leave(KXmlEngErrNoParameters);
+		        } 			
+			return SerializeL(iOutFileName->Des(), aRoot, *defPtr);
+			}
+		case ESerializeToBuffer:
+			{
+			return SerializeL(*iBuffer, aRoot, *defPtr);
+			}
+		case ESerializeToStream:
+			{
+			TXmlEngSXOPProxyOutputStream stream = TXmlEngSXOPProxyOutputStream(*iOutputStream);
+			return StreamSerializeL(stream, aRoot, *defPtr); 
+			}
+		default: 
+			{
+			User::Leave(KErrNotSupported);
+			} 
+		}
+	return 0;
+    }
+// --------------------------------------------------------------------------------------
+// Serializes TXmlEngNode to file
+// --------------------------------------------------------------------------------------
+//
+TInt CXmlEngSerializerXOP::SerializeL(const TDesC& aFileName,
+                                   const TXmlEngNode aRoot,
+                                   const TXmlEngSerializationOptions& aOptions)
+    {
+	iRFs.Close();
+	User::LeaveIfError(iRFs.Connect());
+	return SerializeL(iRFs, aFileName, aRoot, aOptions);  
+    }
+
+// --------------------------------------------------------------------------------------
+// Serializes TXmlEngNode to file
+// --------------------------------------------------------------------------------------
+//
+TInt CXmlEngSerializerXOP::SerializeL(RFs& aRFs,
+								   const TDesC& aFileName, 
+								   const TXmlEngNode aRoot,									
+	 						  	   const TXmlEngSerializationOptions& aOptions)
+    { 
+	User::LeaveIfError( iOutputFile.Replace(aRFs, aFileName, EFileWrite) );    
+ 	TXmlEngSXOPFileOutputStream fileStream = TXmlEngSXOPFileOutputStream(iOutputFile, aRFs);
+	return StreamSerializeL(fileStream, aRoot, aOptions);  
+    }
+
+// --------------------------------------------------------------------------------------
+// Serializes TXmlEngNode to a given type of stream (file or stream)
+// --------------------------------------------------------------------------------------
+//
+TInt CXmlEngSerializerXOP::StreamSerializeL(MXmlEngSXOPOutputStream& aOutputStream, 
+											const TXmlEngNode aRoot,
+											const TXmlEngSerializationOptions& aOptions)
+    {
+	LeaveIfXopIncludeL(aRoot);
+    iDataContainerArray.Reset();
+    if(aOptions.iDataSerializer)
+    	{
+    	return aRoot.OwnerDocument().SaveL(aOutputStream, aRoot, aOptions);
+    	}
+
+	iTmpOutputStream = &aOutputStream;
+	iDataWritten = 0;
+
+	if( !iCleanXOPInfoset )		
+		{
+		BufferedWriteL(KXOPDocumentStart, ETrue);
+		BufferedWriteL(KMimeRoot, ETrue);					
+		}
+	    	
+	TXmlEngSerializationOptions opt = aOptions;
+	opt.iDataSerializer = this;
+
+	iDataWritten += aRoot.OwnerDocument().SaveL(aOutputStream, aRoot, opt);
+
+	if( !iCleanXOPInfoset )		
+		{  
+		for( TInt i = 0; i < iDataContainerArray.Count(); i++ )	
+			{	
+			BufferedWriteL(KMimeHeaderStart);
+			TPtrC8 contentTypeStr;
+			if(GetContentTypeValue(iDataContainerArray[i], contentTypeStr))
+				{	
+				BufferedWriteL(KMimeHeaderContentType);
+				BufferedWriteL(contentTypeStr);
+				BufferedWriteL(KNewLine);
+				}
+			BufferedWriteL(KMimeHeaderContentIdStart);
+			BufferedWriteL(iDataContainerArray[i].Cid());
+			BufferedWriteL(KMimeHeaderContentIdEnd);
+			BufferedWriteL(KNewLine);
+			switch(iDataContainerArray[i].NodeType())
+				{
+				case TXmlEngNode::EBinaryContainer:
+					{
+					if(opt.iOptions & TXmlEngSerializationOptions::KOptionDecodeBinaryContainers)	
+						{
+						HBufC8* decodedData = CreateDecodedBufLC(
+							iDataContainerArray[i].AsBinaryContainer().Contents());
+						BufferedWriteL(decodedData->Des());
+						CleanupStack::PopAndDestroy(); //decodedData
+						}
+					else
+						{
+						BufferedWriteL(iDataContainerArray[i].AsBinaryContainer().Contents());														
+						}
+					break;
+					}
+				case TXmlEngNode::EChunkContainer:
+					{
+					TPtrC8 data = TPtrC8(
+						((RChunk&)iDataContainerArray[i].AsChunkContainer().Chunk()).Base()
+						+ iDataContainerArray[i].AsChunkContainer().ChunkOffset(),
+						iDataContainerArray[i].AsChunkContainer().Size());
+					if(opt.iOptions & TXmlEngSerializationOptions::KOptionDecodeBinaryContainers)	
+						{						
+						HBufC8* decodedData = CreateDecodedBufLC(data);					
+						BufferedWriteL(decodedData->Des());
+						CleanupStack::PopAndDestroy(); //decodedData
+						}
+					else
+						{
+						BufferedWriteL(data);
+						}
+					break;
+					}
+				case TXmlEngNode::EFileContainer:
+					{
+					TInt size = iDataContainerArray[i].AsFileContainer().Size();
+					HBufC8* data = HBufC8::NewLC(size);
+					TPtr8 dataPtr = data->Des();
+					iDataContainerArray[i].AsFileContainer().File().Read(dataPtr, size);
+					if(opt.iOptions & TXmlEngSerializationOptions::KOptionDecodeBinaryContainers )	
+						{
+						HBufC8* decodedData = CreateDecodedBufLC(dataPtr);
+						BufferedWriteL(decodedData->Des());
+						CleanupStack::PopAndDestroy(); //decodedData							
+						}
+					else
+						{
+						BufferedWriteL(dataPtr);
+						}
+					CleanupStack::PopAndDestroy(); //data					
+					break;
+					}														
+				}			
+			}
+		BufferedWriteL(KXOPDocumentEnd);
+		} //if( !iCleanXOPInfoset )	
+	CommitWriteL();	
+	return iDataWritten;
+    }     
+
+// --------------------------------------------------------------------------------------
+// Serializes TXmlEngNode to buffer
+// --------------------------------------------------------------------------------------
+//
+TInt CXmlEngSerializerXOP::SerializeL( RBuf8& aBuffer, 
+                                    const TXmlEngNode aRoot, 
+									const TXmlEngSerializationOptions& aOptions )
+    {
+    if(aBuffer.Length())
+        {
+        aBuffer.Close();
+        }
+	LeaveIfXopIncludeL(aRoot);
+    iDataContainerArray.Reset();	    
+    if(aOptions.iDataSerializer)
+    	{
+    	return CXmlEngSerializer::SerializeL(aBuffer, aRoot, aOptions);
+    	}    
+    	
+	TXmlEngSerializationOptions opt = aOptions;
+	opt.iDataSerializer = this;
+			
+	RBuf8 xopDocument;
+	CleanupClosePushL(xopDocument);
+	aRoot.OwnerDocument().SaveL(xopDocument, aRoot, opt);
+
+	if( iCleanXOPInfoset )		
+		{
+		if(xopDocument.Size() > aBuffer.MaxSize())
+		    {
+		    aBuffer.ReAllocL( xopDocument.Size() );
+		    }
+		aBuffer.Append(xopDocument);		
+		}
+	else		
+		{    
+	    // adjust buffer size
+		TInt bufSize = KXOPDocumentStart().Size() 
+					+ KMimeRoot().Size() 
+					+ xopDocument.Size()
+					+ KXOPDocumentEnd().Size();
+		for(TInt j = 0; j < iDataContainerArray.Count(); j++)	
+			{
+			TPtrC8 contentTypeStr;
+			if(GetContentTypeValue(iDataContainerArray[j], contentTypeStr))
+				{
+				bufSize += KMimeHeaderContentType().Size() 
+						+ contentTypeStr.Size() 
+						+ KNewLine().Size();					
+				}
+			bufSize += KMimeHeaderStart().Size() 
+					+ KMimeHeaderContentIdStart().Size()
+					+ iDataContainerArray[j].Cid().Length()
+					+ KMimeHeaderContentIdEnd().Size()
+					+ KNewLine().Size()
+					+ iDataContainerArray[j].Size(); 
+			}
+		if (bufSize > aBuffer.MaxSize())
+		    {
+		    aBuffer.ReAllocL( bufSize );
+		    }
+		    
+		// write to buffer
+		aBuffer.Append(KXOPDocumentStart());
+		aBuffer.Append(KMimeRoot());
+		aBuffer.Append(xopDocument);
+		for(TInt i = 0; i < iDataContainerArray.Count(); i++)	
+			{
+			aBuffer.Append(KMimeHeaderStart);
+			TPtrC8 contentTypeStr;
+			if(GetContentTypeValue(iDataContainerArray[i], contentTypeStr))
+				{	
+				aBuffer.Append(KMimeHeaderContentType);
+				aBuffer.Append(contentTypeStr);
+				aBuffer.Append(KNewLine);
+				}
+			aBuffer.Append(KMimeHeaderContentIdStart);				
+			aBuffer.Append(iDataContainerArray[i].Cid());
+			aBuffer.Append(KMimeHeaderContentIdEnd);
+			aBuffer.Append(KNewLine);	
+			switch(iDataContainerArray[i].NodeType())
+				{
+				case TXmlEngNode::EBinaryContainer:
+					{
+					if(opt.iOptions & TXmlEngSerializationOptions::KOptionDecodeBinaryContainers )	
+						{						
+						HBufC8* decodedData = CreateDecodedBufLC(iDataContainerArray[i].AsBinaryContainer().Contents());
+						aBuffer.Append(decodedData->Des());
+						CleanupStack::PopAndDestroy(); //decodedData
+						}
+					else
+						{
+						aBuffer.Append(iDataContainerArray[i].AsBinaryContainer().Contents());							
+						}
+					break;
+					}
+				case TXmlEngNode::EChunkContainer:
+					{
+					TPtrC8 data = TPtrC8(
+						((RChunk&)iDataContainerArray[i].AsChunkContainer().Chunk()).Base()
+						+ iDataContainerArray[i].AsChunkContainer().ChunkOffset(),
+						iDataContainerArray[i].AsChunkContainer().Size());
+					if(opt.iOptions & TXmlEngSerializationOptions::KOptionDecodeBinaryContainers )	
+						{							
+						HBufC8* decodedData = CreateDecodedBufLC(data); 
+						aBuffer.Append(decodedData->Des());
+						CleanupStack::PopAndDestroy(); //decodedData
+						}
+					else
+						{
+						aBuffer.Append(data);							
+						}
+					break;
+					}
+				case TXmlEngNode::EFileContainer:
+					{
+					TInt size = iDataContainerArray[i].AsFileContainer().Size();
+					HBufC8* data = HBufC8::NewLC(size);
+					TPtr8 dataPtr = data->Des();
+					iDataContainerArray[i].AsFileContainer().File().Read(dataPtr, size);
+					if(opt.iOptions & TXmlEngSerializationOptions::KOptionDecodeBinaryContainers )	
+						{
+						HBufC8* decodedData = CreateDecodedBufLC(dataPtr); 
+						aBuffer.Append(decodedData->Des());
+						CleanupStack::PopAndDestroy(); //decodedData							
+						}
+					else
+						{
+						aBuffer.Append(dataPtr);
+						}
+					CleanupStack::PopAndDestroy(); //data
+					break;
+					}														
+				}						
+			}
+		aBuffer.Append(KXOPDocumentEnd);
+		}
+	CleanupStack::PopAndDestroy(); //xopDocument
+	return aBuffer.Size(); 
+    }
+      
+// --------------------------------------------------------------------------------------
+// Determines how binary data should be serialized
+// --------------------------------------------------------------------------------------
+//
+TPtrC8 CXmlEngSerializerXOP::SerializeDataL(TXmlEngNode aNode)
+    {
+	User::LeaveIfError(iDataContainerArray.Append(aNode.AsDataContainer()));
+	iXopStubPtr->Zero();
+	iXopStubPtr->Append(KStartTag);
+	TXmlEngNamespace xopNs = aNode.AsElement().LookupNamespaceByUriL(KXOPUri);
+	if(xopNs.IsNull())
+		{
+		iXopStubPtr->Append(KXOPInclude);
+		}
+	else
+		{
+		iXopStubPtr->Append(xopNs.Prefix());
+		iXopStubPtr->Append(KColon);
+		iXopStubPtr->Append(KInclude);
+		}
+	iXopStubPtr->Append(KHrefStart);	
+	iXopStubPtr->Append(aNode.AsDataContainer().Cid());
+	iXopStubPtr->Append(KHrefEnd);
+	iXopStubPtr->ZeroTerminate();
+	return *iXopStubPtr;
+    }
+   
+// --------------------------------------------------------------------------------------
+// Constructor
+// --------------------------------------------------------------------------------------
+//
+CXmlEngSerializerXOP::CXmlEngSerializerXOP( TBool aCleanXOPInfoset ) : 
+	iCleanXOPInfoset(aCleanXOPInfoset)
+    {   
+    }
+
+// --------------------------------------------------------------------------------------
+// Second phase constructor
+// --------------------------------------------------------------------------------------
+//
+void CXmlEngSerializerXOP::ConstructL()
+    { 
+    //create stub buffer
+    iXopStub = HBufC8::NewL(KXopStubMaxSize);
+    iXopStubPtr = new ( ELeave ) TPtr8(iXopStub->Des());
+    //create output buffer
+    iOutputBuffer = HBufC8::NewL(KInitBufferSize);
+    iOutputBufferPtr = new ( ELeave ) TPtr8(iOutputBuffer->Des());
+
+    }
+        
+// --------------------------------------------------------------------------------------
+// Destructor
+// --------------------------------------------------------------------------------------
+//
+CXmlEngSerializerXOP::~CXmlEngSerializerXOP()
+    {
+	iDataContainerArray.Close();
+	iRFs.Close();
+   	delete iXopStub;	
+    delete iXopStubPtr;	
+   	delete iOutputBuffer;	
+   	delete iOutputBufferPtr;
+    }
+
+// --------------------------------------------------------------------------------------
+// Leaves if a DOM tree contains 'Include' elements from XOP 
+// namespace 'http://www.w3.org/2004/08/xop/include'
+// --------------------------------------------------------------------------------------
+//
+void CXmlEngSerializerXOP::LeaveIfXopIncludeL(TXmlEngNode aRoot)
+	{
+	if(aRoot.NodeType() == XML_DOCUMENT_NODE)
+		{
+	    if(HasXopInclude(aRoot.OwnerDocument().DocumentElement()))
+	    	{
+	    	User::Leave(KXmlEngErrBadInfoset);
+	    	}		
+		}
+	else if(HasXopInclude(aRoot))
+	    {
+	    User::Leave(KXmlEngErrBadInfoset);
+	    }	
+	}
+
+// --------------------------------------------------------------------------------------
+// Verifies if a DOM tree contains 'Include' elements from XOP 
+// namespace 'http://www.w3.org/2004/08/xop/include'
+// --------------------------------------------------------------------------------------
+//
+TBool CXmlEngSerializerXOP::HasXopInclude(TXmlEngNode aRoot)
+	{
+	if(aRoot.NodeType() == XML_ELEMENT_NODE)
+		{
+		if(	aRoot.NamespaceDeclaration().NotNull() && 
+			aRoot.Name().Compare(KInclude) == 0 && 
+			aRoot.NamespaceUri().Compare(KXOPUri) == 0 )
+			{
+			return ETrue;
+			}
+		if(aRoot.HasChildNodes())
+			{
+			RXmlEngNodeList<TXmlEngNode> childList;
+			aRoot.GetChildNodes(childList);
+			while(childList.HasNext())
+				{
+				if(HasXopInclude(childList.Next()))
+					return ETrue;				
+				} 
+			}
+		}
+	return EFalse;
+	}
+	
+// --------------------------------------------------------------------------------------
+// Verifies if container's parent node has xmlmime:contentType 
+// attribute information item. If found, the function returns ETrue 
+// and xmlmime:contentType attribute value. Otherwise, function
+// returns EFalse and aContentType is undefined.
+// --------------------------------------------------------------------------------------
+//
+TBool CXmlEngSerializerXOP::GetContentTypeValue(TXmlEngDataContainer aContainer, TPtrC8& aContentType)
+	{
+	_LIT8(KMimeNsUri, "http://www.w3.org/2004/11/xmlmime");
+	_LIT8(KContentTypeName, "contentType");
+	
+	TXmlEngElement parent = aContainer.ParentNode().AsElement();
+	if(parent.HasAttributes())
+		{
+		RXmlEngNodeList<TXmlEngAttr> attrList;
+		parent.GetAttributes(attrList);
+		for(TInt i = 0; i < attrList.Count(); i++)
+			{
+			TXmlEngAttr attr = attrList.Next();
+			if(attr.Name().Compare(KContentTypeName) == 0 
+				&& attr.NamespaceUri().Compare(KMimeNsUri) == 0)
+				{
+				aContentType.Set(attr.Value());
+				return ETrue;
+				}
+			}
+		}
+	return EFalse;
+	}
+
+// --------------------------------------------------------------------------------------
+// Decodes input data from base64 to binary octets and creates
+// heap buffer with the decoded data. The buffer is pushed on the cleanup stack.
+// --------------------------------------------------------------------------------------
+//
+HBufC8* CXmlEngSerializerXOP::CreateDecodedBufLC(TPtrC8 aEncodedData)
+	{
+	// The decoded length of base64 is about half (use same) encoded length
+	HBufC8* decodedData = HBufC8::NewLC(aEncodedData.Size());
+	TPtr8 decodedDataPtr = decodedData->Des();
+	// Decode the base64 Content-Transfer-Encoding
+	using namespace BSUL;
+	Base64Codec::Decode(aEncodedData, decodedDataPtr);
+	if(decodedDataPtr.Length() == 0)
+		{
+		User::Leave(KXmlEngErrDecodingFailed);
+		}
+	return decodedData;	
+	}
+
+// --------------------------------------------------------------------------------------
+// Appends given string to output buffer. If the serializer's 
+// output type is file, the output buffer is released to the output stream 
+// after reaching a specified threshold and the output buffer is cleared.
+// --------------------------------------------------------------------------------------
+//
+void CXmlEngSerializerXOP::BufferedWriteL(const TDesC8& aString, TBool aFlush)
+	{
+	if(aFlush)
+		{
+		if(iOutputBufferPtr->Size() > 0)
+			{
+			if( iTmpOutputStream->Write(iOutputBuffer->Des()) == -1)
+				{
+				User::Leave(iTmpOutputStream->CheckError());
+				}
+			iOutputBufferPtr->Delete(0, iOutputBufferPtr->Size());							
+			}
+		if( iTmpOutputStream->Write(aString) == -1)
+			{
+			User::Leave(iTmpOutputStream->CheckError());
+			}												
+		iDataWritten += aString.Size();
+		return;			
+		}
+
+	// first, check if data is in the buffer and added string will not fit
+	// -> flush buffer
+	if(iOutputBufferPtr->Size() > 0 &&
+	   iOutputBufferPtr->Size() + aString.Size() > iOutputBufferPtr->MaxSize())
+		{
+		if( iTmpOutputStream->Write(iOutputBuffer->Des()) == -1)
+			{
+			User::Leave(iTmpOutputStream->CheckError());
+			}
+		iOutputBufferPtr->Delete(0, iOutputBufferPtr->Size());
+		}
+	// if string alone doesn't fit in the buffer -> save string
+	if(aString.Size() > iOutputBufferPtr->MaxSize())
+		{
+		if( iTmpOutputStream->Write(aString) == -1)
+			{
+			User::Leave(iTmpOutputStream->CheckError());
+			}
+		}
+	// if string fits into the buffer -> append it
+	else
+		{
+		iOutputBufferPtr->Append(aString);
+		}
+	iDataWritten += aString.Size();					
+	}
+
+// --------------------------------------------------------------------------------------
+// Flushes the output buffer and closes the stream
+// --------------------------------------------------------------------------------------
+//
+void CXmlEngSerializerXOP::CommitWriteL()
+	{
+	// release cached data to the output stream
+	if(iOutputBufferPtr->Size() > 0)		
+		{
+		User::LeaveIfError(iTmpOutputStream->Write(iOutputBuffer->Des()));
+		iOutputBufferPtr->Delete(0, iOutputBufferPtr->MaxSize());	
+		}
+	iTmpOutputStream->CloseAll();	
+	}
+
+    
+// --------------------------------------------------------------------------------------
+// Generates random CID
+// --------------------------------------------------------------------------------------
+//
+void CXmlEngSerializerXOP::GenerateRandomCid(TDes8& aCid)
+    {
+    _LIT8(KAt, "@");
+    //generate random CID as <randomNumber>@<homeTime>
+	TTime now;
+	now.HomeTime();
+	TInt64 homeTime = now.Int64();
+	TUint32 randomNumber = Math::Random();
+	aCid.AppendNum(randomNumber);
+	aCid.Append(KAt);
+	aCid.AppendNum(now.Int64());
+    }
+
+// --------------------------------------------------------------------------------------
+// Sets callback for text nodes in serialization options
+// --------------------------------------------------------------------------------------
+//
+void CXmlEngSerializerXOP::SetCallbackL( TXmlEngSerializationOptions& /* aOptions */)
+    {/*
+  	aOptions.iSerializationCallback = (void*)XOPSerializationCallback;
+	aOptions.iHandler = this;*/
+    }