/*================================================================ * ixmlNode_insertBefore * Inserts the node newChild before the existing child node refChild. * If refChild is null, insert newChild at the end of the list of * children. If the newChild is already in the tree, it is first * removed. * External function. * Parameters: * newChild: the node to insert. * Returns: * *=================================================================*/ int ixmlNode_insertBefore( IN IXML_Node * nodeptr, IN IXML_Node * newChild, IN IXML_Node * refChild ) { int ret = IXML_SUCCESS; if( ( nodeptr == NULL ) || ( newChild == NULL ) ) { return IXML_INVALID_PARAMETER; } // whether nodeptr allow children of the type of newChild if( ixmlNode_allowChildren( nodeptr, newChild ) == FALSE ) { return IXML_HIERARCHY_REQUEST_ERR; } // or if newChild is one of nodeptr's ancestors if( ixmlNode_isAncestor( newChild, nodeptr ) == TRUE ) { return IXML_HIERARCHY_REQUEST_ERR; } // if newChild was created from a different document if( nodeptr->ownerDocument != newChild->ownerDocument ) { return IXML_WRONG_DOCUMENT_ERR; } // if refChild is not a child of nodeptr if( ixmlNode_isParent( nodeptr, refChild ) == FALSE ) { return IXML_NOT_FOUND_ERR; } if( refChild != NULL ) { if( ixmlNode_isParent( nodeptr, newChild ) == TRUE ) { ixmlNode_removeChild( nodeptr, newChild, NULL ); newChild->nextSibling = NULL; newChild->prevSibling = NULL; } newChild->nextSibling = refChild; if( refChild->prevSibling != NULL ) { ( refChild->prevSibling )->nextSibling = newChild; newChild->prevSibling = refChild->prevSibling; } refChild->prevSibling = newChild; if( newChild->prevSibling == NULL ) { nodeptr->firstChild = newChild; } newChild->parentNode = nodeptr; } else { ret = ixmlNode_appendChild( nodeptr, newChild ); } return ret; }
/*================================================================ * ixmlNode_isAncestor * check if ancestorNode is ancestor of toFind * Internal to parser only. * Returns: * TRUE or FALSE * *=================================================================*/ BOOL ixmlNode_isAncestor( IXML_Node * ancestorNode, IXML_Node * toFind ) { BOOL found = FALSE; if( ( ancestorNode != NULL ) && ( toFind != NULL ) ) { if( toFind->parentNode == ancestorNode ) { return TRUE; } else { found = ixmlNode_isAncestor( ancestorNode->firstChild, toFind ); if( found == FALSE ) { found = ixmlNode_isAncestor( ancestorNode->nextSibling, toFind ); } } } return found; }
/*! * \brief Check if ancestorNode is ancestor of toFind. * * \return TRUE or FALSE. */ static BOOL ixmlNode_isAncestor( /*! [in] The candidate to ancestor \b Node. */ IXML_Node *ancestorNode, /*! [in] The \b Node to check for an ancestor. */ IXML_Node *toFind) { BOOL found = FALSE; if (ancestorNode != NULL && toFind != NULL) { if (toFind->parentNode == ancestorNode) { return TRUE; } else { found = ixmlNode_isAncestor( ancestorNode->firstChild, toFind); if (found == FALSE) { found = ixmlNode_isAncestor( ancestorNode->nextSibling, toFind); } } } return found; }
/*============================================================================= * ixmlNode_appendChild * Adds the node newChild to the end of the list of children of this node. * If the newChild is already in the tree, it is first removed. * External function. * Parameter: * newChild: the node to add. * Return Value: * IXML_SUCCESS * IXML_INVALID_PARAMETER: if either nodeptr or newChild is NULL * IXML_WRONG_DOCUMENT_ERR: if newChild was created from a different document than * the one that created nodeptr. * IXML_HIERARCHY_REQUEST_ERR: if newChild is ancestor of nodeptr or if nodeptr is of * a type that does not allow children of the type of the * newChild node. * *=================================================================*/ int ixmlNode_appendChild( IN IXML_Node * nodeptr, IN IXML_Node * newChild ) { IXML_Node *prev = NULL, *next = NULL; if( ( nodeptr == NULL ) || ( newChild == NULL ) ) { return IXML_INVALID_PARAMETER; } // if newChild was created from a different document if( ( newChild->ownerDocument != NULL ) && ( nodeptr->ownerDocument != newChild->ownerDocument ) ) { return IXML_WRONG_DOCUMENT_ERR; } // if newChild is an ancestor of nodeptr if( ixmlNode_isAncestor( newChild, nodeptr ) == TRUE ) { return IXML_HIERARCHY_REQUEST_ERR; } // if nodeptr does not allow to have newChild as children if( ixmlNode_allowChildren( nodeptr, newChild ) == FALSE ) { return IXML_HIERARCHY_REQUEST_ERR; } if( ixmlNode_isParent( nodeptr, newChild ) == TRUE ) { ixmlNode_removeChild( nodeptr, newChild, NULL ); } // set the parent node pointer newChild->parentNode = nodeptr; newChild->ownerDocument = nodeptr->ownerDocument; //if the first child if( nodeptr->firstChild == NULL ) { nodeptr->firstChild = newChild; } else { prev = nodeptr->firstChild; next = prev->nextSibling; while( next != NULL ) { prev = next; next = prev->nextSibling; } prev->nextSibling = newChild; newChild->prevSibling = prev; } return IXML_SUCCESS; }
/*================================================================ * ixmlNode_replaceChild * Replaces the child node oldChild with newChild in the list of children, * and returns the oldChild node. * External function. * Parameters: * newChild: the new node to put in the child list. * oldChild: the node being replaced in the list. * returnNode: the node replaced. * Return Value: * IXML_SUCCESS * IXML_INVALID_PARAMETER: if anyone of nodeptr, newChild or oldChild is NULL. * IXML_HIERARCHY_REQUEST_ERR: if the newChild is ancestor of nodeptr or nodeptr * is of a type that does not allow children of the * type of the newChild node. * IXML_WRONG_DOCUMENT_ERR: if newChild was created from a different document than * the one that created this node. * IXML_NOT_FOUND_ERR: if oldChild is not a child of nodeptr. * *=================================================================*/ int ixmlNode_replaceChild( IN IXML_Node * nodeptr, IN IXML_Node * newChild, IN IXML_Node * oldChild, OUT IXML_Node ** returnNode ) { int ret = IXML_SUCCESS; if( ( nodeptr == NULL ) || ( newChild == NULL ) || ( oldChild == NULL ) ) { return IXML_INVALID_PARAMETER; } // if nodetype of nodeptr does not allow children of the type of newChild // needs to add later // or if newChild is one of nodeptr's ancestors if( ixmlNode_isAncestor( newChild, nodeptr ) == TRUE ) { return IXML_HIERARCHY_REQUEST_ERR; } if( ixmlNode_allowChildren( nodeptr, newChild ) == FALSE ) { return IXML_HIERARCHY_REQUEST_ERR; } // if newChild was created from a different document if( nodeptr->ownerDocument != newChild->ownerDocument ) { return IXML_WRONG_DOCUMENT_ERR; } // if refChild is not a child of nodeptr if( ixmlNode_isParent( nodeptr, oldChild ) != TRUE ) { return IXML_NOT_FOUND_ERR; } ret = ixmlNode_insertBefore( nodeptr, newChild, oldChild ); if( ret != IXML_SUCCESS ) { return ret; } ret = ixmlNode_removeChild( nodeptr, oldChild, returnNode ); return ret; }