[PATCH 2/3] msxml3: Copy namespaces as attributes.
Daniel Lehman
dlehman25 at gmail.com
Sun Aug 26 11:27:22 CDT 2018
Signed-off-by: Daniel Lehman <dlehman25 at gmail.com>
---
dlls/msxml3/nodemap.c | 123 ++++++++++++++++++++++++++++++++++++-
dlls/msxml3/tests/domdoc.c | 2 +-
2 files changed, 122 insertions(+), 3 deletions(-)
diff --git a/dlls/msxml3/nodemap.c b/dlls/msxml3/nodemap.c
index a9fef4769d..b35fd34103 100644
--- a/dlls/msxml3/nodemap.c
+++ b/dlls/msxml3/nodemap.c
@@ -39,6 +39,7 @@
#include "msxml_private.h"
#include "wine/debug.h"
+#include "wine/list.h"
#ifdef HAVE_LIBXML2
@@ -54,10 +55,17 @@ typedef struct
xmlNodePtr node;
LONG iterator;
IEnumVARIANT *enumvariant;
+ struct list nsattrs;
const struct nodemap_funcs *funcs;
} xmlnodemap;
+typedef struct
+{
+ struct list entry;
+ xmlAttrPtr attr;
+} nsattr_entry;
+
static HRESULT nodemap_get_item(IUnknown *iface, LONG index, VARIANT *item)
{
V_VT(item) = VT_DISPATCH;
@@ -140,9 +148,20 @@ static ULONG WINAPI xmlnodemap_Release(
TRACE("(%p)->(%d)\n", This, ref);
if ( ref == 0 )
{
+ nsattr_entry *nsattr;
+ struct list *head;
+
xmlnode_release( This->node );
xmldoc_release( This->node->doc );
if (This->enumvariant) IEnumVARIANT_Release(This->enumvariant);
+ while ((head = list_head( &This->nsattrs )))
+ {
+ list_remove( head );
+ nsattr = LIST_ENTRY( head, nsattr_entry, entry );
+ xmlFreeNs( nsattr->attr->ns );
+ xmlFreeProp( nsattr->attr );
+ heap_free( nsattr );
+ }
heap_free( This );
}
@@ -224,16 +243,102 @@ static HRESULT WINAPI xmlnodemap_removeNamedItem(
return This->funcs->remove_named_item(This->node, name, namedItem);
}
+static HRESULT copy_ns_as_attrs(xmlnodemap *This)
+{
+ xmlNsPtr ns;
+ xmlNsPtr cur;
+ xmlAttrPtr prop;
+ nsattr_entry *entry;
+
+ cur = This->node->nsDef;
+ while (cur)
+ {
+ entry = heap_alloc(sizeof(*entry));
+ if (!entry)
+ return E_OUTOFMEMORY;
+
+ ns = xmlNewNs(NULL, BAD_CAST "http://www.w3.org/2000/xmlns/", BAD_CAST "xmlns");
+ if (!ns)
+ {
+ heap_free(entry);
+ return E_OUTOFMEMORY;
+ }
+
+ prop = xmlNewNsProp(NULL, ns, cur->prefix, cur->href);
+ if (!prop)
+ {
+ xmlFreeNs(ns);
+ heap_free(entry);
+ return E_OUTOFMEMORY;
+ }
+
+ prop->doc = This->node->doc;
+ entry->attr = prop;
+ list_add_tail(&This->nsattrs, &entry->entry);
+
+ cur = cur->next;
+ }
+
+ return S_OK;
+}
+
static HRESULT WINAPI xmlnodemap_get_item(
IXMLDOMNamedNodeMap *iface,
LONG index,
IXMLDOMNode** item)
{
+ HRESULT hr;
+ xmlAttrPtr cur;
+ struct list *ptr;
+ nsattr_entry *nsattr;
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
TRACE("(%p)->(%d %p)\n", This, index, item);
- return This->funcs->get_item(This->node, index, item);
+ hr = This->funcs->get_item(This->node, index, item);
+ if (hr != S_FALSE)
+ return hr;
+
+ ptr = list_head(&This->nsattrs);
+ if (!ptr)
+ {
+ if (!This->node->nsDef)
+ return S_FALSE;
+
+ if (This->node->nsDef)
+ {
+ hr = copy_ns_as_attrs(This);
+ if (FAILED(hr))
+ return hr;
+ }
+
+ ptr = list_head(&This->nsattrs);
+ if (!ptr)
+ return FALSE;
+ }
+
+ if (This->node->properties)
+ {
+ --index;
+ cur = This->node->properties;
+ while (cur->next)
+ {
+ --index;
+ cur = cur->next;
+ }
+ }
+
+ if (index < 0)
+ return S_FALSE;
+
+ while (index--)
+ ptr = list_next(ptr, ptr);
+
+ nsattr = LIST_ENTRY(ptr, nsattr_entry, entry);
+ cur = nsattr->attr;
+ *item = create_node((xmlNodePtr) cur);
+
+ return S_OK;
}
static HRESULT WINAPI xmlnodemap_get_length(
@@ -241,10 +346,23 @@ static HRESULT WINAPI xmlnodemap_get_length(
LONG *length)
{
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
+ xmlNsPtr cur;
+ HRESULT hr;
TRACE("(%p)->(%p)\n", This, length);
- return This->funcs->get_length(This->node, length);
+ hr = This->funcs->get_length(This->node, length);
+ if (FAILED(hr))
+ return hr;
+
+ cur = This->node->nsDef;
+ while (cur)
+ {
+ ++*length;
+ cur = cur->next;
+ }
+
+ return S_OK;
}
static HRESULT WINAPI xmlnodemap_getQualifiedItem(
@@ -447,6 +565,7 @@ IXMLDOMNamedNodeMap *create_nodemap(xmlNodePtr node, const struct nodemap_funcs
This->ref = 1;
This->iterator = 0;
This->enumvariant = NULL;
+ list_init(&This->nsattrs);
This->funcs = funcs;
init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNamedNodeMap_iface, &xmlnodemap_dispex);
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index ffb9e1462d..667feaa244 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -12894,7 +12894,7 @@ void test_namespaces_as_attributes(void)
len = -1;
hr = IXMLDOMNamedNodeMap_get_length(map, &len);
EXPECT_HR(hr, S_OK);
- todo_wine ok(len == 3, "got %d\n", len);
+ ok(len == 3, "got %d\n", len);
for (i = 0; i < len; i++)
{
--
2.17.1
More information about the wine-devel
mailing list