Nikolay Sivov : msxml3: Partially implement ::setAttributeNode().

Alexandre Julliard julliard at winehq.org
Thu Oct 21 10:50:45 CDT 2010


Module: wine
Branch: master
Commit: 88adaa06179703c567427f6bc744a658df60cd29
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=88adaa06179703c567427f6bc744a658df60cd29

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Oct 21 02:07:20 2010 +0400

msxml3: Partially implement ::setAttributeNode().

---

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

diff --git a/dlls/msxml3/element.c b/dlls/msxml3/element.c
index a3834ff..8e33dd2 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;
 }
@@ -705,16 +705,61 @@ 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);
+        heap_free(name);
+        heap_free(value);
+        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 fd56c61..d7d94e6 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -6853,20 +6853,29 @@ 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);
+
+    IXMLDOMElement_Release(elem);
 
+    /* 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 */




More information about the wine-cvs mailing list