static HRESULT WINAPI xmlnodemap_setNamedItem( IXMLDOMNamedNodeMap *iface, IXMLDOMNode* newItem, IXMLDOMNode** namedItem) { xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); xmlNodePtr nodeNew; xmlnode *ThisNew; TRACE("(%p)->(%p %p)\n", This, newItem, namedItem ); if(!newItem) return E_INVALIDARG; if(namedItem) *namedItem = NULL; /* Must be an Attribute */ ThisNew = get_node_obj( newItem ); if(!ThisNew) return E_FAIL; if(ThisNew->node->type != XML_ATTRIBUTE_NODE) return E_FAIL; if(!ThisNew->node->parent) if(xmldoc_remove_orphan(ThisNew->node->doc, ThisNew->node) != S_OK) WARN("%p is not an orphan of %p\n", ThisNew->node, ThisNew->node->doc); nodeNew = xmlAddChild(This->node, ThisNew->node); if(namedItem) *namedItem = create_node( nodeNew ); return S_OK; }
HRESULT node_clone(xmlnode *This, VARIANT_BOOL deep, IXMLDOMNode **cloneNode) { IXMLDOMNode *node; xmlNodePtr clone; if(!cloneNode) return E_INVALIDARG; clone = xmlCopyNode(This->node, deep ? 1 : 2); if (clone) { xmlSetTreeDoc(clone, This->node->doc); xmldoc_add_orphan(clone->doc, clone); node = create_node(clone); if (!node) { ERR("Copy failed\n"); xmldoc_remove_orphan(clone->doc, clone); xmlFreeNode(clone); return E_FAIL; } *cloneNode = node; } else { ERR("Copy failed\n"); return E_FAIL; } return S_OK; }
HRESULT node_replace_child(xmlnode *This, IXMLDOMNode *newChild, IXMLDOMNode *oldChild, IXMLDOMNode **ret) { xmlnode *old_child, *new_child; xmlDocPtr leaving_doc; xmlNode *my_ancestor; int refcount = 0; /* Do not believe any documentation telling that newChild == NULL means removal. It does certainly *not* apply to msxml3! */ if(!newChild || !oldChild) return E_INVALIDARG; if(ret) *ret = NULL; old_child = get_node_obj(oldChild); if(!old_child) return E_FAIL; if(old_child->node->parent != This->node) { WARN("childNode %p is not a child of %p\n", oldChild, This); return E_INVALIDARG; } new_child = get_node_obj(newChild); if(!new_child) return E_FAIL; my_ancestor = This->node; while(my_ancestor) { if(my_ancestor == new_child->node) { WARN("tried to create loop\n"); return E_FAIL; } my_ancestor = my_ancestor->parent; } if(!new_child->node->parent) if(xmldoc_remove_orphan(new_child->node->doc, new_child->node) != S_OK) WARN("%p is not an orphan of %p\n", new_child->node, new_child->node->doc); leaving_doc = new_child->node->doc; if (leaving_doc != old_child->node->doc) refcount = xmlnode_get_inst_cnt(new_child); if (refcount) xmldoc_add_refs(old_child->node->doc, refcount); xmlReplaceNode(old_child->node, new_child->node); if (refcount) xmldoc_release_refs(leaving_doc, refcount); new_child->parent = old_child->parent; old_child->parent = NULL; xmldoc_add_orphan(old_child->node->doc, old_child->node); if(ret) { IXMLDOMNode_AddRef(oldChild); *ret = oldChild; } return S_OK; }
HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT *ref_child, IXMLDOMNode **ret) { IXMLDOMNode *before = NULL; xmlnode *node_obj; int refcount = 0; xmlDocPtr doc; HRESULT hr; if(!new_child) return E_INVALIDARG; node_obj = get_node_obj(new_child); if(!node_obj) return E_FAIL; switch(V_VT(ref_child)) { case VT_EMPTY: case VT_NULL: break; case VT_UNKNOWN: case VT_DISPATCH: if (V_UNKNOWN(ref_child)) { hr = IUnknown_QueryInterface(V_UNKNOWN(ref_child), &IID_IXMLDOMNode, (void**)&before); if(FAILED(hr)) return hr; } break; default: FIXME("refChild var type %x\n", V_VT(ref_child)); return E_FAIL; } TRACE("new child %p, This->node %p\n", node_obj->node, This->node); if(!node_obj->node->parent) if(xmldoc_remove_orphan(node_obj->node->doc, node_obj->node) != S_OK) WARN("%p is not an orphan of %p\n", node_obj->node, node_obj->node->doc); refcount = xmlnode_get_inst_cnt(node_obj); if(before) { xmlnode *before_node_obj = get_node_obj(before); IXMLDOMNode_Release(before); if(!before_node_obj) return E_FAIL; /* unlink from current parent first */ if(node_obj->parent) { hr = IXMLDOMNode_removeChild(node_obj->parent, node_obj->iface, NULL); if (hr == S_OK) xmldoc_remove_orphan(node_obj->node->doc, node_obj->node); } doc = node_obj->node->doc; /* refs count including subtree */ if (doc != before_node_obj->node->doc) refcount = xmlnode_get_inst_cnt(node_obj); if (refcount) xmldoc_add_refs(before_node_obj->node->doc, refcount); xmlAddPrevSibling(before_node_obj->node, node_obj->node); if (refcount) xmldoc_release_refs(doc, refcount); node_obj->parent = This->parent; } else { /* unlink from current parent first */ if(node_obj->parent) { hr = IXMLDOMNode_removeChild(node_obj->parent, node_obj->iface, NULL); if (hr == S_OK) xmldoc_remove_orphan(node_obj->node->doc, node_obj->node); } doc = node_obj->node->doc; if (doc != This->node->doc) refcount = xmlnode_get_inst_cnt(node_obj); if (refcount) xmldoc_add_refs(This->node->doc, refcount); /* xmlAddChild doesn't unlink node from previous parent */ xmlUnlinkNode(node_obj->node); xmlAddChild(This->node, node_obj->node); if (refcount) xmldoc_release_refs(doc, refcount); node_obj->parent = This->iface; } if(ret) { IXMLDOMNode_AddRef(new_child); *ret = new_child; } TRACE("ret S_OK\n"); return S_OK; }