/*
* Node.c : implementation of the Node interface as defined by
* Document Object Model (Core) Level 1
* http://www.w3.org/TR/WD-DOM/level-one-core.html
*
* Daniel.Veillard@w3.org
*
* $Id: Node.c,v 1.2 1998/06/14 03:20:17 daniel Exp $
*/
#include "config.h"
#include <stdio.h>
#include "Node.h"
#include "NodeIterator.h"
/*
* Returns the type of the node (DOM_NODE_xxx).
*/
int getNodeType(domNodePtr node) {
if (node == NULL) return(-1);
return((int) node->type);
}
/*
* Return the parent node if available (document roots don't have
* parents).
*/
domNodePtr getParentNode(domNodePtr node) {
if (node == NULL) return(NULL);
return(node->parent);
}
/*
* Create a NodeIterator starting at the first child.
*/
domNodeIteratorPtr getChildNodes(domNodePtr node) {
if (node == NULL) return(NULL);
/* TODO !!!! */
return(NULL);
}
/*
* Interrogation : has child ?
*/
int hasChildNodes(domNodePtr node) {
if (node == NULL) return(-1);
return(node->childs == NULL ? 0 : 1);
}
/*
* Navigation : get first child
*/
domNodePtr getFirstChild(domNodePtr node) {
if (node == NULL) return(NULL);
return(node->childs);
}
/*
* Navigation : previous sibling
*/
domNodePtr getPreviousSibling(domNodePtr node) {
if (node == NULL) return(NULL);
return(node->prev);
}
/*
* Navigation : next sibling
*/
domNodePtr getNextSibling(domNodePtr node) {
if (node == NULL) return(NULL);
return(node->next);
}
/*
* Insert a child before another one. If defChild is null,
* the new one is appended at the end of the list.
* NOTE: the DOM spec ask to trigger a NotMyChildException
* the C language mapping is to return NULL !
*/
domNodePtr insertBefore(domNodePtr node, domNodePtr newChild,
domNodePtr refChild) {
domNodePtr cur;
if (node == NULL) return(NULL);
if (newChild == NULL) {
return(removeChild(node, refChild));
}
if (refChild == NULL) {
if (node->lastchild == NULL) {
if (node->childs != NULL) {
fprintf(stderr,
"Node %x corrupted, lastchild == NULL, childs = %x\n",
(int) node, (int) node->childs);
return(NULL);
}
newChild->next = newChild->prev = NULL;
newChild->parent = node;
node->lastchild = node->childs = newChild;
} else {
cur = node->lastchild;
newChild->next = cur->next;
cur->next = newChild;
newChild->prev = cur;
newChild->parent = node;
node->lastchild = newChild;
}
}
/* TODO if (refChild->parent != node) */
cur = node->childs;
while (cur != NULL) {
if (cur == refChild) {
/* Link in the new node */
newChild->parent = node;
newChild->prev = cur->prev;
cur->prev = newChild;
newChild->next = cur;
if (newChild->prev == NULL)
node->childs = newChild;
else
newChild->prev->next = newChild;
return(newChild);
}
cur = cur->next;
}
return(NULL);
}
/*
* Replace one child by another one. If oldChild is null,
* the new one is appended at the end of the list.
* NOTE: the DOM spec ask to trigger a NotMyChildException
* the C language mapping is to return NULL !
*/
domNodePtr replaceChild(domNodePtr node, domNodePtr newChild,
domNodePtr oldChild) {
domNodePtr cur;
if (node == NULL) return(NULL);
if (newChild == NULL) {
return(removeChild(node, oldChild));
}
if (oldChild == NULL) return(NULL);
/* TODO if (oldChild->parent != node) */
cur = node->childs;
while (cur != NULL) {
if (cur == oldChild) {
/* Link in the new node */
newChild->parent = node;
newChild->prev = cur->prev;
newChild->next = cur->next;
if (newChild->prev == NULL)
node->childs = newChild;
else
newChild->prev->next = newChild;
if (newChild->next == NULL)
node->lastchild = newChild;
else
newChild->next->prev = newChild;
/* unlink the old node */
cur->prev = NULL;
cur->next = NULL;
cur->parent = NULL;
return(cur);
}
cur = cur->next;
}
return(NULL);
}
/*
* Remove a Child.
* NOTE: the DOM spec ask to trigger a NotMyChildException
* the C language mapping is to return NULL !
*/
domNodePtr removeChild(domNodePtr node, domNodePtr oldChild) {
domNodePtr cur;
if (node == NULL) return(NULL);
if (oldChild == NULL) return(NULL);
/* TODO if (oldChild->parent != node) */
cur = node->childs;
while (cur != NULL) {
if (cur == oldChild) {
if (cur->prev == NULL)
node->childs = cur->next;
else
cur->prev->next = cur->next;
if (cur->next == NULL)
node->lastchild = cur->prev;
else
cur->next->prev = cur->prev;
cur->prev = NULL;
cur->next = NULL;
cur->parent = NULL;
return(cur);
}
cur = cur->next;
}
return(NULL);
}
Webmaster