[MSXML3] Sync with Wine Staging 1.7.55. CORE-10536
[reactos.git] / reactos / dll / win32 / msxml3 / element.c
index cfc4165..5addf33 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-
-#define COBJMACROS
-
-#include <config.h>
-
-//#include <stdarg.h>
-#ifdef HAVE_LIBXML2
-# include <libxml/parser.h>
-//# include <libxml/xmlerror.h>
-#endif
-
-#include <windef.h>
-#include <winbase.h>
-//#include "winuser.h"
-//#include "winnls.h"
-#include <ole2.h>
-#include <msxml6.h>
-
-#include "msxml_private.h"
-
-#include <wine/debug.h>
-
-WINE_DEFAULT_DEBUG_CHANNEL(msxml);
+#include "precomp.h"
 
 #ifdef HAVE_LIBXML2
 
@@ -61,7 +37,7 @@ static const struct nodemap_funcs domelem_attr_map;
 static const tid_t domelem_se_tids[] = {
     IXMLDOMNode_tid,
     IXMLDOMElement_tid,
-    0
+    NULL_tid
 };
 
 static inline domelem *impl_from_IXMLDOMElement( IXMLDOMElement *iface )
@@ -304,13 +280,29 @@ static HRESULT WINAPI domelem_get_attributes(
 static HRESULT WINAPI domelem_insertBefore(
     IXMLDOMElement *iface,
     IXMLDOMNode* newNode, VARIANT refChild,
-    IXMLDOMNode** outOldNode)
+    IXMLDOMNode** old_node)
 {
     domelem *This = impl_from_IXMLDOMElement( iface );
+    DOMNodeType type;
+    HRESULT hr;
 
-    TRACE("(%p)->(%p %s %p)\n", This, newNode, debugstr_variant(&refChild), outOldNode);
+    TRACE("(%p)->(%p %s %p)\n", This, newNode, debugstr_variant(&refChild), old_node);
 
-    return node_insert_before(&This->node, newNode, &refChild, outOldNode);
+    hr = IXMLDOMNode_get_nodeType(newNode, &type);
+    if (hr != S_OK) return hr;
+
+    TRACE("new node type %d\n", type);
+    switch (type)
+    {
+        case NODE_DOCUMENT:
+        case NODE_DOCUMENT_TYPE:
+        case NODE_ENTITY:
+        case NODE_NOTATION:
+            if (old_node) *old_node = NULL;
+            return E_FAIL;
+        default:
+            return node_insert_before(&This->node, newNode, &refChild, old_node);
+    }
 }
 
 static HRESULT WINAPI domelem_replaceChild(
@@ -739,7 +731,7 @@ static HRESULT encode_base64(const BYTE *buf, int len, BSTR *ret)
 {
     static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     const BYTE *d = buf;
-    int bytes, pad_bytes, div, i;
+    int bytes, pad_bytes, div;
     DWORD needed;
     WCHAR *ptr;
 
@@ -756,7 +748,6 @@ static HRESULT encode_base64(const BYTE *buf, int len, BSTR *ret)
     div = len / 3;
 
     ptr = *ret;
-    i = 0;
     while (div > 0)
     {
         /* first char is the first 6 bits of the first byte*/
@@ -769,7 +760,6 @@ static HRESULT encode_base64(const BYTE *buf, int len, BSTR *ret)
         *ptr++ = b64[ ((d[1] << 2) & 0x3c) | (d[2] >> 6 & 0x03)];
         /* fourth char is the remaining 6 bits of the third byte */
         *ptr++ = b64[   d[2]       & 0x3f];
-        i += 4;
         d += 3;
         div--;
     }
@@ -1192,7 +1182,9 @@ static HRESULT WINAPI domelem_getAttribute(
     domelem *This = impl_from_IXMLDOMElement( iface );
     xmlNodePtr element;
     xmlChar *xml_name, *xml_value = NULL;
+    xmlChar *local, *prefix;
     HRESULT hr = S_FALSE;
+    xmlNsPtr ns;
 
     TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), value);
 
@@ -1211,7 +1203,28 @@ static HRESULT WINAPI domelem_getAttribute(
     if(!xmlValidateNameValue(xml_name))
         hr = E_FAIL;
     else
-        xml_value = xmlGetNsProp(element, xml_name, NULL);
+    {
+        if ((local = xmlSplitQName2(xml_name, &prefix)))
+        {
+            if (xmlStrEqual(prefix, BAD_CAST "xmlns"))
+            {
+                ns = xmlSearchNs(element->doc, element, local);
+                if (ns)
+                    xml_value = xmlStrdup(ns->href);
+            }
+            else
+            {
+                ns = xmlSearchNs(element->doc, element, prefix);
+                if (ns)
+                    xml_value = xmlGetNsProp(element, local, ns->href);
+            }
+
+            xmlFree(prefix);
+            xmlFree(local);
+        }
+        else
+            xml_value = xmlGetNsProp(element, xml_name, NULL);
+    }
 
     heap_free(xml_name);
     if(xml_value)
@@ -1232,8 +1245,7 @@ static HRESULT WINAPI domelem_setAttribute(
     domelem *This = impl_from_IXMLDOMElement( iface );
     xmlChar *xml_name, *xml_value, *local, *prefix;
     xmlNodePtr element;
-    HRESULT hr;
-    VARIANT var;
+    HRESULT hr = S_OK;
 
     TRACE("(%p)->(%s %s)\n", This, debugstr_w(name), debugstr_variant(&value));
 
@@ -1241,16 +1253,25 @@ static HRESULT WINAPI domelem_setAttribute(
     if ( !element )
         return E_FAIL;
 
-    VariantInit(&var);
-    hr = VariantChangeType(&var, &value, 0, VT_BSTR);
-    if(hr != S_OK)
+    if (V_VT(&value) != VT_BSTR)
     {
-        FIXME("VariantChangeType failed\n");
-        return hr;
+        VARIANT var;
+
+        VariantInit(&var);
+        hr = VariantChangeType(&var, &value, 0, VT_BSTR);
+        if (hr != S_OK)
+        {
+            FIXME("VariantChangeType failed\n");
+            return hr;
+        }
+
+        xml_value = xmlchar_from_wchar(V_BSTR(&var));
+        VariantClear(&var);
     }
+    else
+        xml_value = xmlchar_from_wchar(V_BSTR(&value));
 
     xml_name = xmlchar_from_wchar( name );
-    xml_value = xmlchar_from_wchar( V_BSTR(&var) );
 
     if ((local = xmlSplitQName2(xml_name, &prefix)))
     {
@@ -1265,7 +1286,12 @@ static HRESULT WINAPI domelem_setAttribute(
         xmlFree(local);
 
         if (ns)
-            return xmlStrEqual(ns->href, xml_value) ? S_OK : E_INVALIDARG;
+        {
+            int cmp = xmlStrEqual(ns->href, xml_value);
+            heap_free(xml_value);
+            heap_free(xml_name);
+            return cmp ? S_OK : E_INVALIDARG;
+        }
     }
 
     if (!xmlSetNsProp(element, NULL, xml_name, xml_value))
@@ -1273,7 +1299,6 @@ static HRESULT WINAPI domelem_setAttribute(
 
     heap_free(xml_value);
     heap_free(xml_name);
-    VariantClear(&var);
 
     return hr;
 }