xml/cxmllibrary/src/dom/src/node.c
changeset 27 450972dee096
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xml/cxmllibrary/src/dom/src/node.c	Tue Jul 06 16:24:52 2010 +0300
@@ -0,0 +1,538 @@
+/*
+* Copyright (c) 2000 - 2001 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: 
+*
+*/
+
+
+#include "cxml_internal.h"
+#include <xml/cxml/nw_dom_node.h>
+#include <xml/cxml/nw_dom_document.h>
+#include <xml/cxml/nw_dom_element.h>
+
+/**
+ * GENERAL NODE METHODS - applicable to all node types
+ * These methods will be repeated for other Node types also
+ **/
+
+/*
+ * RETURN 
+ * NW_STAT_SUCCESS
+ * NW_STAT_OUT_OF_MEMORY - If memory could not be allocated for storage
+ * NW_STAT_WBXML_ERROR_CHARSET_UNSUPPORTED - If encoding is not valid
+ * NW_STAT_DOM_NODE_TYPE_ERR - If node type is not a standard node type
+ * NW_STAT_DOM_NO_STRING_RETURNED - If the storage was not assigned to NW_DOM_String
+ *
+ * MODIFIED nodeName
+ */
+
+EXPORT_C NW_Status_t 
+NW_DOM_Node_getNodeName(NW_DOM_Node_t *node, NW_String_t *nodeName)
+{
+  NW_Uint16 type;
+  NW_String_UCS2Buff_t *name = NULL;
+  NW_DOM_DocumentNode_t *docNode;
+  NW_Uint32 encoding;
+  
+  NW_ASSERT(node != NULL);
+  NW_ASSERT(nodeName != NULL);  
+   
+  type = NW_DOM_Node_getNodeType(node);
+  if (type == 0){
+    return NW_STAT_DOM_NODE_TYPE_ERR;
+  }
+
+  switch (type) {
+    case NW_DOM_ELEMENT_NODE:
+      return NW_DOM_ElementNode_getTagName(node, nodeName);
+
+    case NW_DOM_PROCESSING_INSTRUCTION_NODE:/* Not supported */
+       return NW_STAT_DOM_NO_STRING_RETURNED;
+
+    case NW_DOM_TEXT_NODE:
+      name = (NW_String_UCS2Buff_t *) L"#text";
+      break;
+
+    case NW_DOM_DOCUMENT_NODE:
+      name = (NW_String_UCS2Buff_t *) L"#document";
+      break;
+
+    case NW_DOM_COMMENT_NODE:
+      name = (NW_String_UCS2Buff_t *) L"#comment";
+      break;
+
+    case NW_DOM_CDATA_SECTION_NODE:
+      name = (NW_String_UCS2Buff_t *) L"#cdata-section";
+      break;
+    default: 
+      return NW_STAT_DOM_NO_STRING_RETURNED;
+  }
+
+  docNode = NW_DOM_Node_getOwnerDocument(node);
+  if (docNode == NULL) {
+    return NW_STAT_DOM_NO_STRING_RETURNED;
+  }
+  encoding = NW_DOM_DocumentNode_getCharacterEncoding(docNode);
+    return NW_String_UCS2BuffToString(name, nodeName, encoding);    
+  }
+
+/* 
+ * returns NW_DOM_NodeType 
+ * Returns 0 if Node type is not one of the recognized nodes
+ */
+
+EXPORT_C NW_Uint16 
+NW_DOM_Node_getNodeType(NW_DOM_Node_t *node)
+{
+  NW_Uint16 type;
+
+  NW_ASSERT(node != NULL);
+
+  type = (NW_Uint16)(NW_TinyDom_Node_getType(node) & 0x0f);
+
+  switch(type) {
+
+  case T_DOM_NODE_DOC:
+    return NW_DOM_DOCUMENT_NODE;
+
+  case T_DOM_NODE_TAG:
+    return NW_DOM_ELEMENT_NODE;
+
+  case T_DOM_NODE_TEXT:
+    return NW_DOM_TEXT_NODE;
+
+  case T_DOM_NODE_PI:
+    return NW_DOM_PROCESSING_INSTRUCTION_NODE;
+
+  case T_DOM_NODE_COMMENT:
+    return NW_DOM_COMMENT_NODE;
+
+  case T_DOM_NODE_CDATASECTION:
+    return NW_DOM_CDATA_SECTION_NODE;
+
+  default:
+  return 0;
+}
+}
+
+/*  
+ * Returns fully qualified node token (including dictionary id)
+ * Returns 0 for invalid node
+ */
+EXPORT_C NW_Uint16 
+NW_DOM_Node_getNodeToken(NW_DOM_Node_t *node)
+{
+
+  NW_ASSERT(node != NULL);
+
+  if (NW_DOM_Node_getNodeType(node) == NW_DOM_ELEMENT_NODE){
+    return NW_DOM_ElementNode_getTagToken(node);
+  }
+  return 0;
+}
+
+/* 
+ * Returns NW_TRUE if the document is of WBXML type 
+ * otherwise returns NW_FALSE
+ */
+
+NW_Bool 
+NW_DOM_Node_isWBXML(NW_DOM_Node_t *node)
+{
+  NW_Uint16 type;
+
+  NW_ASSERT(node != NULL);
+
+  type = (NW_Uint16)(NW_TinyDom_Node_getType(node) & 0x8000);
+  
+  if (type == T_DOM_NODE_XML){
+    return NW_FALSE;
+  }
+  return NW_TRUE;
+}
+
+/* 
+ * Finds parent node of the given node
+ * returns NULL for DOCUMENT_NODE 
+ */
+
+EXPORT_C NW_DOM_Node_t * 
+NW_DOM_Node_getParentNode(NW_DOM_Node_t *node)
+{
+  NW_ASSERT (node != NULL); 
+
+  if (NW_DOM_Node_getNodeType(node) == NW_DOM_DOCUMENT_NODE)
+    return NULL;
+
+  return NW_TinyTree_findParent(node);
+}
+
+/* 
+ * Following 3 methods return valid values only
+ * for ELEMENT_NODE and DOCUMENT_NODE, since these are the 
+ * only nodes that have children. For other nodes, the value is
+ * either NULL or 0
+ */
+
+EXPORT_C NW_DOM_Node_t * 
+NW_DOM_Node_getFirstChild(NW_DOM_Node_t *node)
+{
+  NW_DOM_Node_t *child;
+
+  NW_ASSERT(node != NULL);
+
+  child = NW_TinyTree_findFirstChild(node);
+
+  if(child)
+  {
+      if(NW_TinyDom_Node_getType(child) == T_DOM_NODE_ATTR)
+        return NW_DOM_Node_getNextSibling(child);
+      else
+        return child;
+  }
+  return NULL;
+}
+
+EXPORT_C NW_DOM_Node_t * 
+NW_DOM_Node_getLastChild(NW_DOM_Node_t *node)
+{
+  NW_DOM_Node_t *currentNode = NULL;
+  NW_DOM_Node_t *previousNode = NULL;
+
+  NW_ASSERT(node != NULL);
+
+  currentNode = NW_DOM_Node_getFirstChild(node);
+  while (currentNode != NULL) 
+    {
+    previousNode = currentNode;
+    currentNode = NW_DOM_Node_getNextSibling(currentNode);
+  }
+  return previousNode;
+}
+
+EXPORT_C NW_Bool 
+NW_DOM_Node_hasChildNodes(NW_DOM_Node_t *node)
+{
+  
+  NW_ASSERT(node != NULL);
+  
+  if (NW_DOM_Node_getFirstChild(node))
+    return NW_TRUE;
+  return NW_FALSE;
+}
+
+EXPORT_C NW_DOM_Node_t * 
+NW_DOM_Node_getNextSibling(NW_DOM_Node_t *node)
+{
+  NW_DOM_Node_t *sibling;
+  
+  NW_ASSERT(node != NULL);
+ 
+  sibling = NW_TinyTree_findNextSibling(node);
+
+  if (sibling == NULL){
+    return NULL;
+  }
+
+  while ((sibling != NULL) && (NW_TinyDom_Node_getType(sibling) == T_DOM_NODE_ATTR)){
+    sibling = NW_TinyTree_findNextSibling(sibling);
+  }
+  return sibling;
+}
+
+EXPORT_C NW_DOM_Node_t * 
+NW_DOM_Node_getPreviousSibling(NW_DOM_Node_t *node)
+{
+  NW_DOM_Node_t *sibling;
+  NW_ASSERT(node != NULL);
+
+  sibling = NW_TinyTree_findPreviousSibling(node);
+
+  if (sibling == NULL)
+    return NULL;
+
+  while ((sibling != NULL) && (NW_TinyDom_Node_getType(sibling) == T_DOM_NODE_ATTR)){
+    sibling = NW_TinyTree_findPreviousSibling(sibling);
+  }
+
+  return sibling;
+}
+
+EXPORT_C NW_DOM_DocumentNode_t * 
+NW_DOM_Node_getOwnerDocument(NW_DOM_Node_t *node)
+{
+  NW_TinyTree_t *tiny_tree;
+
+  NW_ASSERT(node != NULL);
+
+  if (NW_DOM_Node_getNodeType(node) == NW_DOM_DOCUMENT_NODE){
+    return node;
+  }
+
+  tiny_tree = NW_TinyTree_Node_findTree(node);
+
+  return NW_TinyTree_getRoot(tiny_tree); 
+}
+
+/*********************
+ * NODE LIST ITERATOR
+ **********************/
+
+/*
+ * Returns NULL if unable to allocate memory
+ */
+
+NW_DOM_NodeIterator_t *
+NW_DOM_NodeIterator_new(void)
+{
+  return (NW_DOM_NodeIterator_t *) NW_Mem_Malloc(sizeof (NW_DOM_NodeIterator_t));
+}
+
+/*
+ * Initializes the Node handle which uses the given node
+ * as the starting point to iterate down the tree
+ * Returns NW_STAT_SUCCESS
+ *         NW_STAT_BAD_INPUT_PARAM
+ */
+
+NW_Status_t
+NW_DOM_NodeIterator_initialize(NW_DOM_NodeIterator_t *handle, 
+                               NW_DOM_Node_t *node, 
+                               NW_Uint16 token)
+{
+  NW_ASSERT (handle != NULL);
+  NW_ASSERT (node != NULL);
+
+  NW_TinyTree_NodeIterator_init(node, &handle->nodeIter);
+  handle->token = token;
+  return NW_STAT_SUCCESS;
+}
+
+/*
+ * Deletes the handle
+ * Returns NW_STAT_SUCCESS
+ */
+
+NW_Status_t
+NW_DOM_NodeIterator_delete(NW_DOM_NodeIterator_t *handle)
+{
+  
+  NW_ASSERT(handle != NULL);
+
+  NW_Mem_Free (handle);
+
+  return NW_STAT_SUCCESS;
+}
+
+/*
+ * Returns the next node
+ */
+
+NW_DOM_Node_t * 
+NW_DOM_NodeIterator_nextNode(NW_DOM_NodeIterator_t *handle)
+{
+  NW_DOM_Node_t* node = NULL;
+  NW_Uint16 token = 0;
+
+  NW_ASSERT(handle != NULL);
+  
+  do {
+
+    node = NW_TinyTree_NodeIterator_iterate(&handle->nodeIter);
+
+    if (node == NULL){
+      return NULL;
+    }
+
+    token = NW_DOM_Node_getNodeToken(node);
+
+  } while (token != handle->token);
+  
+  return node;
+}
+
+
+
+/**
+ * Inserts newChild before the refChild
+ * Returns one of:
+ *   NW_STAT_BAD_INPUT_PARAM
+ *   NW_STAT_SUCCESS
+ *   NW_STAT_NOT_FOUND - If reChild is not a child of given node
+ *   NW_STAT_DOM_WRONG_DOC_ERR - If newChild was created from a 
+ *        different document than the one that created the node
+ *   NW_STAT_DOM_HEIRARCHY_REQ_ERR - If node is of the type that 
+ *        does not allow children of the type of newChild node
+ */
+EXPORT_C NW_Status_t
+NW_DOM_Node_insertBefore(
+  NW_DOM_Node_t *node, 
+  NW_DOM_Node_t *newChild, 
+  NW_DOM_Node_t *refChild)
+{
+  NW_TinyTree_Node_t *child = NULL;
+  NW_DOM_DocumentNode_t *doc = NULL;
+  NW_DOM_DocumentNode_t *newDoc = NULL;
+  
+  if ((node == NULL) || (newChild == NULL) || (refChild == NULL))
+    return NW_STAT_BAD_INPUT_PARAM;
+
+  doc = NW_DOM_Node_getOwnerDocument(node);
+  newDoc = NW_DOM_Node_getOwnerDocument(newChild);
+
+  if ((doc == NULL) || (newDoc == NULL))
+    return NW_STAT_BAD_INPUT_PARAM;
+
+  if (doc != newDoc)
+    return NW_STAT_DOM_WRONG_DOC_ERR;
+
+  /* Only Element and Document nodes can have children */
+  if ((NW_DOM_Node_getNodeType(node) != NW_DOM_ELEMENT_NODE) &&
+      (NW_DOM_Node_getNodeType(node) != NW_DOM_DOCUMENT_NODE)) {
+    return NW_STAT_DOM_HEIRARCHY_REQUEST_ERR;
+  }
+
+  child = NW_DOM_Node_getFirstChild (node);
+  while (child)
+  {
+    if (child == refChild)
+    {
+      NW_TinyTree_attachBefore(child, newChild);
+      return NW_STAT_SUCCESS;
+    }
+    child = NW_DOM_Node_getNextSibling(child);
+  }
+  /* The refChild is not a child of node */
+  return NW_STAT_NOT_FOUND;
+}
+
+/**
+ * Replaces oldChild with the newChild and removes old child
+ * Returns one of:
+ *   NW_STAT_BAD_INPUT_PARAM
+ *   NW_STAT_SUCCESS
+ *   NW_STAT_NOT_FOUND - If oldChild is not a child of given node
+ *   NW_STAT_DOM_WRONG_DOC_ERR - If newChild was created from a 
+ *        different document than the one that created the node
+ *   NW_STAT_DOM_HEIRARCHY_REQ_ERR - If node is of the type that 
+ *        does not allow children of the type of newChild node
+ */
+
+EXPORT_C NW_Status_t
+NW_DOM_Node_replaceChild(NW_DOM_Node_t *node, NW_DOM_Node_t *newChild, NW_DOM_Node_t *oldChild)
+{
+  NW_TinyTree_Node_t *child = NULL;
+  NW_DOM_DocumentNode_t *doc = NULL;
+  NW_DOM_DocumentNode_t *newDoc = NULL;
+
+  if ((node == NULL) || (oldChild == NULL) || (newChild == NULL))
+    return NW_STAT_BAD_INPUT_PARAM;
+
+  doc = NW_DOM_Node_getOwnerDocument(node);
+  newDoc = NW_DOM_Node_getOwnerDocument(newChild);
+
+  if ((doc == NULL) || (newDoc == NULL))
+    return NW_STAT_BAD_INPUT_PARAM;
+
+  if (doc != newDoc)
+    return NW_STAT_DOM_WRONG_DOC_ERR;
+
+  /* Only Element and Document nodes can have children */
+  if ((NW_DOM_Node_getNodeType(node) != NW_DOM_ELEMENT_NODE) &&
+      (NW_DOM_Node_getNodeType(node) != NW_DOM_DOCUMENT_NODE)) {
+    return NW_STAT_DOM_HEIRARCHY_REQUEST_ERR;
+  }
+
+  child = NW_DOM_Node_getFirstChild (node);
+  while (child)
+  {
+    if (child == oldChild)
+    {
+      NW_TinyTree_attachBefore(oldChild, newChild);
+      return NW_DOM_Node_removeChild(node, oldChild);
+    }
+    child = NW_DOM_Node_getNextSibling(child);
+  }
+  /* The refChild is not a child of node */
+  return NW_STAT_NOT_FOUND;  
+}
+
+/*
+ * Removes the oldChild
+ * Returns one of:
+ *   NW_STAT_BAD_INPUT_PARAM
+ *   NW_STAT_SUCCESS
+ *   NW_STAT_NOT_FOUND - If oldChild is not a child of given node
+ */
+EXPORT_C NW_Status_t
+NW_DOM_Node_removeChild(NW_DOM_Node_t *node, NW_DOM_Node_t *oldChild)
+{
+  NW_TinyTree_Node_t *child = NULL;
+
+  if ((node == NULL) || (oldChild == NULL))
+    return NW_STAT_BAD_INPUT_PARAM;
+
+  child = NW_DOM_Node_getFirstChild (node);
+  while (child)
+  {
+    if (child == oldChild)
+    {
+      NW_TinyTree_deleteNode(oldChild);
+      return NW_STAT_SUCCESS;
+    }
+    child = NW_DOM_Node_getNextSibling(child);
+  }
+
+  /* The refChild is not a child of node */
+  return NW_STAT_NOT_FOUND;  
+}
+
+/*
+ * Appends a new child
+ * Returns one of:
+ *   NW_STAT_BAD_INPUT_PARAM
+ *   NW_STAT_SUCCESS
+ *   NW_STAT_DOM_WRONG_DOC_ERR - If newChild was created from a 
+ *        different document than the one that created the node
+ *   NW_STAT_DOM_HEIRARCHY_REQ_ERR - If node is of the type that 
+ *        does not allow children of the type of newChild node
+ */
+EXPORT_C NW_Status_t
+NW_DOM_Node_appendChild(NW_DOM_Node_t *node, NW_DOM_Node_t *newChild)
+{
+  NW_DOM_DocumentNode_t *doc = NULL;
+  NW_DOM_DocumentNode_t *newDoc = NULL;
+
+  if (( node == NULL) || (newChild == NULL))
+    return NW_STAT_BAD_INPUT_PARAM;
+
+  doc = NW_DOM_Node_getOwnerDocument(node);
+  newDoc = NW_DOM_Node_getOwnerDocument(newChild);
+
+ if ((doc == NULL) || (newDoc == NULL))
+    return NW_STAT_BAD_INPUT_PARAM;
+
+  if (doc != newDoc)
+    return NW_STAT_DOM_WRONG_DOC_ERR;
+
+  /* Only Element and Document nodes can have children */
+  if ((NW_DOM_Node_getNodeType(node) != NW_DOM_ELEMENT_NODE) &&
+      (NW_DOM_Node_getNodeType(node) != NW_DOM_DOCUMENT_NODE)) {
+    return NW_STAT_DOM_HEIRARCHY_REQUEST_ERR;
+  }
+
+  return(NW_TinyTree_attachChild(node, newChild));
+}
+
+