Module: wine Branch: master Commit: 6fe686f599a013026cf2a5cff50690f11ae88ffb URL: http://source.winehq.org/git/wine.git/?a=commit;h=6fe686f599a013026cf2a5cff5...
Author: Michael Karcher wine@mkarcher.dialup.fu-berlin.de Date: Tue Oct 7 11:55:01 2008 +0200
msxml3: Basic implementation of IXMLDOMNode::replaceChild.
---
dlls/msxml3/node.c | 39 +++++++++++++++++++++++++++++++++++++-- dlls/msxml3/tests/domdoc.c | 22 +++++++++++++--------- 2 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index b82ef55..27c8e53 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -610,6 +610,9 @@ static HRESULT WINAPI xmlnode_replaceChild( IXMLDOMNode** outOldChild) { xmlnode *This = impl_from_IXMLDOMNode( iface ); + xmlNode *old_child_ptr, *new_child_ptr; + xmlDocPtr leaving_doc; + xmlNode *my_ancestor;
TRACE("%p->(%p,%p,%p)\n",This,newChild,oldChild,outOldChild);
@@ -618,8 +621,40 @@ static HRESULT WINAPI xmlnode_replaceChild( if(!newChild || !oldChild) return E_INVALIDARG;
- FIXME("not implemented\n"); - return E_NOTIMPL; + if(outOldChild) + *outOldChild = NULL; + + old_child_ptr = impl_from_IXMLDOMNode(oldChild)->node; + if(old_child_ptr->parent != This->node) + { + WARN("childNode %p is not a child of %p\n", oldChild, iface); + return E_INVALIDARG; + } + + new_child_ptr = impl_from_IXMLDOMNode(newChild)->node; + my_ancestor = This->node; + while(my_ancestor) + { + if(my_ancestor == new_child_ptr) + { + WARN("tried to create loop\n"); + return E_FAIL; + } + my_ancestor = my_ancestor->parent; + } + + leaving_doc = new_child_ptr->doc; + xmldoc_add_ref(old_child_ptr->doc); + xmlReplaceNode(old_child_ptr, new_child_ptr); + xmldoc_release(leaving_doc); + + if(outOldChild) + { + IXMLDOMNode_AddRef(oldChild); + *outOldChild = oldChild; + } + + return S_OK; }
static HRESULT WINAPI xmlnode_removeChild( diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 57d8689..85c19cc 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -1843,7 +1843,7 @@ static void test_replaceChild(void) VARIANT_BOOL b; IXMLDOMDocument *doc; IXMLDOMElement *element; - IXMLDOMNode *fo_node, *ba_node, *removed_node, *temp_node; + IXMLDOMNode *fo_node, *ba_node, *lc_node, *removed_node, *temp_node; IXMLDOMNodeList *root_list, *fo_list; IUnknown * unk1, *unk2; long len; @@ -1865,6 +1865,9 @@ static void test_replaceChild(void) r = IXMLDOMElement_get_childNodes( element, &root_list ); ok( r == S_OK, "ret %08x\n", r);
+ r = IXMLDOMNodeList_get_item( root_list, 0, &lc_node ); + ok( r == S_OK, "ret %08x\n", r); + r = IXMLDOMNodeList_get_item( root_list, 3, &fo_node ); ok( r == S_OK, "ret %08x\n", r);
@@ -1890,13 +1893,14 @@ static void test_replaceChild(void)
/* invalid parameter: OldNode is not a child */ removed_node = (void*)0xdeadbeef; - r = IXMLDOMElement_replaceChild( element, ba_node, ba_node, &removed_node ); - todo_wine ok( r == E_INVALIDARG, "ret %08x\n", r ); - if( r == E_NOTIMPL) - { - skip("replaceChild not implemented\n"); - return; - } + r = IXMLDOMElement_replaceChild( element, lc_node, ba_node, &removed_node ); + ok( r == E_INVALIDARG, "ret %08x\n", r ); + ok( removed_node == NULL, "%p\n", removed_node ); + + /* invalid parameter: would create loop */ + removed_node = (void*)0xdeadbeef; + r = IXMLDOMNode_replaceChild( fo_node, fo_node, ba_node, &removed_node ); + ok( r == E_FAIL, "ret %08x\n", r ); ok( removed_node == NULL, "%p\n", removed_node );
r = IXMLDOMElement_replaceChild( element, ba_node, fo_node, NULL ); @@ -1912,7 +1916,7 @@ static void test_replaceChild(void) ok( r == S_OK, "ret %08x\n", r ); r = IXMLDOMNode_QueryInterface( ba_node, &IID_IUnknown, (void**)&unk2); ok( r == S_OK, "ret %08x\n", r ); - ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2); + todo_wine ok( unk1 == unk2, "unk1 %p unk2 %p\n", unk1, unk2);
IUnknown_Release( unk1 ); IUnknown_Release( unk2 );