msxml3: Fix reference counting behaviour for named map.
This commit is contained in:
parent
88a4b618b1
commit
68cc66d800
|
@ -314,13 +314,13 @@ static HRESULT WINAPI domelem_get_nextSibling(
|
||||||
|
|
||||||
static HRESULT WINAPI domelem_get_attributes(
|
static HRESULT WINAPI domelem_get_attributes(
|
||||||
IXMLDOMElement *iface,
|
IXMLDOMElement *iface,
|
||||||
IXMLDOMNamedNodeMap** attributeMap)
|
IXMLDOMNamedNodeMap** map)
|
||||||
{
|
{
|
||||||
domelem *This = impl_from_IXMLDOMElement( iface );
|
domelem *This = impl_from_IXMLDOMElement( iface );
|
||||||
|
|
||||||
TRACE("(%p)->(%p)\n", This, attributeMap);
|
TRACE("(%p)->(%p)\n", This, map);
|
||||||
|
|
||||||
*attributeMap = create_nodemap((IXMLDOMNode*)&This->IXMLDOMElement_iface);
|
*map = create_nodemap(This->node.node);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ extern IUnknown *create_pi( xmlNodePtr pi );
|
||||||
extern IUnknown *create_comment( xmlNodePtr comment );
|
extern IUnknown *create_comment( xmlNodePtr comment );
|
||||||
extern IUnknown *create_cdata( xmlNodePtr text );
|
extern IUnknown *create_cdata( xmlNodePtr text );
|
||||||
extern IXMLDOMNodeList *create_children_nodelist( xmlNodePtr );
|
extern IXMLDOMNodeList *create_children_nodelist( xmlNodePtr );
|
||||||
extern IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node );
|
extern IXMLDOMNamedNodeMap *create_nodemap( const xmlNodePtr );
|
||||||
extern IUnknown *create_doc_Implementation(void);
|
extern IUnknown *create_doc_Implementation(void);
|
||||||
extern IUnknown *create_doc_fragment( xmlNodePtr fragment );
|
extern IUnknown *create_doc_fragment( xmlNodePtr fragment );
|
||||||
extern IUnknown *create_doc_entity_ref( xmlNodePtr entity );
|
extern IUnknown *create_doc_entity_ref( xmlNodePtr entity );
|
||||||
|
|
|
@ -48,7 +48,8 @@ typedef struct _xmlnodemap
|
||||||
IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface;
|
IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface;
|
||||||
ISupportErrorInfo ISupportErrorInfo_iface;
|
ISupportErrorInfo ISupportErrorInfo_iface;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
IXMLDOMNode *node;
|
|
||||||
|
xmlNodePtr node;
|
||||||
LONG iterator;
|
LONG iterator;
|
||||||
} xmlnodemap;
|
} xmlnodemap;
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ static ULONG WINAPI xmlnodemap_Release(
|
||||||
TRACE("(%p)->(%d)\n", This, ref);
|
TRACE("(%p)->(%d)\n", This, ref);
|
||||||
if ( ref == 0 )
|
if ( ref == 0 )
|
||||||
{
|
{
|
||||||
IXMLDOMNode_Release( This->node );
|
xmldoc_release( This->node->doc );
|
||||||
heap_free( This );
|
heap_free( This );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +218,6 @@ static HRESULT WINAPI xmlnodemap_setNamedItem(
|
||||||
{
|
{
|
||||||
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
||||||
xmlNodePtr nodeNew;
|
xmlNodePtr nodeNew;
|
||||||
xmlNodePtr node;
|
|
||||||
xmlnode *ThisNew;
|
xmlnode *ThisNew;
|
||||||
|
|
||||||
TRACE("(%p)->(%p %p)\n", This, newItem, namedItem );
|
TRACE("(%p)->(%p %p)\n", This, newItem, namedItem );
|
||||||
|
@ -227,10 +227,6 @@ static HRESULT WINAPI xmlnodemap_setNamedItem(
|
||||||
|
|
||||||
if(namedItem) *namedItem = NULL;
|
if(namedItem) *namedItem = NULL;
|
||||||
|
|
||||||
node = xmlNodePtr_from_domnode( This->node, 0 );
|
|
||||||
if ( !node )
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
/* Must be an Attribute */
|
/* Must be an Attribute */
|
||||||
ThisNew = get_node_obj( newItem );
|
ThisNew = get_node_obj( newItem );
|
||||||
if(!ThisNew) return E_FAIL;
|
if(!ThisNew) return E_FAIL;
|
||||||
|
@ -242,7 +238,7 @@ static HRESULT WINAPI xmlnodemap_setNamedItem(
|
||||||
if(xmldoc_remove_orphan(ThisNew->node->doc, ThisNew->node) != S_OK)
|
if(xmldoc_remove_orphan(ThisNew->node->doc, ThisNew->node) != S_OK)
|
||||||
WARN("%p is not an orphan of %p\n", ThisNew->node, ThisNew->node->doc);
|
WARN("%p is not an orphan of %p\n", ThisNew->node, ThisNew->node->doc);
|
||||||
|
|
||||||
nodeNew = xmlAddChild(node, ThisNew->node);
|
nodeNew = xmlAddChild(This->node, ThisNew->node);
|
||||||
|
|
||||||
if(namedItem)
|
if(namedItem)
|
||||||
*namedItem = create_node( nodeNew );
|
*namedItem = create_node( nodeNew );
|
||||||
|
@ -265,7 +261,6 @@ static HRESULT WINAPI xmlnodemap_get_item(
|
||||||
IXMLDOMNode** listItem)
|
IXMLDOMNode** listItem)
|
||||||
{
|
{
|
||||||
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
||||||
xmlNodePtr node;
|
|
||||||
xmlAttrPtr curr;
|
xmlAttrPtr curr;
|
||||||
LONG attrIndex;
|
LONG attrIndex;
|
||||||
|
|
||||||
|
@ -276,8 +271,7 @@ static HRESULT WINAPI xmlnodemap_get_item(
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
node = xmlNodePtr_from_domnode( This->node, 0 );
|
curr = This->node->properties;
|
||||||
curr = node->properties;
|
|
||||||
|
|
||||||
for (attrIndex = 0; attrIndex < index; attrIndex++) {
|
for (attrIndex = 0; attrIndex < index; attrIndex++) {
|
||||||
if (curr->next == NULL)
|
if (curr->next == NULL)
|
||||||
|
@ -295,7 +289,6 @@ static HRESULT WINAPI xmlnodemap_get_length(
|
||||||
IXMLDOMNamedNodeMap *iface,
|
IXMLDOMNamedNodeMap *iface,
|
||||||
LONG *listLength)
|
LONG *listLength)
|
||||||
{
|
{
|
||||||
xmlNodePtr node;
|
|
||||||
xmlAttrPtr first;
|
xmlAttrPtr first;
|
||||||
xmlAttrPtr curr;
|
xmlAttrPtr curr;
|
||||||
LONG attrCount;
|
LONG attrCount;
|
||||||
|
@ -307,11 +300,7 @@ static HRESULT WINAPI xmlnodemap_get_length(
|
||||||
if( !listLength )
|
if( !listLength )
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
node = xmlNodePtr_from_domnode( This->node, 0 );
|
first = This->node->properties;
|
||||||
if ( !node )
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
first = node->properties;
|
|
||||||
if (first == NULL) {
|
if (first == NULL) {
|
||||||
*listLength = 0;
|
*listLength = 0;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -336,7 +325,6 @@ static HRESULT WINAPI xmlnodemap_getQualifiedItem(
|
||||||
{
|
{
|
||||||
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
||||||
xmlAttrPtr attr;
|
xmlAttrPtr attr;
|
||||||
xmlNodePtr node;
|
|
||||||
xmlChar *href;
|
xmlChar *href;
|
||||||
xmlChar *name;
|
xmlChar *name;
|
||||||
|
|
||||||
|
@ -344,10 +332,6 @@ static HRESULT WINAPI xmlnodemap_getQualifiedItem(
|
||||||
|
|
||||||
if (!baseName || !qualifiedItem) return E_INVALIDARG;
|
if (!baseName || !qualifiedItem) return E_INVALIDARG;
|
||||||
|
|
||||||
node = xmlNodePtr_from_domnode(This->node, XML_ELEMENT_NODE);
|
|
||||||
if ( !node )
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
if (namespaceURI && *namespaceURI)
|
if (namespaceURI && *namespaceURI)
|
||||||
{
|
{
|
||||||
href = xmlChar_from_wchar(namespaceURI);
|
href = xmlChar_from_wchar(namespaceURI);
|
||||||
|
@ -363,7 +347,7 @@ static HRESULT WINAPI xmlnodemap_getQualifiedItem(
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr = xmlHasNsProp(node, name, href);
|
attr = xmlHasNsProp(This->node, name, href);
|
||||||
|
|
||||||
heap_free(name);
|
heap_free(name);
|
||||||
heap_free(href);
|
heap_free(href);
|
||||||
|
@ -387,7 +371,6 @@ static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
|
||||||
{
|
{
|
||||||
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
||||||
xmlAttrPtr attr;
|
xmlAttrPtr attr;
|
||||||
xmlNodePtr node;
|
|
||||||
xmlChar *name;
|
xmlChar *name;
|
||||||
xmlChar *href;
|
xmlChar *href;
|
||||||
|
|
||||||
|
@ -395,10 +378,6 @@ static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
|
||||||
|
|
||||||
if (!baseName) return E_INVALIDARG;
|
if (!baseName) return E_INVALIDARG;
|
||||||
|
|
||||||
node = xmlNodePtr_from_domnode( This->node, XML_ELEMENT_NODE );
|
|
||||||
if ( !node )
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
if (namespaceURI && *namespaceURI)
|
if (namespaceURI && *namespaceURI)
|
||||||
{
|
{
|
||||||
href = xmlChar_from_wchar(namespaceURI);
|
href = xmlChar_from_wchar(namespaceURI);
|
||||||
|
@ -414,7 +393,7 @@ static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr = xmlHasNsProp( node, name, href );
|
attr = xmlHasNsProp( This->node, name, href );
|
||||||
|
|
||||||
heap_free(name);
|
heap_free(name);
|
||||||
heap_free(href);
|
heap_free(href);
|
||||||
|
@ -445,7 +424,6 @@ static HRESULT WINAPI xmlnodemap_nextNode(
|
||||||
IXMLDOMNode** nextItem)
|
IXMLDOMNode** nextItem)
|
||||||
{
|
{
|
||||||
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
||||||
xmlNodePtr node;
|
|
||||||
xmlAttrPtr curr;
|
xmlAttrPtr curr;
|
||||||
LONG attrIndex;
|
LONG attrIndex;
|
||||||
|
|
||||||
|
@ -453,8 +431,7 @@ static HRESULT WINAPI xmlnodemap_nextNode(
|
||||||
|
|
||||||
*nextItem = NULL;
|
*nextItem = NULL;
|
||||||
|
|
||||||
node = xmlNodePtr_from_domnode( This->node, 0 );
|
curr = This->node->properties;
|
||||||
curr = node->properties;
|
|
||||||
|
|
||||||
for (attrIndex = 0; attrIndex < This->iterator; attrIndex++) {
|
for (attrIndex = 0; attrIndex < This->iterator; attrIndex++) {
|
||||||
if (curr->next == NULL)
|
if (curr->next == NULL)
|
||||||
|
@ -551,7 +528,7 @@ static const struct ISupportErrorInfoVtbl support_error_vtbl =
|
||||||
support_error_InterfaceSupportsErrorInfo
|
support_error_InterfaceSupportsErrorInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node )
|
IXMLDOMNamedNodeMap *create_nodemap( const xmlNodePtr node )
|
||||||
{
|
{
|
||||||
xmlnodemap *nodemap;
|
xmlnodemap *nodemap;
|
||||||
|
|
||||||
|
@ -565,8 +542,7 @@ IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node )
|
||||||
nodemap->ref = 1;
|
nodemap->ref = 1;
|
||||||
nodemap->iterator = 0;
|
nodemap->iterator = 0;
|
||||||
|
|
||||||
IXMLDOMNode_AddRef( node );
|
xmldoc_add_ref(node->doc);
|
||||||
/* Since we AddRef a node here, we don't need to call xmldoc_add_ref() */
|
|
||||||
|
|
||||||
return &nodemap->IXMLDOMNamedNodeMap_iface;
|
return &nodemap->IXMLDOMNamedNodeMap_iface;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8329,6 +8329,7 @@ static void test_get_nodeTypeString(void)
|
||||||
ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
|
ok(!lstrcmpW(str, _bstr_(entry->string)), "got string %s, expected %s. node type %d\n",
|
||||||
wine_dbgstr_w(str), entry->string, entry->type);
|
wine_dbgstr_w(str), entry->string, entry->type);
|
||||||
SysFreeString(str);
|
SysFreeString(str);
|
||||||
|
IXMLDOMNode_Release(node);
|
||||||
|
|
||||||
entry++;
|
entry++;
|
||||||
}
|
}
|
||||||
|
@ -8358,14 +8359,15 @@ static void test_get_attributes(void)
|
||||||
const get_attributes_t *entry = get_attributes;
|
const get_attributes_t *entry = get_attributes;
|
||||||
IXMLDOMNamedNodeMap *map;
|
IXMLDOMNamedNodeMap *map;
|
||||||
IXMLDOMDocument *doc;
|
IXMLDOMDocument *doc;
|
||||||
IXMLDOMNode *node;
|
IXMLDOMNode *node, *node2;
|
||||||
VARIANT_BOOL b;
|
VARIANT_BOOL b;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
BSTR str;
|
BSTR str;
|
||||||
|
LONG length;
|
||||||
|
|
||||||
doc = create_document(&IID_IXMLDOMDocument);
|
doc = create_document(&IID_IXMLDOMDocument);
|
||||||
|
|
||||||
str = SysAllocString( szComplete3 );
|
str = SysAllocString( szComplete4 );
|
||||||
hr = IXMLDOMDocument_loadXML(doc, str, &b);
|
hr = IXMLDOMDocument_loadXML(doc, str, &b);
|
||||||
SysFreeString(str);
|
SysFreeString(str);
|
||||||
|
|
||||||
|
@ -8403,6 +8405,43 @@ static void test_get_attributes(void)
|
||||||
|
|
||||||
IXMLDOMNode_Release(node);
|
IXMLDOMNode_Release(node);
|
||||||
|
|
||||||
|
/* last child is element */
|
||||||
|
EXPECT_REF(doc, 1);
|
||||||
|
hr = IXMLDOMDocument_get_lastChild(doc, &node);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
EXPECT_REF(doc, 1);
|
||||||
|
|
||||||
|
EXPECT_REF(node, 1);
|
||||||
|
hr = IXMLDOMNode_get_attributes(node, &map);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
EXPECT_REF(node, 1);
|
||||||
|
EXPECT_REF(doc, 1);
|
||||||
|
|
||||||
|
EXPECT_REF(map, 1);
|
||||||
|
hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
EXPECT_REF(node, 1);
|
||||||
|
EXPECT_REF(node2, 1);
|
||||||
|
EXPECT_REF(map, 1);
|
||||||
|
EXPECT_REF(doc, 1);
|
||||||
|
IXMLDOMNode_Release(node2);
|
||||||
|
|
||||||
|
/* release node before map release, map still works */
|
||||||
|
IXMLDOMNode_Release(node);
|
||||||
|
|
||||||
|
length = 0;
|
||||||
|
hr = IXMLDOMNamedNodeMap_get_length(map, &length);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
ok(length == 1, "got %d\n", length);
|
||||||
|
|
||||||
|
node2 = NULL;
|
||||||
|
hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node2);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
EXPECT_REF(node2, 1);
|
||||||
|
IXMLDOMNode_Release(node2);
|
||||||
|
|
||||||
|
IXMLDOMNamedNodeMap_Release(map);
|
||||||
|
|
||||||
while (entry->type)
|
while (entry->type)
|
||||||
{
|
{
|
||||||
VARIANT var;
|
VARIANT var;
|
||||||
|
@ -8423,6 +8462,8 @@ static void test_get_attributes(void)
|
||||||
hr, entry->hr, entry->type);
|
hr, entry->hr, entry->type);
|
||||||
ok(map == NULL, "got %p\n", map);
|
ok(map == NULL, "got %p\n", map);
|
||||||
|
|
||||||
|
IXMLDOMNode_Release(node);
|
||||||
|
|
||||||
entry++;
|
entry++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue