msxml3: Add stub IEnumVARIANT support for IXMLDOMSelection.
This commit is contained in:
parent
ae6ea94bb3
commit
a3a1f4e3fb
|
@ -58,6 +58,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
|
||||||
int registerNamespaces(xmlXPathContextPtr ctxt);
|
int registerNamespaces(xmlXPathContextPtr ctxt);
|
||||||
xmlChar* XSLPattern_to_XPath(xmlXPathContextPtr ctxt, xmlChar const* xslpat_str);
|
xmlChar* XSLPattern_to_XPath(xmlXPathContextPtr ctxt, xmlChar const* xslpat_str);
|
||||||
|
|
||||||
|
typedef struct _enumvariant
|
||||||
|
{
|
||||||
|
IEnumVARIANT IEnumVARIANT_iface;
|
||||||
|
LONG ref;
|
||||||
|
|
||||||
|
IXMLDOMSelection *selection;
|
||||||
|
BOOL own;
|
||||||
|
} enumvariant;
|
||||||
|
|
||||||
typedef struct _domselection
|
typedef struct _domselection
|
||||||
{
|
{
|
||||||
DispatchEx dispex;
|
DispatchEx dispex;
|
||||||
|
@ -66,6 +75,7 @@ typedef struct _domselection
|
||||||
xmlNodePtr node;
|
xmlNodePtr node;
|
||||||
xmlXPathObjectPtr result;
|
xmlXPathObjectPtr result;
|
||||||
int resultPos;
|
int resultPos;
|
||||||
|
IEnumVARIANT *enumvariant;
|
||||||
} domselection;
|
} domselection;
|
||||||
|
|
||||||
static inline domselection *impl_from_IXMLDOMSelection( IXMLDOMSelection *iface )
|
static inline domselection *impl_from_IXMLDOMSelection( IXMLDOMSelection *iface )
|
||||||
|
@ -73,6 +83,13 @@ static inline domselection *impl_from_IXMLDOMSelection( IXMLDOMSelection *iface
|
||||||
return CONTAINING_RECORD(iface, domselection, IXMLDOMSelection_iface);
|
return CONTAINING_RECORD(iface, domselection, IXMLDOMSelection_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline enumvariant *impl_from_IEnumVARIANT( IEnumVARIANT *iface )
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, enumvariant, IEnumVARIANT_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT create_enumvariant(IXMLDOMSelection*, BOOL, IUnknown**);
|
||||||
|
|
||||||
static HRESULT WINAPI domselection_QueryInterface(
|
static HRESULT WINAPI domselection_QueryInterface(
|
||||||
IXMLDOMSelection *iface,
|
IXMLDOMSelection *iface,
|
||||||
REFIID riid,
|
REFIID riid,
|
||||||
|
@ -91,7 +108,17 @@ static HRESULT WINAPI domselection_QueryInterface(
|
||||||
{
|
{
|
||||||
*ppvObject = &This->IXMLDOMSelection_iface;
|
*ppvObject = &This->IXMLDOMSelection_iface;
|
||||||
}
|
}
|
||||||
else if(dispex_query_interface(&This->dispex, riid, ppvObject))
|
else if (IsEqualGUID( riid, &IID_IEnumVARIANT ))
|
||||||
|
{
|
||||||
|
if (!This->enumvariant)
|
||||||
|
{
|
||||||
|
HRESULT hr = create_enumvariant(iface, FALSE, (IUnknown**)&This->enumvariant);
|
||||||
|
if (FAILED(hr)) return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IEnumVARIANT_QueryInterface(This->enumvariant, &IID_IEnumVARIANT, ppvObject);
|
||||||
|
}
|
||||||
|
else if (dispex_query_interface(&This->dispex, riid, ppvObject))
|
||||||
{
|
{
|
||||||
return *ppvObject ? S_OK : E_NOINTERFACE;
|
return *ppvObject ? S_OK : E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
@ -127,6 +154,7 @@ static ULONG WINAPI domselection_Release(
|
||||||
{
|
{
|
||||||
xmlXPathFreeObject(This->result);
|
xmlXPathFreeObject(This->result);
|
||||||
xmldoc_release(This->node->doc);
|
xmldoc_release(This->node->doc);
|
||||||
|
if (This->enumvariant) IEnumVARIANT_Release(This->enumvariant);
|
||||||
heap_free(This);
|
heap_free(This);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,8 +321,10 @@ static HRESULT WINAPI domselection_get__newEnum(
|
||||||
IUnknown** ppUnk)
|
IUnknown** ppUnk)
|
||||||
{
|
{
|
||||||
domselection *This = impl_from_IXMLDOMSelection( iface );
|
domselection *This = impl_from_IXMLDOMSelection( iface );
|
||||||
FIXME("(%p)->(%p)\n", This, ppUnk);
|
|
||||||
return E_NOTIMPL;
|
TRACE("(%p)->(%p)\n", This, ppUnk);
|
||||||
|
|
||||||
|
return create_enumvariant(iface, TRUE, ppUnk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI domselection_get_expr(
|
static HRESULT WINAPI domselection_get_expr(
|
||||||
|
@ -425,6 +455,118 @@ static const struct IXMLDOMSelectionVtbl domselection_vtbl =
|
||||||
domselection_setProperty
|
domselection_setProperty
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* IEnumVARIANT support */
|
||||||
|
static HRESULT WINAPI enumvariant_QueryInterface(
|
||||||
|
IEnumVARIANT *iface,
|
||||||
|
REFIID riid,
|
||||||
|
void** ppvObject )
|
||||||
|
{
|
||||||
|
enumvariant *This = impl_from_IEnumVARIANT( iface );
|
||||||
|
|
||||||
|
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
|
||||||
|
|
||||||
|
*ppvObject = NULL;
|
||||||
|
|
||||||
|
if ( IsEqualGUID( riid, &IID_IUnknown ) ||
|
||||||
|
IsEqualGUID( riid, &IID_IEnumVARIANT ))
|
||||||
|
{
|
||||||
|
*ppvObject = &This->IEnumVARIANT_iface;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return IXMLDOMSelection_QueryInterface(This->selection, riid, ppvObject);
|
||||||
|
|
||||||
|
IEnumVARIANT_AddRef( iface );
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI enumvariant_AddRef(IEnumVARIANT *iface )
|
||||||
|
{
|
||||||
|
enumvariant *This = impl_from_IEnumVARIANT( iface );
|
||||||
|
ULONG ref = InterlockedIncrement( &This->ref );
|
||||||
|
TRACE("(%p)->(%d)\n", This, ref);
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI enumvariant_Release(IEnumVARIANT *iface )
|
||||||
|
{
|
||||||
|
enumvariant *This = impl_from_IEnumVARIANT( iface );
|
||||||
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
|
TRACE("(%p)->(%d)\n", This, ref);
|
||||||
|
if ( ref == 0 )
|
||||||
|
{
|
||||||
|
if (This->own) IXMLDOMSelection_Release(This->selection);
|
||||||
|
heap_free(This);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI enumvariant_Next(
|
||||||
|
IEnumVARIANT *iface,
|
||||||
|
ULONG celt,
|
||||||
|
VARIANT *rgvar,
|
||||||
|
ULONG *pceltFetched)
|
||||||
|
{
|
||||||
|
enumvariant *This = impl_from_IEnumVARIANT( iface );
|
||||||
|
FIXME("(%p)->(%u %p %p): stub\n", This, celt, rgvar, pceltFetched);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI enumvariant_Skip(
|
||||||
|
IEnumVARIANT *iface,
|
||||||
|
ULONG celt)
|
||||||
|
{
|
||||||
|
enumvariant *This = impl_from_IEnumVARIANT( iface );
|
||||||
|
FIXME("(%p)->(%u): stub\n", This, celt);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI enumvariant_Reset(IEnumVARIANT *iface)
|
||||||
|
{
|
||||||
|
enumvariant *This = impl_from_IEnumVARIANT( iface );
|
||||||
|
FIXME("(%p): stub\n", This);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI enumvariant_Clone(
|
||||||
|
IEnumVARIANT *iface, IEnumVARIANT **ppenum)
|
||||||
|
{
|
||||||
|
enumvariant *This = impl_from_IEnumVARIANT( iface );
|
||||||
|
FIXME("(%p)->(%p): stub\n", This, ppenum);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct IEnumVARIANTVtbl EnumVARIANTVtbl =
|
||||||
|
{
|
||||||
|
enumvariant_QueryInterface,
|
||||||
|
enumvariant_AddRef,
|
||||||
|
enumvariant_Release,
|
||||||
|
enumvariant_Next,
|
||||||
|
enumvariant_Skip,
|
||||||
|
enumvariant_Reset,
|
||||||
|
enumvariant_Clone
|
||||||
|
};
|
||||||
|
|
||||||
|
static HRESULT create_enumvariant(IXMLDOMSelection *selection, BOOL own, IUnknown **penum)
|
||||||
|
{
|
||||||
|
enumvariant *This;
|
||||||
|
|
||||||
|
This = heap_alloc(sizeof(enumvariant));
|
||||||
|
if (!This) return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
This->IEnumVARIANT_iface.lpVtbl = &EnumVARIANTVtbl;
|
||||||
|
This->ref = 0;
|
||||||
|
This->selection = selection;
|
||||||
|
This->own = own;
|
||||||
|
|
||||||
|
if (This->own)
|
||||||
|
IXMLDOMSelection_AddRef(selection);
|
||||||
|
|
||||||
|
return IEnumVARIANT_QueryInterface(&This->IEnumVARIANT_iface, &IID_IUnknown, (void**)penum);
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT domselection_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DISPID *dispid)
|
static HRESULT domselection_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DISPID *dispid)
|
||||||
{
|
{
|
||||||
domselection *This = impl_from_IXMLDOMSelection( (IXMLDOMSelection*)iface );
|
domselection *This = impl_from_IXMLDOMSelection( (IXMLDOMSelection*)iface );
|
||||||
|
@ -622,6 +764,7 @@ HRESULT create_selection(xmlNodePtr node, xmlChar* query, IXMLDOMNodeList **out)
|
||||||
This->ref = 1;
|
This->ref = 1;
|
||||||
This->resultPos = 0;
|
This->resultPos = 0;
|
||||||
This->node = node;
|
This->node = node;
|
||||||
|
This->enumvariant = NULL;
|
||||||
xmldoc_add_ref(This->node->doc);
|
xmldoc_add_ref(This->node->doc);
|
||||||
|
|
||||||
ctxt->error = query_serror;
|
ctxt->error = query_serror;
|
||||||
|
|
|
@ -9964,7 +9964,9 @@ static void test_get_attributes(void)
|
||||||
|
|
||||||
static void test_selection(void)
|
static void test_selection(void)
|
||||||
{
|
{
|
||||||
IXMLDOMSelection *selection;
|
IXMLDOMSelection *selection, *selection2;
|
||||||
|
IEnumVARIANT *enum1, *enum2, *enum3;
|
||||||
|
IDispatch *disp;
|
||||||
IXMLDOMNodeList *list;
|
IXMLDOMNodeList *list;
|
||||||
IXMLDOMDocument *doc;
|
IXMLDOMDocument *doc;
|
||||||
VARIANT_BOOL b;
|
VARIANT_BOOL b;
|
||||||
|
@ -9982,6 +9984,85 @@ static void test_selection(void)
|
||||||
EXPECT_HR(hr, S_OK);
|
EXPECT_HR(hr, S_OK);
|
||||||
IXMLDOMSelection_Release(selection);
|
IXMLDOMSelection_Release(selection);
|
||||||
|
|
||||||
|
/* IEnumVARIANT tests */
|
||||||
|
enum1 = NULL;
|
||||||
|
hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum1);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(enum1 != NULL, "got %p\n", enum1);
|
||||||
|
EXPECT_REF(enum1, 2);
|
||||||
|
|
||||||
|
enum3 = NULL;
|
||||||
|
hr = IXMLDOMSelection_QueryInterface(selection, &IID_IEnumVARIANT, (void**)&enum3);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(enum3 != NULL, "got %p\n", enum3);
|
||||||
|
ok(enum1 == enum3, "got %p and %p\n", enum1, enum3);
|
||||||
|
EXPECT_REF(enum1, 3);
|
||||||
|
IEnumVARIANT_Release(enum3);
|
||||||
|
|
||||||
|
EXPECT_REF(selection, 1);
|
||||||
|
EXPECT_REF(enum1, 2);
|
||||||
|
|
||||||
|
enum2 = NULL;
|
||||||
|
hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(enum2 != NULL, "got %p\n", enum2);
|
||||||
|
|
||||||
|
EXPECT_REF(selection, 2);
|
||||||
|
EXPECT_REF(enum1, 2);
|
||||||
|
EXPECT_REF(enum2, 1);
|
||||||
|
|
||||||
|
ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
|
||||||
|
|
||||||
|
selection2 = NULL;
|
||||||
|
hr = IEnumVARIANT_QueryInterface(enum1, &IID_IXMLDOMSelection, (void**)&selection2);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(selection2 == selection, "got %p and %p\n", selection, selection2);
|
||||||
|
EXPECT_REF(selection, 3);
|
||||||
|
EXPECT_REF(enum1, 2);
|
||||||
|
|
||||||
|
IXMLDOMSelection_Release(selection2);
|
||||||
|
|
||||||
|
hr = IEnumVARIANT_QueryInterface(enum1, &IID_IDispatch, (void**)&disp);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
EXPECT_REF(selection, 3);
|
||||||
|
IDispatch_Release(disp);
|
||||||
|
|
||||||
|
hr = IEnumVARIANT_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enum3);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(enum3 == enum1, "got %p and %p\n", enum3, enum1);
|
||||||
|
EXPECT_REF(selection, 2);
|
||||||
|
EXPECT_REF(enum1, 3);
|
||||||
|
|
||||||
|
IEnumVARIANT_Release(enum1);
|
||||||
|
IEnumVARIANT_Release(enum2);
|
||||||
|
|
||||||
|
enum1 = NULL;
|
||||||
|
hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(enum1 != NULL, "got %p\n", enum1);
|
||||||
|
EXPECT_REF(enum1, 1);
|
||||||
|
EXPECT_REF(selection, 2);
|
||||||
|
|
||||||
|
enum2 = NULL;
|
||||||
|
hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum2);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(enum2 != NULL, "got %p\n", enum2);
|
||||||
|
EXPECT_REF(enum2, 1);
|
||||||
|
EXPECT_REF(selection, 3);
|
||||||
|
|
||||||
|
ok(enum1 != enum2, "got %p, %p\n", enum1, enum2);
|
||||||
|
|
||||||
|
IEnumVARIANT_AddRef(enum1);
|
||||||
|
EXPECT_REF(selection, 3);
|
||||||
|
EXPECT_REF(enum1, 2);
|
||||||
|
EXPECT_REF(enum2, 1);
|
||||||
|
IEnumVARIANT_Release(enum1);
|
||||||
|
|
||||||
|
IEnumVARIANT_Release(enum1);
|
||||||
|
IEnumVARIANT_Release(enum2);
|
||||||
|
|
||||||
|
EXPECT_REF(selection, 1);
|
||||||
|
|
||||||
IXMLDOMNodeList_Release(list);
|
IXMLDOMNodeList_Release(list);
|
||||||
|
|
||||||
hr = IXMLDOMDocument_get_childNodes(doc, &list);
|
hr = IXMLDOMDocument_get_childNodes(doc, &list);
|
||||||
|
|
Loading…
Reference in New Issue