Nikolay Sivov : msxml3: Track linked/ unlinked state for element and free node data only when unlinked.
Alexandre Julliard
julliard at winehq.org
Mon Jan 18 10:58:51 CST 2010
Module: wine
Branch: master
Commit: f9cb63116d2558dd2bb0759218b2d6773fb048a3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=f9cb63116d2558dd2bb0759218b2d6773fb048a3
Author: Nikolay Sivov <bunglehead at gmail.com>
Date: Fri Jan 15 00:18:32 2010 +0300
msxml3: Track linked/unlinked state for element and free node data only when unlinked.
---
dlls/msxml3/msxml_private.h | 2 +-
dlls/msxml3/tests/xmlelem.c | 1 +
dlls/msxml3/xmldoc.c | 4 ++--
dlls/msxml3/xmlelem.c | 16 ++++++++++++----
4 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index d62a8a4..e46642d 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -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);
diff --git a/dlls/msxml3/tests/xmlelem.c b/dlls/msxml3/tests/xmlelem.c
index bcbae94..3304d5a 100644
--- a/dlls/msxml3/tests/xmlelem.c
+++ b/dlls/msxml3/tests/xmlelem.c
@@ -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;
diff --git a/dlls/msxml3/xmldoc.c b/dlls/msxml3/xmldoc.c
index af67d4e..b77fd00 100644
--- a/dlls/msxml3/xmldoc.c
+++ b/dlls/msxml3/xmldoc.c
@@ -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 =
diff --git a/dlls/msxml3/xmlelem.c b/dlls/msxml3/xmlelem.c
index b96df3a..3c1f4f2 100644
--- a/dlls/msxml3/xmlelem.c
+++ b/dlls/msxml3/xmlelem.c
@@ -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(
More information about the wine-cvs
mailing list