--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xml/legacyminidomparser/xmldom/src/gmxmlnode.cpp Mon Sep 13 13:16:40 2010 +0530
@@ -0,0 +1,399 @@
+// Copyright (c) 2001-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:
+// MDXMLNode.CPP
+// @file
+// This file contains the implementation of the CMDXMLNode class which
+// is the base class for the Mini-DOM.
+// This class forms the basis for the Mini-DOM. It is a
+// pure abstract class and it's sole concern is the node
+// type and name and the management of the list of child
+// nodes.
+// The node name and type are set in the constructor and
+// cannot be changed thereafter.
+// The list of child nodes is managed as a doubly-linked
+// list, not an array or similar structure. Derived
+// classes which are not allowed children will override the
+// operations to manipulate the child list.
+//
+//
+
+#include <gmxmlnode.h>
+#include <gmxmldomconstants.h>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include "gmxmldummydtd.h"
+#endif
+
+CMDXMLNode::CMDXMLNode( TDOMNodeType aNodeType, TBool aCanHaveChildren, CMDXMLDocument* aOwnerDocument ):
+ iElementType(KXMLUndefinedElement),
+ iNodeType(aNodeType),
+ iCanHaveChildren(aCanHaveChildren)
+//
+// The node type will normally be hard-wired in any derived class constructor.
+// The node name and HaveChildren flag will normally be hard-wired in a derived class constructor unless it
+// covers a generic element.
+// @param aNodeType The tpe of node to be created
+// @param aCanHaveChildren Flag to indicate if the node represents a node which is allowed children
+// @param aOwnerDocument Pointer to the document at the root of the DOM tree
+//
+ {
+ iOwnerDocument = aOwnerDocument;
+ }
+
+EXPORT_C CMDXMLNode::~CMDXMLNode()
+//
+// When this node is deleted it will links its previous and next siblings across the gap, will
+// delete all of its children and will correct its parents first and last child pointers if necessary.
+//
+ {
+ // Perform housekeeping on parent and siblings - shouldn't be necessary as the links to
+ // this element should have been removed first or we are in a tree delete but
+ // let's be helpful anyway.
+ if((iNextSiblingPtr != NULL) && (iNextSiblingPtr->iPrevSiblingPtr == this))
+ {
+ iNextSiblingPtr->iPrevSiblingPtr = iPrevSiblingPtr;
+ }
+ if((iPrevSiblingPtr != NULL) && (iPrevSiblingPtr->iNextSiblingPtr == this))
+ {
+ iPrevSiblingPtr->iNextSiblingPtr = iNextSiblingPtr;
+ }
+ if( iParentPtr != NULL )
+ {
+ if(iParentPtr->iFirstChildPtr == this)
+ {
+ iParentPtr->iFirstChildPtr = iNextSiblingPtr;
+ }
+ if(iParentPtr->iLastChildPtr == this)
+ {
+ iParentPtr->iLastChildPtr = iPrevSiblingPtr;
+ }
+ }
+
+ // Delete all children
+ CMDXMLNode* childToDelete;
+ CMDXMLNode* nextChild;
+ childToDelete = iFirstChildPtr;
+ while( childToDelete != NULL )
+ {
+ nextChild = childToDelete->iNextSiblingPtr;
+ delete childToDelete;
+ childToDelete = nextChild;
+ }
+
+ delete iNodeName;
+ iNodeName = NULL;
+ }
+
+EXPORT_C void CMDXMLNode::SetNodeNameL( const TDesC& aNodeName)
+//
+// @param aNodeName The name of the node.
+// @leave Can Leave due to OOM
+//
+ {
+ iNodeName = HBufC::NewMaxL(aNodeName.Length());
+ TPtr nodeAccess = iNodeName->Des();
+ nodeAccess = aNodeName;
+ }
+
+EXPORT_C TPtrC CMDXMLNode::NodeName()
+//
+// @return Returns the name of the node
+//
+ {
+ TPtrC retVal = iNodeName->Des();
+ return retVal;
+ }
+
+
+EXPORT_C CMDXMLNode* CMDXMLNode::PreviousSameTypeSibling()
+//
+// @return Returns a pointer to the previous sibling node of the same type if any,
+// oherwise returns NULL
+//
+ {
+ CMDXMLNode* nodePtr = iPrevSiblingPtr;
+ while((nodePtr != NULL) && nodePtr->iElementType != iElementType)
+ {
+ nodePtr = nodePtr->iPrevSiblingPtr;
+ }
+ return nodePtr;
+ }
+
+EXPORT_C CMDXMLNode* CMDXMLNode::NextSameTypeSibling()
+//
+// @return Returns a pointer to the next sibling node of the same type if any,
+// oherwise returns NULL
+//
+ {
+ CMDXMLNode* nodePtr = iNextSiblingPtr;
+ while((nodePtr != NULL) && nodePtr->iElementType != iElementType)
+ {
+ nodePtr = nodePtr->iNextSiblingPtr;
+ }
+ return nodePtr;
+ }
+
+EXPORT_C TInt CMDXMLNode::RemoveChild(CMDXMLNode* aChildToRemove)
+//
+// Removes a child from the list of child nodes. The child node is not deleted - that is the responsibility of the caller
+// @param aChildToRemove Pointer to child to remove from the list
+// @return Returns KERRNone if sucessful or KErrNotFound if the referenced child node is not found
+//
+ {
+ TInt retVal=KErrNone;
+
+ if(aChildToRemove == NULL)
+ {
+ retVal = KErrNotFound;
+ }
+ else if( !iCanHaveChildren )
+ {
+ retVal = KErrXMLInvalidChild;
+ }
+ else if( aChildToRemove->iParentPtr != this )
+ {
+ retVal = KErrNotFound;
+ }
+ else
+ {
+ if(iFirstChildPtr == NULL)
+ {
+ retVal = KErrNotFound;
+ }
+ else
+ {
+ if( aChildToRemove == iFirstChildPtr)
+ {
+ if( aChildToRemove == iLastChildPtr )
+ { // Only child so just zero pointers
+ iFirstChildPtr = NULL;
+ iLastChildPtr = NULL;
+ }
+ else
+ { // First but not only child
+ iFirstChildPtr->iNextSiblingPtr->iPrevSiblingPtr = NULL;
+ iFirstChildPtr = iFirstChildPtr->iNextSiblingPtr;
+ }
+ }
+ else if( aChildToRemove == iLastChildPtr )
+ { // Last but not only child
+ iLastChildPtr->iPrevSiblingPtr->iNextSiblingPtr = NULL;
+ iLastChildPtr = iLastChildPtr->iPrevSiblingPtr;
+ }
+ else
+ { // Not first or last so somewhere in the list
+ CMDXMLNode* nodeBefore = iFirstChildPtr;
+ while((nodeBefore->iNextSiblingPtr != NULL) &&
+ (nodeBefore->iNextSiblingPtr != aChildToRemove))
+ {
+ nodeBefore = nodeBefore->iNextSiblingPtr;
+ }
+ if( nodeBefore->iNextSiblingPtr != aChildToRemove )
+ {
+ retVal = KErrNotFound;
+ }
+ else
+ {
+ nodeBefore->iNextSiblingPtr = aChildToRemove->iNextSiblingPtr;
+ aChildToRemove->iNextSiblingPtr->iPrevSiblingPtr = nodeBefore;
+ }
+ }
+ }
+ }//end if
+
+ if( retVal == KErrNone )
+ { // Having cleared this node off the list, clear its own pointers
+ aChildToRemove->iPrevSiblingPtr = NULL;
+ aChildToRemove->iNextSiblingPtr = NULL;
+ aChildToRemove->iParentPtr = NULL;
+ }
+ return retVal;
+ }
+
+EXPORT_C TInt CMDXMLNode::InsertBefore(CMDXMLNode* aInsertBeforeChild, CMDXMLNode* aChildToInsert)
+//
+// Inserts a new child node at a specific point in the child list.
+// @param aInsertBeforeChild Pointer to the element before which the new child should be inserted (NULL to insert at the start of the list)
+// @param aChildToInsert Pointer to the new child node to insert.
+// @return Returns KErrNone if successful, KErrXMLInvalidChild if the node cannot have children or KErrNotFound if it cannot fnd the child before which to insert
+//
+ {
+ TInt retVal = KErrNone;
+
+ if(aChildToInsert == NULL)
+ {
+ retVal = KErrNotSupported;
+ }
+ else if( !iCanHaveChildren )
+ {
+ retVal = KErrXMLInvalidChild ;
+ }
+ else if(iFirstChildPtr == NULL && aInsertBeforeChild != NULL)
+ {
+ retVal = KErrNotFound;
+ }
+ else if((aInsertBeforeChild == NULL) || (aInsertBeforeChild == iFirstChildPtr))
+ { // Insert at start of list
+ aChildToInsert->iParentPtr = this;
+ if(iFirstChildPtr != NULL)
+ {
+ iFirstChildPtr->iPrevSiblingPtr = aChildToInsert;
+ aChildToInsert->iNextSiblingPtr = iFirstChildPtr;
+ }
+ else
+ {
+ iLastChildPtr = aChildToInsert;
+ aChildToInsert->iNextSiblingPtr = NULL;
+ }
+ iFirstChildPtr = aChildToInsert;
+ }
+ else
+ { // Find the insert before child as a check.
+ CMDXMLNode* nodeBefore = iFirstChildPtr;
+ while((nodeBefore->iNextSiblingPtr != NULL) &&
+ (nodeBefore->iNextSiblingPtr != aInsertBeforeChild))
+ {
+ nodeBefore = nodeBefore->iNextSiblingPtr;
+ }
+ if( nodeBefore->iNextSiblingPtr != aInsertBeforeChild )
+ {
+ retVal = KErrNotFound;
+ }
+ else
+ {
+ aChildToInsert->iParentPtr = this;
+ aChildToInsert->iNextSiblingPtr = nodeBefore->iNextSiblingPtr;
+ aChildToInsert->iPrevSiblingPtr = nodeBefore;
+ nodeBefore->iNextSiblingPtr = aChildToInsert;
+ aChildToInsert->iNextSiblingPtr->iPrevSiblingPtr = aChildToInsert;
+ }
+ }
+ return retVal;
+ }
+
+EXPORT_C TInt CMDXMLNode::AppendChild(CMDXMLNode* aChildToInsert)
+//
+// Appends a new child at the end of the child list.
+// @param aChildToInsert Pointer to the new child node to append.
+// @return Returns KErrNone if successful or KErrXMLInvalidChild if the node cannot have children
+//
+ {
+ TInt retVal = KErrNone;
+
+ if(aChildToInsert == NULL)
+ {
+ retVal = KErrNotSupported;
+ }
+ else if( !iCanHaveChildren )
+ {
+ retVal = KErrXMLInvalidChild;
+ }
+ else
+ {
+ if(iFirstChildPtr == NULL)
+ {
+ iFirstChildPtr = aChildToInsert;
+ }
+
+ if(iLastChildPtr != NULL)
+ {
+ iLastChildPtr->iNextSiblingPtr = aChildToInsert;
+ }
+
+ aChildToInsert->iPrevSiblingPtr = iLastChildPtr;
+ iLastChildPtr = aChildToInsert;
+ aChildToInsert->iParentPtr = this;
+ }
+ return retVal;
+ }
+
+EXPORT_C TInt CMDXMLNode::ReplaceChild(CMDXMLNode* aChildToInsert, CMDXMLNode* aChildToReplace)
+//
+// Inserts a new child node while removing an existing one. The old child is not deleted.
+// @param aChildToInsert Pointer to the new child node to insert.
+// @param aChildToReplace Pointer to the child node to be replaced.
+// @return Returns KErrNone if successful, KErrXMLInvalidChild if the node cannot have children or KErrNotFound if it cannot fnd the child to replace.
+//
+ {
+ TInt retVal = KErrNone;
+
+ if(aChildToInsert == NULL)
+ {
+ retVal = KErrNotSupported;
+ }
+ else if(aChildToReplace == NULL)
+ {
+ retVal = KErrNotFound;
+ }
+ else if( !iCanHaveChildren )
+ {
+ retVal = KErrXMLInvalidChild ;
+ }
+ else
+ {
+ if((aChildToReplace == iFirstChildPtr) && (aChildToReplace == iLastChildPtr))
+ { // Replace only child
+ iFirstChildPtr = aChildToInsert;
+ iLastChildPtr = aChildToInsert;
+ }
+ else if(aChildToReplace == iFirstChildPtr)
+ { // Replace first but not only
+ aChildToInsert->iNextSiblingPtr = iFirstChildPtr->iNextSiblingPtr;
+ aChildToInsert->iNextSiblingPtr->iPrevSiblingPtr = aChildToInsert;
+ iFirstChildPtr = aChildToInsert;
+ }
+ else if(aChildToReplace == iLastChildPtr)
+ { // Replace Last but not only
+ aChildToInsert->iPrevSiblingPtr = iLastChildPtr->iPrevSiblingPtr;
+ aChildToInsert->iPrevSiblingPtr->iNextSiblingPtr = aChildToInsert;
+ iLastChildPtr = aChildToInsert;
+ }
+ else if(iFirstChildPtr != NULL)
+ { // Replace in the middle of the list
+ CMDXMLNode* nodeBefore = iFirstChildPtr;
+ while((nodeBefore->iNextSiblingPtr != NULL) &&
+ (nodeBefore->iNextSiblingPtr != aChildToReplace))
+ {
+ nodeBefore = nodeBefore->iNextSiblingPtr;
+ }
+ if( nodeBefore->iNextSiblingPtr != aChildToReplace )
+ {
+ retVal = KErrNotFound;
+ }
+ else
+ { // found so just cross link
+ aChildToInsert->iNextSiblingPtr = aChildToReplace->iNextSiblingPtr;
+ aChildToInsert->iPrevSiblingPtr = aChildToReplace->iPrevSiblingPtr;
+ aChildToInsert->iPrevSiblingPtr->iNextSiblingPtr = aChildToInsert;
+ aChildToInsert->iNextSiblingPtr->iPrevSiblingPtr = aChildToInsert;
+ }
+ }
+ else
+ {
+ retVal = KErrNotFound;
+ }
+ }
+
+ if( retVal == KErrNone )
+ { // Clear out the replaced node
+ aChildToReplace->iPrevSiblingPtr = NULL;
+ aChildToReplace->iNextSiblingPtr = NULL;
+ aChildToReplace->iParentPtr = NULL;
+ // Point the new child at its parent
+ aChildToInsert->iParentPtr = this;
+ }
+ return retVal;
+ }
+
+// End Of File
+