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(
|
||||
IXMLDOMElement *iface,
|
||||
IXMLDOMNamedNodeMap** attributeMap)
|
||||
IXMLDOMNamedNodeMap** map)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ extern IUnknown *create_pi( xmlNodePtr pi );
|
|||
extern IUnknown *create_comment( xmlNodePtr comment );
|
||||
extern IUnknown *create_cdata( xmlNodePtr text );
|
||||
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_fragment( xmlNodePtr fragment );
|
||||
extern IUnknown *create_doc_entity_ref( xmlNodePtr entity );
|
||||
|
|
|
@ -48,7 +48,8 @@ typedef struct _xmlnodemap
|
|||
IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface;
|
||||
ISupportErrorInfo ISupportErrorInfo_iface;
|
||||
LONG ref;
|
||||
IXMLDOMNode *node;
|
||||
|
||||
xmlNodePtr node;
|
||||
LONG iterator;
|
||||
} xmlnodemap;
|
||||
|
||||
|
@ -109,7 +110,7 @@ static ULONG WINAPI xmlnodemap_Release(
|
|||
TRACE("(%p)->(%d)\n", This, ref);
|
||||
if ( ref == 0 )
|
||||
{
|
||||
IXMLDOMNode_Release( This->node );
|
||||
xmldoc_release( This->node->doc );
|
||||
heap_free( This );
|
||||
}
|
||||
|
||||
|
@ -217,7 +218,6 @@ static HRESULT WINAPI xmlnodemap_setNamedItem(
|
|||
{
|
||||
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
||||
xmlNodePtr nodeNew;
|
||||
xmlNodePtr node;
|
||||
xmlnode *ThisNew;
|
||||
|
||||
TRACE("(%p)->(%p %p)\n", This, newItem, namedItem );
|
||||
|
@ -227,10 +227,6 @@ static HRESULT WINAPI xmlnodemap_setNamedItem(
|
|||
|
||||
if(namedItem) *namedItem = NULL;
|
||||
|
||||
node = xmlNodePtr_from_domnode( This->node, 0 );
|
||||
if ( !node )
|
||||
return E_FAIL;
|
||||
|
||||
/* Must be an Attribute */
|
||||
ThisNew = get_node_obj( newItem );
|
||||
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)
|
||||
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)
|
||||
*namedItem = create_node( nodeNew );
|
||||
|
@ -265,7 +261,6 @@ static HRESULT WINAPI xmlnodemap_get_item(
|
|||
IXMLDOMNode** listItem)
|
||||
{
|
||||
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
||||
xmlNodePtr node;
|
||||
xmlAttrPtr curr;
|
||||
LONG attrIndex;
|
||||
|
||||
|
@ -276,8 +271,7 @@ static HRESULT WINAPI xmlnodemap_get_item(
|
|||
if (index < 0)
|
||||
return S_FALSE;
|
||||
|
||||
node = xmlNodePtr_from_domnode( This->node, 0 );
|
||||
curr = node->properties;
|
||||
curr = This->node->properties;
|
||||
|
||||
for (attrIndex = 0; attrIndex < index; attrIndex++) {
|
||||
if (curr->next == NULL)
|
||||
|
@ -295,7 +289,6 @@ static HRESULT WINAPI xmlnodemap_get_length(
|
|||
IXMLDOMNamedNodeMap *iface,
|
||||
LONG *listLength)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
xmlAttrPtr first;
|
||||
xmlAttrPtr curr;
|
||||
LONG attrCount;
|
||||
|
@ -307,11 +300,7 @@ static HRESULT WINAPI xmlnodemap_get_length(
|
|||
if( !listLength )
|
||||
return E_INVALIDARG;
|
||||
|
||||
node = xmlNodePtr_from_domnode( This->node, 0 );
|
||||
if ( !node )
|
||||
return E_FAIL;
|
||||
|
||||
first = node->properties;
|
||||
first = This->node->properties;
|
||||
if (first == NULL) {
|
||||
*listLength = 0;
|
||||
return S_OK;
|
||||
|
@ -336,7 +325,6 @@ static HRESULT WINAPI xmlnodemap_getQualifiedItem(
|
|||
{
|
||||
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
||||
xmlAttrPtr attr;
|
||||
xmlNodePtr node;
|
||||
xmlChar *href;
|
||||
xmlChar *name;
|
||||
|
||||
|
@ -344,10 +332,6 @@ static HRESULT WINAPI xmlnodemap_getQualifiedItem(
|
|||
|
||||
if (!baseName || !qualifiedItem) return E_INVALIDARG;
|
||||
|
||||
node = xmlNodePtr_from_domnode(This->node, XML_ELEMENT_NODE);
|
||||
if ( !node )
|
||||
return E_FAIL;
|
||||
|
||||
if (namespaceURI && *namespaceURI)
|
||||
{
|
||||
href = xmlChar_from_wchar(namespaceURI);
|
||||
|
@ -363,7 +347,7 @@ static HRESULT WINAPI xmlnodemap_getQualifiedItem(
|
|||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
attr = xmlHasNsProp(node, name, href);
|
||||
attr = xmlHasNsProp(This->node, name, href);
|
||||
|
||||
heap_free(name);
|
||||
heap_free(href);
|
||||
|
@ -387,7 +371,6 @@ static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
|
|||
{
|
||||
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
||||
xmlAttrPtr attr;
|
||||
xmlNodePtr node;
|
||||
xmlChar *name;
|
||||
xmlChar *href;
|
||||
|
||||
|
@ -395,10 +378,6 @@ static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
|
|||
|
||||
if (!baseName) return E_INVALIDARG;
|
||||
|
||||
node = xmlNodePtr_from_domnode( This->node, XML_ELEMENT_NODE );
|
||||
if ( !node )
|
||||
return E_FAIL;
|
||||
|
||||
if (namespaceURI && *namespaceURI)
|
||||
{
|
||||
href = xmlChar_from_wchar(namespaceURI);
|
||||
|
@ -414,7 +393,7 @@ static HRESULT WINAPI xmlnodemap_removeQualifiedItem(
|
|||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
attr = xmlHasNsProp( node, name, href );
|
||||
attr = xmlHasNsProp( This->node, name, href );
|
||||
|
||||
heap_free(name);
|
||||
heap_free(href);
|
||||
|
@ -445,7 +424,6 @@ static HRESULT WINAPI xmlnodemap_nextNode(
|
|||
IXMLDOMNode** nextItem)
|
||||
{
|
||||
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
||||
xmlNodePtr node;
|
||||
xmlAttrPtr curr;
|
||||
LONG attrIndex;
|
||||
|
||||
|
@ -453,8 +431,7 @@ static HRESULT WINAPI xmlnodemap_nextNode(
|
|||
|
||||
*nextItem = NULL;
|
||||
|
||||
node = xmlNodePtr_from_domnode( This->node, 0 );
|
||||
curr = node->properties;
|
||||
curr = This->node->properties;
|
||||
|
||||
for (attrIndex = 0; attrIndex < This->iterator; attrIndex++) {
|
||||
if (curr->next == NULL)
|
||||
|
@ -551,7 +528,7 @@ static const struct ISupportErrorInfoVtbl support_error_vtbl =
|
|||
support_error_InterfaceSupportsErrorInfo
|
||||
};
|
||||
|
||||
IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node )
|
||||
IXMLDOMNamedNodeMap *create_nodemap( const xmlNodePtr node )
|
||||
{
|
||||
xmlnodemap *nodemap;
|
||||
|
||||
|
@ -565,8 +542,7 @@ IXMLDOMNamedNodeMap *create_nodemap( IXMLDOMNode *node )
|
|||
nodemap->ref = 1;
|
||||
nodemap->iterator = 0;
|
||||
|
||||
IXMLDOMNode_AddRef( node );
|
||||
/* Since we AddRef a node here, we don't need to call xmldoc_add_ref() */
|
||||
xmldoc_add_ref(node->doc);
|
||||
|
||||
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",
|
||||
wine_dbgstr_w(str), entry->string, entry->type);
|
||||
SysFreeString(str);
|
||||
IXMLDOMNode_Release(node);
|
||||
|
||||
entry++;
|
||||
}
|
||||
|
@ -8358,14 +8359,15 @@ static void test_get_attributes(void)
|
|||
const get_attributes_t *entry = get_attributes;
|
||||
IXMLDOMNamedNodeMap *map;
|
||||
IXMLDOMDocument *doc;
|
||||
IXMLDOMNode *node;
|
||||
IXMLDOMNode *node, *node2;
|
||||
VARIANT_BOOL b;
|
||||
HRESULT hr;
|
||||
BSTR str;
|
||||
LONG length;
|
||||
|
||||
doc = create_document(&IID_IXMLDOMDocument);
|
||||
|
||||
str = SysAllocString( szComplete3 );
|
||||
str = SysAllocString( szComplete4 );
|
||||
hr = IXMLDOMDocument_loadXML(doc, str, &b);
|
||||
SysFreeString(str);
|
||||
|
||||
|
@ -8403,6 +8405,43 @@ static void test_get_attributes(void)
|
|||
|
||||
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)
|
||||
{
|
||||
VARIANT var;
|
||||
|
@ -8423,6 +8462,8 @@ static void test_get_attributes(void)
|
|||
hr, entry->hr, entry->type);
|
||||
ok(map == NULL, "got %p\n", map);
|
||||
|
||||
IXMLDOMNode_Release(node);
|
||||
|
||||
entry++;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue