xml/xmldomandxpath/src/xmlengineserializer/xmlengdomcontenthandler.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 // Content handler implementation
       
    15 //
       
    16 
       
    17 #include <xml/parser.h>
       
    18 #include <xml/documentparameters.h>
       
    19 #include <xml/dom/xmlengdom.h>
       
    20 #include <xml/dom/xmlengdocument.h>
       
    21 #include "xmlengdomdefs.h"
       
    22 #include <xml/dom/xmlengbinarycontainer.h>
       
    23 #include <stdapis/libxml2/libxml2_globals.h>	//xmlFree
       
    24 #include <xml/utils/xmlengxestd.h>
       
    25 #include "xmlengdomcontenthandler.h"
       
    26 
       
    27 xmlChar* xmlCharFromDesC8L(const TDesC8& aDesc)
       
    28     {
       
    29     if(!aDesc.Length())
       
    30         {
       
    31         return NULL;
       
    32         }
       
    33     xmlChar* newContent = (xmlChar*)new(ELeave) TUint8[aDesc.Length() + 1];
       
    34     *(Mem::Copy((TAny*)newContent, aDesc.Ptr(), aDesc.Length())) = 0;
       
    35     return newContent;
       
    36     }
       
    37 
       
    38 CXmlEngDOMContentHandler* CXmlEngDOMContentHandler::NewL(RXmlEngDocument& aDoc)
       
    39 	{
       
    40 	CXmlEngDOMContentHandler* self = new (ELeave) CXmlEngDOMContentHandler(aDoc);
       
    41 	return self;
       
    42 	}
       
    43 
       
    44 CXmlEngDOMContentHandler::~CXmlEngDOMContentHandler()
       
    45 	{
       
    46 	}
       
    47 
       
    48 CXmlEngDOMContentHandler::CXmlEngDOMContentHandler(RXmlEngDocument& aDoc):
       
    49 iDoc(aDoc)
       
    50 	{
       
    51 	iLastElement = iDoc;
       
    52 	iTmpElement = TXmlEngElement();
       
    53 	}
       
    54 
       
    55 /**
       
    56 This method is a callback to indicate the start of the document.
       
    57 @param				aDocParam Specifies the various parameters of the document.
       
    58 @param				aDocParam.iCharacterSetName The character encoding of the document.
       
    59 @param				aErrorCode is the error code. 
       
    60 					If this is not KErrNone then special action may be required.
       
    61 */
       
    62 void CXmlEngDOMContentHandler::OnStartDocumentL(const RDocumentParameters& aDocParam, TInt aErrorCode)
       
    63     {
       
    64     if(aErrorCode)
       
    65         {
       
    66         return;
       
    67         }
       
    68         
       
    69 	INTERNAL_DOCPTR(iDoc)->encoding = xmlCharFromDesC8L(aDocParam.CharacterSetName().DesC());
       
    70 	iTmpElement = iDoc.CreateDocumentElementL(_L8("fake"));	
       
    71     }
       
    72 
       
    73 
       
    74 /**
       
    75 This method is a callback to indicate the end of the document.
       
    76 @param				aErrorCode is the error code. 
       
    77 					If this is not KErrNone then special action may be required.
       
    78 */
       
    79 void CXmlEngDOMContentHandler::OnEndDocumentL(TInt /*aErrorCode*/)
       
    80     {
       
    81     }
       
    82 
       
    83 
       
    84 /**
       
    85 This method is a callback to indicate an element has been parsed.
       
    86 @param				aElement is a handle to the element's details.
       
    87 @param				aAttributes contains the attributes for the element.
       
    88 @param				aErrorCode is the error code.
       
    89 					If this is not KErrNone then special action may be required.
       
    90 */
       
    91 void CXmlEngDOMContentHandler::OnStartElementL(const RTagInfo& aElement,
       
    92 								 const RAttributeArray& aAttributes, 
       
    93 								 TInt aErrorCode)
       
    94     {
       
    95     if(aErrorCode)
       
    96         {
       
    97         return;
       
    98         }
       
    99         
       
   100     TXmlEngElement element;
       
   101     if(iTmpElement.IsNull())
       
   102         {
       
   103         element = iDoc.CreateElementL(aElement.LocalName().DesC(),
       
   104                                       aElement.Uri().DesC(),
       
   105                                       aElement.Prefix().DesC());
       
   106         }
       
   107     else
       
   108         {
       
   109         element = iTmpElement;
       
   110 
       
   111          CXmlEngDOMContentHandler::RenameElementL( element,
       
   112                 		aElement.LocalName().DesC(),
       
   113                             aElement.Uri().DesC(),
       
   114                             aElement.Prefix().DesC() );
       
   115                            
       
   116         iTmpElement = TXmlEngElement();
       
   117         }
       
   118 	
       
   119 	RArray <RAttribute> array = aAttributes;
       
   120 	TInt size = array.Count();
       
   121 	RAttribute attr;
       
   122 		
       
   123 	for ( TInt i = 0; i < size; i++)
       
   124 		{
       
   125 		attr = array[i];
       
   126 		if(attr.Attribute().Prefix().DesC().Length())
       
   127 		{
       
   128 			element.AddNewAttributeL(attr.Attribute().LocalName().DesC(),
       
   129 		                         attr.Value().DesC(),
       
   130 		                         attr.Attribute().Uri().DesC(),		
       
   131 		                         attr.Attribute().Prefix().DesC());
       
   132 		}
       
   133 		else
       
   134 		{
       
   135 			element.AddNewAttributeL(attr.Attribute().LocalName().DesC(),
       
   136 		                         attr.Value().DesC());
       
   137 		}
       
   138 	}
       
   139 	iLastElement.AppendChildL(element);
       
   140 	iLastElement = element;	
       
   141 }
       
   142 	
       
   143 /**
       
   144 This method is a callback to indicate the end of the element has been reached.
       
   145 @param				aElement is a handle to the element's details.
       
   146 @param				aErrorCode is the error code.
       
   147 					If this is not KErrNone then special action may be required.
       
   148 */
       
   149 void CXmlEngDOMContentHandler::OnEndElementL(const RTagInfo& /*aElement*/, TInt aErrorCode)
       
   150     {
       
   151     if(aErrorCode)
       
   152         {
       
   153         return;
       
   154         }
       
   155     iLastElement = iLastElement.ParentNode();
       
   156     }
       
   157 
       
   158 /**
       
   159 This method is a callback that sends the content of the element.
       
   160 Not all the content may be returned in one go. The data may be sent in chunks.
       
   161 When an OnEndElementL is received this means there is no more content to be sent.
       
   162 @param				aBytes is the raw content data for the element. 
       
   163 					The client is responsible for converting the data to the 
       
   164 					required character set if necessary.
       
   165 					In some instances the content may be binary and must not be converted.
       
   166 @param				aErrorCode is the error code.
       
   167 					If this is not KErrNone then special action may be required.
       
   168 */
       
   169 void CXmlEngDOMContentHandler::OnContentL(const TDesC8& aBytes, TInt aErrorCode)
       
   170     {
       
   171     if(aErrorCode)
       
   172         {
       
   173         return;
       
   174         }
       
   175     iLastElement.AppendChildL(iDoc.CreateTextNodeL(aBytes));
       
   176     }
       
   177 	
       
   178 /**
       
   179 This method is a notification of the beginning of the scope of a prefix-URI Namespace mapping.
       
   180 This method is always called before the corresponding OnStartElementL method.
       
   181 @param				aPrefix is the Namespace prefix being declared.
       
   182 @param				aUri is the Namespace URI the prefix is mapped to.
       
   183 @param				aErrorCode is the error code.
       
   184 					If this is not KErrNone then special action may be required.
       
   185 */
       
   186 void CXmlEngDOMContentHandler::OnStartPrefixMappingL(const RString& aPrefix, const RString& aUri, 
       
   187 									   TInt aErrorCode)
       
   188     {
       
   189     if(aErrorCode)
       
   190         {
       
   191         return;
       
   192         }
       
   193         
       
   194     if(iTmpElement.IsNull())
       
   195         {
       
   196         iTmpElement = iDoc.CreateElementL(_L8("fake"));
       
   197         }
       
   198     iTmpElement.AddNamespaceDeclarationL(aUri.DesC(),aPrefix.DesC());
       
   199     }
       
   200 
       
   201 /**
       
   202 This method is a notification of the end of the scope of a prefix-URI mapping.
       
   203 This method is called after the corresponding DoEndElementL method.
       
   204 @param				aPrefix is the Namespace prefix that was mapped.
       
   205 @param				aErrorCode is the error code.
       
   206 					If this is not KErrNone then special action may be required.
       
   207 */
       
   208 void CXmlEngDOMContentHandler::OnEndPrefixMappingL(const RString& /*aPrefix*/, TInt /*aErrorCode*/)
       
   209     {
       
   210     }
       
   211 
       
   212 /**
       
   213 This method is a notification of ignorable whitespace in element content.
       
   214 @param				aBytes are the ignored bytes from the document being parsed.
       
   215 @param				aErrorCode is the error code.
       
   216 					If this is not KErrNone then special action may be required.
       
   217 */
       
   218 void CXmlEngDOMContentHandler::OnIgnorableWhiteSpaceL(const TDesC8& /*aBytes*/, TInt /*aErrorCode*/)
       
   219     {
       
   220     }
       
   221 
       
   222 /**
       
   223 This method is a notification of a skipped entity. If the parser encounters an 
       
   224 external entity it does not need to expand it - it can return the entity as aName 
       
   225 for the client to deal with.
       
   226 @param				aName is the name of the skipped entity.
       
   227 @param				aErrorCode is the error code.
       
   228 					If this is not KErrNone then special action may be required.
       
   229 */
       
   230 void CXmlEngDOMContentHandler::OnSkippedEntityL(const RString& /*aName*/, TInt /*aErrorCode*/)
       
   231     {
       
   232     
       
   233     }
       
   234 
       
   235 /**
       
   236 This method is a receive notification of a processing instruction.
       
   237 @param				aTarget is the processing instruction target.
       
   238 @param				aData is the processing instruction data. If empty none was supplied.
       
   239 @param				aErrorCode is the error code.
       
   240 					If this is not KErrNone then special action may be required.
       
   241 */
       
   242 void CXmlEngDOMContentHandler::OnProcessingInstructionL(const TDesC8& aTarget,
       
   243 										  const TDesC8& aData, 
       
   244 										  TInt aErrorCode)
       
   245     {
       
   246     if(aErrorCode)
       
   247         {
       
   248         return;
       
   249         }
       
   250         
       
   251 	iLastElement.AppendChildL(iDoc.CreateProcessingInstructionL(aTarget,aData));	
       
   252     }
       
   253 
       
   254 /**
       
   255  * This method is a callback that sends the binary content of the element.
       
   256  *
       
   257  * @param				aBytes is the raw binary data of the element 
       
   258  *						and must not be converted.
       
   259  * @param				aErrorCode is the error code. If this is not KErrNone
       
   260  *						then special action may be required.
       
   261  */
       
   262 void CXmlEngDOMContentHandler::OnBinaryContentL(const TDesC8& aBytes, 
       
   263                                                 const TDesC8& aCid,
       
   264                                                 TInt aErrorCode)
       
   265     {
       
   266     if(aErrorCode)
       
   267         {
       
   268         return;
       
   269         }
       
   270         
       
   271 	iLastElement.AppendChildL(iDoc.CreateBinaryContainerL(aCid,aBytes));    
       
   272     }
       
   273 	
       
   274 /**
       
   275  * This method is a callback that provides data container reference
       
   276  *
       
   277  * @param				aContainer Container encapsulating binary data
       
   278  * @param				aErrorCode is the error code. If this is not KErrNone
       
   279  *						then special action may be required.
       
   280  */	
       
   281 void CXmlEngDOMContentHandler::OnDataContainerL( const TXmlEngDataContainer& aContainer, 
       
   282 								   TInt aErrorCode)
       
   283     {
       
   284     if(aErrorCode)
       
   285         {
       
   286         return;
       
   287         }
       
   288         
       
   289 	iLastElement.AppendChildL(aContainer);
       
   290     }
       
   291 
       
   292 /**
       
   293 This method indicates an error has occurred.
       
   294 @param				aError is the error code
       
   295 */
       
   296 void CXmlEngDOMContentHandler::OnError(TInt /*aErrorCode*/)
       
   297     {
       
   298     }
       
   299 
       
   300 /**
       
   301 This method obtains the interface matching the specified uid.
       
   302 @return				0 if no interface matching the uid is found.
       
   303 					Otherwise, the this pointer cast to that interface.
       
   304 @param				aUid the uid identifying the required interface.
       
   305 */
       
   306 TAny* CXmlEngDOMContentHandler::GetExtendedInterface(const TInt32 aUid)
       
   307     {
       
   308     if (aUid == MXmlEngExtendedHandler::EExtInterfaceUid)
       
   309         {
       
   310         return static_cast<MXmlEngExtendedHandler*>(this);
       
   311         }
       
   312     return 0;	
       
   313     }
       
   314 
       
   315 /**
       
   316    Renames TXmlEngElement nodes only.	(static helper method)
       
   317     
       
   318   @param aElement element to rename
       
   319   @param aLocalName New name
       
   320   @param aNamespaceUri New namespace uri
       
   321   @param aPrefix New namespace prefix
       
   322 */
       
   323 void CXmlEngDOMContentHandler::RenameElementL(TXmlEngElement& aElement,
       
   324     const TDesC8& aLocalName,
       
   325     const TDesC8& aNamespaceUri,
       
   326     const TDesC8& aPrefix )
       
   327     {
       
   328     	if ( !INTERNAL_NODEPTR(aElement)->type == XML_ELEMENT_NODE ) 
       
   329     		{
       
   330     		User::Leave(KXmlEngErrWrongUseOfAPI);	
       
   331     		}
       
   332     
       
   333     TXmlEngNode::TXmlEngDOMNodeType type = aElement.NodeType();
       
   334     if (type == TXmlEngNode::EElement)
       
   335         {
       
   336         SetNameL(aElement, aLocalName);
       
   337         if (aNamespaceUri.Length() || aPrefix.Length())
       
   338             {
       
   339             TXmlEngElement nsElem = aElement.AsElement();
       
   340             TXmlEngNamespace ns = nsElem.FindOrCreateNsDeclL(aNamespaceUri, aPrefix);
       
   341             INTERNAL_NODEPTR(aElement)->ns = INTERNAL_NSPTR(ns);
       
   342             }
       
   343         }
       
   344     }
       
   345   
       
   346 // ---------------------------------------------------------------------------------------------
       
   347 // Changes name of the element so that Name() on it will return new name
       
   348 // ---------------------------------------------------------------------------------------------  
       
   349     void CXmlEngDOMContentHandler::SetNameL( TXmlEngElement& aElement,
       
   350     const TDesC8& aName )
       
   351     {
       
   352        
       
   353     if ( !INTERNAL_NODEPTR(aElement) )
       
   354     	{
       
   355     	User::Leave(KXmlEngErrNullNode);
       
   356     	}
       
   357     const xmlChar* KOldName = INTERNAL_NODEPTR(aElement)->name;
       
   358 
       
   359         if ( aName.Length() <= 0 )
       
   360     		{
       
   361     		User::Leave(KXmlEngErrWrongUseOfAPI);
       
   362     		}
       
   363         INTERNAL_NODEPTR(aElement)->name = xmlCharFromDesC8L(aName);
       
   364         xmlFree((void *)KOldName);
       
   365     
       
   366     }