msxml3: Track linked/unlinked state for element and free node data only when unlinked.

This commit is contained in:
Nikolay Sivov 2010-01-15 00:18:32 +03:00 committed by Alexandre Julliard
parent 20e63dcfd1
commit f9cb63116d
4 changed files with 16 additions and 7 deletions

View File

@ -135,7 +135,7 @@ extern LONG xmldoc_release( xmlDocPtr doc );
extern HRESULT xmldoc_add_orphan( xmlDocPtr doc, xmlNodePtr node );
extern HRESULT xmldoc_remove_orphan( xmlDocPtr doc, xmlNodePtr node );
extern HRESULT XMLElement_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj );
extern HRESULT XMLElement_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj, BOOL own );
extern xmlDocPtr parse_xml(char *ptr, int len);

View File

@ -523,6 +523,7 @@ static void test_xmlelem_children(void)
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
ok(child2 != NULL, "Expected not NULL child\n");
IXMLElementCollection_Release(collection);
IXMLElement_Release(child2);
/* add element->child->child2 structure, then remove child2 from node */
V_VT(&vType) = VT_I4;

View File

@ -209,7 +209,7 @@ static HRESULT WINAPI xmldoc_get_root(IXMLDocument *iface, IXMLElement **p)
if (!(root = xmlDocGetRootElement(This->xmldoc)))
return E_FAIL;
return XMLElement_create((IUnknown *)This, root, (LPVOID *)p);
return XMLElement_create((IUnknown *)This, root, (LPVOID *)p, FALSE);
}
static HRESULT WINAPI xmldoc_get_fileSize(IXMLDocument *iface, BSTR *p)
@ -520,7 +520,7 @@ static HRESULT WINAPI xmldoc_createElement(IXMLDocument *iface, VARIANT vType,
node->type = type_msxml_to_libxml(V_I4(&vType));
/* FIXME: create xmlNodePtr based on vType and var1 */
return XMLElement_create((IUnknown *)iface, node, (LPVOID *)ppElem);
return XMLElement_create((IUnknown *)iface, node, (LPVOID *)ppElem, TRUE);
}
static const struct IXMLDocumentVtbl xmldoc_vtbl =

View File

@ -48,6 +48,7 @@ typedef struct _xmlelem
const IXMLElementVtbl *lpVtbl;
LONG ref;
xmlNodePtr node;
BOOL own;
} xmlelem;
static inline xmlelem *impl_from_IXMLElement(IXMLElement *iface)
@ -94,6 +95,7 @@ static ULONG WINAPI xmlelem_Release(IXMLElement *iface)
ref = InterlockedDecrement(&This->ref);
if (ref == 0)
{
if (This->own) xmlFreeNode(This->node);
HeapFree(GetProcessHeap(), 0, This);
}
@ -212,7 +214,7 @@ static HRESULT WINAPI xmlelem_get_parent(IXMLElement *iface, IXMLElement **paren
if (!This->node->parent)
return S_FALSE;
return XMLElement_create((IUnknown *)iface, This->node->parent, (LPVOID *)parent);
return XMLElement_create((IUnknown *)iface, This->node->parent, (LPVOID *)parent, FALSE);
}
static HRESULT WINAPI xmlelem_setAttribute(IXMLElement *iface, BSTR strPropertyName,
@ -407,6 +409,9 @@ static HRESULT WINAPI xmlelem_addChild(IXMLElement *iface, IXMLElement *pChildEl
else
child = xmlAddNextSibling(This->node, childElem->node->last);
/* parent is responsible for child data */
if (child) childElem->own = FALSE;
return (child) ? S_OK : S_FALSE;
}
@ -425,6 +430,8 @@ static HRESULT WINAPI xmlelem_removeChild(IXMLElement *iface, IXMLElement *pChil
return E_INVALIDARG;
xmlUnlinkNode(childElem->node);
/* standalone element now */
childElem->own = TRUE;
return S_OK;
}
@ -452,7 +459,7 @@ static const struct IXMLElementVtbl xmlelem_vtbl =
xmlelem_removeChild
};
HRESULT XMLElement_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj)
HRESULT XMLElement_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj, BOOL own)
{
xmlelem *elem;
@ -470,6 +477,7 @@ HRESULT XMLElement_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj)
elem->lpVtbl = &xmlelem_vtbl;
elem->ref = 1;
elem->node = node;
elem->own = own;
*ppObj = &elem->lpVtbl;
@ -652,7 +660,7 @@ static HRESULT WINAPI xmlelem_collection_item(IXMLElementCollection *iface, VARI
for (i = 0; i < index; i++)
ptr = ptr->next;
return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)ppDisp);
return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)ppDisp, FALSE);
}
static const struct IXMLElementCollectionVtbl xmlelem_collection_vtbl =
@ -712,7 +720,7 @@ static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Next(
This->current = This->current->next;
V_VT(rgVar) = VT_DISPATCH;
return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)&V_DISPATCH(rgVar));
return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)&V_DISPATCH(rgVar), FALSE);
}
static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Skip(