From 0adfd6cf4c4f5b512c10ab2a5f4c77de13a8fa2a Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sat, 4 Sep 2010 18:41:10 +0400 Subject: [PATCH] msxml3/domdoc: Implement IXMLDOMNamedNodeMap::removeQualifiedItem(). --- dlls/msxml3/nodemap.c | 99 ++++++++++++++++++++++---------------- dlls/msxml3/tests/domdoc.c | 70 ++++++++++++++++++++++++++- 2 files changed, 125 insertions(+), 44 deletions(-) diff --git a/dlls/msxml3/nodemap.c b/dlls/msxml3/nodemap.c index f7818f9e265..78d9d469c63 100644 --- a/dlls/msxml3/nodemap.c +++ b/dlls/msxml3/nodemap.c @@ -250,43 +250,8 @@ static HRESULT WINAPI xmlnodemap_removeNamedItem( IXMLDOMNode** namedItem) { xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); - xmlChar *element_name; - xmlAttrPtr attr; - xmlNodePtr node; - TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), namedItem ); - - if ( !name) - return E_INVALIDARG; - - node = xmlNodePtr_from_domnode( This->node, 0 ); - if ( !node ) - return E_FAIL; - - element_name = xmlChar_from_wchar( name ); - attr = xmlHasNsProp( node, element_name, NULL ); - heap_free( element_name ); - - if ( !attr ) - { - if( namedItem ) - *namedItem = NULL; - return S_FALSE; - } - - if ( namedItem ) - { - xmlUnlinkNode( (xmlNodePtr) attr ); - xmldoc_add_orphan( attr->doc, (xmlNodePtr) attr ); - *namedItem = create_node( (xmlNodePtr) attr ); - } - else - { - if( xmlRemoveProp( attr ) == -1 ) - ERR("xmlRemoveProp failed\n"); - } - - return S_OK; + return IXMLDOMNamedNodeMap_removeQualifiedItem(iface, name, NULL, namedItem); } static HRESULT WINAPI xmlnodemap_get_item( @@ -394,6 +359,10 @@ static HRESULT WINAPI xmlnodemap_getQualifiedItem( } attr = xmlHasNsProp(node, name, href); + + heap_free(name); + heap_free(href); + if (!attr) { *qualifiedItem = NULL; @@ -402,9 +371,6 @@ static HRESULT WINAPI xmlnodemap_getQualifiedItem( *qualifiedItem = create_node((xmlNodePtr)attr); - heap_free(name); - heap_free(href); - return S_OK; } @@ -415,8 +381,58 @@ static HRESULT WINAPI xmlnodemap_removeQualifiedItem( IXMLDOMNode** qualifiedItem) { xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); - FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), qualifiedItem); - return E_NOTIMPL; + xmlAttrPtr attr; + xmlNodePtr node; + xmlChar *name; + xmlChar *href; + + TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(baseName), debugstr_w(namespaceURI), qualifiedItem); + + if (!baseName) return E_INVALIDARG; + + node = xmlNodePtr_from_domnode( This->node, XML_ELEMENT_NODE ); + if ( !node ) + return E_FAIL; + + if (namespaceURI && *namespaceURI) + { + href = xmlChar_from_wchar(namespaceURI); + if (!href) return E_OUTOFMEMORY; + } + else + href = NULL; + + name = xmlChar_from_wchar(baseName); + if (!name) + { + heap_free(href); + return E_OUTOFMEMORY; + } + + attr = xmlHasNsProp( node, name, href ); + + heap_free(name); + heap_free(href); + + if ( !attr ) + { + if (qualifiedItem) *qualifiedItem = NULL; + return S_FALSE; + } + + if ( qualifiedItem ) + { + xmlUnlinkNode( (xmlNodePtr) attr ); + xmldoc_add_orphan( attr->doc, (xmlNodePtr) attr ); + *qualifiedItem = create_node( (xmlNodePtr) attr ); + } + else + { + if (xmlRemoveProp(attr) == -1) + ERR("xmlRemoveProp failed\n"); + } + + return S_OK; } static HRESULT WINAPI xmlnodemap_nextNode( @@ -497,7 +513,6 @@ static HRESULT WINAPI support_error_QueryInterface( { xmlnodemap *This = impl_from_ISupportErrorInfo( iface ); TRACE("%p %s %p\n", iface, debugstr_guid(riid), ppvObject); - return IXMLDOMNamedNodeMap_QueryInterface((IXMLDOMNamedNodeMap*)&This->lpVtbl, riid, ppvObject); } diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 8211aec1b03..ded817584fc 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -2791,7 +2791,7 @@ static void test_removeNamedItem(void) removed_node = (void*)0xdeadbeef; r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, NULL, &removed_node); ok ( r == E_INVALIDARG, "ret %08x\n", r); - ok ( removed_node == (void*)0xdeadbeef, "removed_node == %p\n", removed_node); + ok ( removed_node == (void*)0xdeadbeef, "got %p\n", removed_node); removed_node = (void*)0xdeadbeef; str = SysAllocString(szvr); @@ -2801,7 +2801,7 @@ static void test_removeNamedItem(void) removed_node2 = (void*)0xdeadbeef; r = IXMLDOMNamedNodeMap_removeNamedItem( pr_attrs, str, &removed_node2); ok ( r == S_FALSE, "ret %08x\n", r); - ok ( removed_node2 == NULL, "removed_node == %p\n", removed_node2 ); + ok ( removed_node2 == NULL, "got %p\n", removed_node2 ); r = IXMLDOMNamedNodeMap_get_length( pr_attrs, &len ); ok( r == S_OK, "ret %08x\n", r); @@ -5789,6 +5789,71 @@ static void test_getQualifiedItem(void) free_bstrs(); } +static void test_removeQualifiedItem(void) +{ + IXMLDOMDocument *doc; + IXMLDOMElement *element; + IXMLDOMNode *pr_node, *node; + IXMLDOMNodeList *root_list; + IXMLDOMNamedNodeMap *map; + VARIANT_BOOL b; + BSTR str; + LONG len; + HRESULT hr; + + doc = create_document(&IID_IXMLDOMDocument); + if (!doc) return; + + str = SysAllocString( szComplete4 ); + hr = IXMLDOMDocument_loadXML( doc, str, &b ); + ok( hr == S_OK, "loadXML failed\n"); + ok( b == VARIANT_TRUE, "failed to load XML string\n"); + SysFreeString( str ); + + hr = IXMLDOMDocument_get_documentElement(doc, &element); + ok( hr == S_OK, "ret %08x\n", hr); + + hr = IXMLDOMElement_get_childNodes(element, &root_list); + ok( hr == S_OK, "ret %08x\n", hr); + + hr = IXMLDOMNodeList_get_item(root_list, 1, &pr_node); + ok( hr == S_OK, "ret %08x\n", hr); + IXMLDOMNodeList_Release(root_list); + + hr = IXMLDOMNode_get_attributes(pr_node, &map); + ok( hr == S_OK, "ret %08x\n", hr); + IXMLDOMNode_Release(pr_node); + + hr = IXMLDOMNamedNodeMap_get_length(map, &len); + ok( hr == S_OK, "ret %08x\n", hr); + ok( len == 3, "length %d\n", len); + + hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, NULL); + ok( hr == E_INVALIDARG, "ret %08x\n", hr); + + node = (void*)0xdeadbeef; + hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, NULL, NULL, &node); + ok( hr == E_INVALIDARG, "ret %08x\n", hr); + ok( node == (void*)0xdeadbeef, "got %p\n", node); + + /* out pointer is optional */ + hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL); + ok( hr == S_OK, "ret %08x\n", hr); + + /* already removed */ + hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("id"), NULL, NULL); + ok( hr == S_FALSE, "ret %08x\n", hr); + + hr = IXMLDOMNamedNodeMap_removeQualifiedItem(map, _bstr_("vr"), NULL, &node); + ok( hr == S_OK, "ret %08x\n", hr); + IXMLDOMNode_Release(node); + + IXMLDOMNamedNodeMap_Release( map ); + IXMLDOMElement_Release( element ); + IXMLDOMDocument_Release( doc ); + free_bstrs(); +} + START_TEST(domdoc) { IXMLDOMDocument *doc; @@ -5840,6 +5905,7 @@ START_TEST(domdoc) test_document_IObjectSafety(); test_splitText(); test_getQualifiedItem(); + test_removeQualifiedItem(); CoUninitialize(); }