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

View File

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

View File

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

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", 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++;
} }