[PATCH 4/4] Partially implement ::setAttributeNode()

Nikolay Sivov nsivov at codeweavers.com
Sat Oct 16 17:45:49 CDT 2010


---
 dlls/msxml3/element.c      |   55 +++++++++++++++++++++++++++++++++++++++----
 dlls/msxml3/tests/domdoc.c |   21 ++++++++++++----
 2 files changed, 65 insertions(+), 11 deletions(-)

diff --git a/dlls/msxml3/element.c b/dlls/msxml3/element.c
index c4fd389..66648fd 100644
--- a/dlls/msxml3/element.c
+++ b/dlls/msxml3/element.c
@@ -50,7 +50,7 @@ static inline domelem *impl_from_IXMLDOMElement( IXMLDOMElement *iface )
     return (domelem *)((char*)iface - FIELD_OFFSET(domelem, lpVtbl));
 }
 
-static inline xmlNodePtr get_element( domelem *This )
+static inline xmlNodePtr get_element( const domelem *This )
 {
     return This->node.node;
 }
@@ -690,16 +690,59 @@ static HRESULT WINAPI domelem_getAttributeNode(
 
 static HRESULT WINAPI domelem_setAttributeNode(
     IXMLDOMElement *iface,
-    IXMLDOMAttribute* domAttribute,
-    IXMLDOMAttribute** attributeNode)
+    IXMLDOMAttribute* attribute,
+    IXMLDOMAttribute** old)
 {
     domelem *This = impl_from_IXMLDOMElement( iface );
+    xmlChar *name, *value;
+    BSTR nameW, prefix;
+    xmlAttrPtr attr;
+    VARIANT valueW;
+    HRESULT hr;
 
-    FIXME("(%p)->(%p %p)\n", This, domAttribute, attributeNode);
+    FIXME("(%p)->(%p %p): semi-stub\n", This, attribute, old);
 
-    if(!domAttribute) return E_INVALIDARG;
+    if (!attribute) return E_INVALIDARG;
 
-    return E_NOTIMPL;
+    if (old) *old = NULL;
+
+    hr = IXMLDOMAttribute_get_nodeName(attribute, &nameW);
+    if (hr != S_OK) return hr;
+
+    hr = IXMLDOMAttribute_get_nodeValue(attribute, &valueW);
+    if (hr != S_OK)
+    {
+        SysFreeString(nameW);
+        return hr;
+    }
+
+    TRACE("attribute: %s=%s\n", debugstr_w(nameW), debugstr_w(V_BSTR(&valueW)));
+
+    hr = IXMLDOMAttribute_get_prefix(attribute, &prefix);
+    if (hr == S_OK)
+    {
+        FIXME("namespaces not supported: %s\n", debugstr_w(prefix));
+        SysFreeString(prefix);
+    }
+
+    name = xmlChar_from_wchar(nameW);
+    value = xmlChar_from_wchar(V_BSTR(&valueW));
+
+    if (!name || !value)
+    {
+        SysFreeString(nameW);
+        VariantClear(&valueW);
+        return E_OUTOFMEMORY;
+    }
+
+    attr = xmlSetNsProp(get_element(This), NULL, name, value);
+
+    SysFreeString(nameW);
+    VariantClear(&valueW);
+    heap_free(name);
+    heap_free(value);
+
+    return attr ? S_OK : E_FAIL;
 }
 
 static HRESULT WINAPI domelem_removeAttributeNode(
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index a4db4d9..93d4ab0 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -6830,6 +6830,7 @@ static void test_setAttributeNode(void)
     VARIANT_BOOL b;
     HRESULT hr;
     BSTR str;
+    LONG ref;
 
     doc = create_document(&IID_IXMLDOMDocument);
     if (!doc) return;
@@ -6853,20 +6854,30 @@ static void test_setAttributeNode(void)
 
     ret_attr = (void*)0xdeadbeef;
     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
-    todo_wine ok( hr == S_OK, "got 0x%08x\n", hr);
-    todo_wine ok( ret_attr == NULL, "got %p\n", ret_attr);
+    ok( hr == S_OK, "got 0x%08x\n", hr);
+    ok( ret_attr == NULL, "got %p\n", ret_attr);
 
     attr2 = NULL;
     hr = IXMLDOMElement_getAttributeNode(elem, _bstr_("attr"), &attr2);
-    todo_wine ok( hr == S_OK, "got 0x%08x\n", hr);
-    if (attr2) IXMLDOMAttribute_Release(attr2);
+    ok( hr == S_OK, "got 0x%08x\n", hr);
+    IXMLDOMAttribute_Release(attr2);
 
     /* try to add it another time */
     ret_attr = (void*)0xdeadbeef;
     hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
     todo_wine ok( hr == E_FAIL, "got 0x%08x\n", hr);
-    ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
+    todo_wine ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
+
+    ref = IXMLDOMElement_Release(elem);
+    ok(ref == 0, "got %d\n", ref);
 
+    /* initialy used element is released attribute still 'has' a container */
+    hr = IXMLDOMDocument_get_documentElement(doc, &elem);
+    ok( hr == S_OK, "got 0x%08x\n", hr);
+    ret_attr = (void*)0xdeadbeef;
+    hr = IXMLDOMElement_setAttributeNode(elem, attr, &ret_attr);
+    todo_wine ok( hr == E_FAIL, "got 0x%08x\n", hr);
+    todo_wine ok( ret_attr == (void*)0xdeadbeef, "got %p\n", ret_attr);
     IXMLDOMElement_Release(elem);
 
     /* add attribute already attached to another document */
-- 
1.5.6.5



--------------010005080009040008060109--



More information about the wine-patches mailing list