msxml3: Track linked/unlinked state for element and free node data only when unlinked.
This commit is contained in:
parent
20e63dcfd1
commit
f9cb63116d
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue