forked from Mirrors/wine-wine
msxml3: Implement IEnumVARIANT::Next() for IXMLDOMSelection.
parent
a35513bbd0
commit
4bb9da7776
|
@ -65,6 +65,8 @@ typedef struct _enumvariant
|
||||||
|
|
||||||
IXMLDOMSelection *selection;
|
IXMLDOMSelection *selection;
|
||||||
BOOL own;
|
BOOL own;
|
||||||
|
|
||||||
|
LONG pos;
|
||||||
} enumvariant;
|
} enumvariant;
|
||||||
|
|
||||||
typedef struct _domselection
|
typedef struct _domselection
|
||||||
|
@ -507,12 +509,44 @@ static ULONG WINAPI enumvariant_Release(IEnumVARIANT *iface )
|
||||||
static HRESULT WINAPI enumvariant_Next(
|
static HRESULT WINAPI enumvariant_Next(
|
||||||
IEnumVARIANT *iface,
|
IEnumVARIANT *iface,
|
||||||
ULONG celt,
|
ULONG celt,
|
||||||
VARIANT *rgvar,
|
VARIANT *var,
|
||||||
ULONG *pceltFetched)
|
ULONG *fetched)
|
||||||
{
|
{
|
||||||
enumvariant *This = impl_from_IEnumVARIANT( iface );
|
enumvariant *This = impl_from_IEnumVARIANT( iface );
|
||||||
FIXME("(%p)->(%u %p %p): stub\n", This, celt, rgvar, pceltFetched);
|
IXMLDOMNode *node;
|
||||||
return E_NOTIMPL;
|
ULONG ret_count = 0;
|
||||||
|
|
||||||
|
TRACE("(%p)->(%u %p %p)\n", This, celt, var, fetched);
|
||||||
|
|
||||||
|
if (fetched) *fetched = 0;
|
||||||
|
|
||||||
|
if (celt && !var) return E_INVALIDARG;
|
||||||
|
|
||||||
|
for (; celt > 0; celt--, var++, This->pos++)
|
||||||
|
{
|
||||||
|
IDispatch *disp = NULL;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
node = NULL;
|
||||||
|
hr = IXMLDOMSelection_get_item(This->selection, This->pos, &node);
|
||||||
|
if (hr != S_OK) break;
|
||||||
|
|
||||||
|
IXMLDOMNode_QueryInterface(node, &IID_IDispatch, (void**)&disp);
|
||||||
|
IXMLDOMNode_Release(node);
|
||||||
|
|
||||||
|
V_VT(var) = VT_DISPATCH;
|
||||||
|
V_DISPATCH(var) = disp;
|
||||||
|
|
||||||
|
ret_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fetched) (*fetched)++;
|
||||||
|
|
||||||
|
/* we need to advance one step more for some reason */
|
||||||
|
if (ret_count)
|
||||||
|
IXMLDOMSelection_nextNode(This->selection, &node);
|
||||||
|
|
||||||
|
return celt == 0 ? S_OK : S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI enumvariant_Skip(
|
static HRESULT WINAPI enumvariant_Skip(
|
||||||
|
@ -561,6 +595,7 @@ static HRESULT create_enumvariant(IXMLDOMSelection *selection, BOOL own, IUnknow
|
||||||
This->ref = 0;
|
This->ref = 0;
|
||||||
This->selection = selection;
|
This->selection = selection;
|
||||||
This->own = own;
|
This->own = own;
|
||||||
|
This->pos = 0;
|
||||||
|
|
||||||
if (This->own)
|
if (This->own)
|
||||||
IXMLDOMSelection_AddRef(selection);
|
IXMLDOMSelection_AddRef(selection);
|
||||||
|
|
|
@ -1728,6 +1728,15 @@ SZ_EMAIL_DTD
|
||||||
" <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
|
" <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
|
||||||
"</email>";
|
"</email>";
|
||||||
|
|
||||||
|
static const char xpath_simple_list[] =
|
||||||
|
"<?xml version=\"1.0\"?>"
|
||||||
|
"<root>"
|
||||||
|
" <a/>"
|
||||||
|
" <b/>"
|
||||||
|
" <c/>"
|
||||||
|
" <d/>"
|
||||||
|
"</root>";
|
||||||
|
|
||||||
static const WCHAR szNonExistentFile[] = {
|
static const WCHAR szNonExistentFile[] = {
|
||||||
'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
|
'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
|
||||||
};
|
};
|
||||||
|
@ -10043,11 +10052,16 @@ static void test_selection(void)
|
||||||
{
|
{
|
||||||
IXMLDOMSelection *selection, *selection2;
|
IXMLDOMSelection *selection, *selection2;
|
||||||
IEnumVARIANT *enum1, *enum2, *enum3;
|
IEnumVARIANT *enum1, *enum2, *enum3;
|
||||||
IDispatch *disp;
|
|
||||||
IXMLDOMNodeList *list;
|
IXMLDOMNodeList *list;
|
||||||
IXMLDOMDocument *doc;
|
IXMLDOMDocument *doc;
|
||||||
|
IXMLDOMNode *node;
|
||||||
|
IDispatch *disp;
|
||||||
VARIANT_BOOL b;
|
VARIANT_BOOL b;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
VARIANT v;
|
||||||
|
BSTR name;
|
||||||
|
ULONG ret;
|
||||||
|
LONG len;
|
||||||
|
|
||||||
doc = create_document(&IID_IXMLDOMDocument);
|
doc = create_document(&IID_IXMLDOMDocument);
|
||||||
|
|
||||||
|
@ -10150,7 +10164,86 @@ static void test_selection(void)
|
||||||
|
|
||||||
IXMLDOMNodeList_Release(list);
|
IXMLDOMNodeList_Release(list);
|
||||||
|
|
||||||
|
/* test if IEnumVARIANT touches selection context */
|
||||||
|
hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xpath_simple_list), &b);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
hr = IXMLDOMDocument_selectNodes(doc, _bstr_("root/*"), &list);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
hr = IXMLDOMNodeList_QueryInterface(list, &IID_IXMLDOMSelection, (void**)&selection);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
len = 0;
|
||||||
|
hr = IXMLDOMSelection_get_length(selection, &len);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(len == 4, "got %d\n", len);
|
||||||
|
|
||||||
|
enum1 = NULL;
|
||||||
|
hr = IXMLDOMSelection_get__newEnum(selection, (IUnknown**)&enum1);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
|
||||||
|
/* no-op if zero count */
|
||||||
|
V_VT(&v) = VT_I2;
|
||||||
|
hr = IEnumVARIANT_Next(enum1, 0, &v, NULL);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(V_VT(&v) == VT_I2, "got var type %d\n", V_VT(&v));
|
||||||
|
|
||||||
|
/* positive count, null array pointer */
|
||||||
|
hr = IEnumVARIANT_Next(enum1, 1, NULL, NULL);
|
||||||
|
EXPECT_HR(hr, E_INVALIDARG);
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
hr = IEnumVARIANT_Next(enum1, 1, NULL, &ret);
|
||||||
|
EXPECT_HR(hr, E_INVALIDARG);
|
||||||
|
ok(ret == 0, "got %d\n", ret);
|
||||||
|
|
||||||
|
V_VT(&v) = VT_I2;
|
||||||
|
hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
|
||||||
|
|
||||||
|
hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
hr = IXMLDOMNode_get_nodeName(node, &name);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(!lstrcmpW(name, _bstr_("a")), "got node name %s\n", wine_dbgstr_w(name));
|
||||||
|
SysFreeString(name);
|
||||||
|
IXMLDOMNode_Release(node);
|
||||||
|
VariantClear(&v);
|
||||||
|
|
||||||
|
/* list cursor is updated */
|
||||||
|
hr = IXMLDOMSelection_nextNode(selection, &node);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
hr = IXMLDOMNode_get_nodeName(node, &name);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(!lstrcmpW(name, _bstr_("c")), "got node name %s\n", wine_dbgstr_w(name));
|
||||||
|
IXMLDOMNode_Release(node);
|
||||||
|
|
||||||
|
V_VT(&v) = VT_I2;
|
||||||
|
hr = IEnumVARIANT_Next(enum1, 1, &v, NULL);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(V_VT(&v) == VT_DISPATCH, "got var type %d\n", V_VT(&v));
|
||||||
|
hr = IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IXMLDOMNode, (void**)&node);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
hr = IXMLDOMNode_get_nodeName(node, &name);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(!lstrcmpW(name, _bstr_("b")), "got node name %s\n", wine_dbgstr_w(name));
|
||||||
|
SysFreeString(name);
|
||||||
|
IXMLDOMNode_Release(node);
|
||||||
|
VariantClear(&v);
|
||||||
|
|
||||||
|
hr = IXMLDOMSelection_nextNode(selection, &node);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
hr = IXMLDOMNode_get_nodeName(node, &name);
|
||||||
|
EXPECT_HR(hr, S_OK);
|
||||||
|
ok(!lstrcmpW(name, _bstr_("d")), "got node name %s\n", wine_dbgstr_w(name));
|
||||||
|
IXMLDOMNode_Release(node);
|
||||||
|
|
||||||
|
IXMLDOMSelection_Release(selection);
|
||||||
|
IXMLDOMNodeList_Release(list);
|
||||||
IXMLDOMDocument_Release(doc);
|
IXMLDOMDocument_Release(doc);
|
||||||
|
|
||||||
free_bstrs();
|
free_bstrs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue