msxml3: Fix reference counting behaviour for named map.

This commit is contained in:
Nikolay Sivov 2011-03-10 21:56:51 +03:00 committed by Alexandre Julliard
parent 88a4b618b1
commit 68cc66d800
4 changed files with 58 additions and 41 deletions

View File

@ -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;
}

View File

@ -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 );

View File

@ -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;
}

View File

@ -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++;
}