File:  [Public] / DOM / Node.c
Revision 1.2: download - view: text, annotated - select for diffs
Sun Jun 14 03:20:17 1998 UTC (26 years ago) by daniel
Branches: MAIN
CVS tags: HEAD
More work done on the core, Daniel.

/*
 * 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