msxml3: Implement IEnumVARIANT::Next() for IXMLDOMSelection.

oldstable
Nikolay Sivov 2011-10-30 10:57:09 +03:00 committed by Alexandre Julliard
parent a35513bbd0
commit 4bb9da7776
2 changed files with 133 additions and 5 deletions

View File

@ -65,6 +65,8 @@ typedef struct _enumvariant
IXMLDOMSelection *selection;
BOOL own;
LONG pos;
} enumvariant;
typedef struct _domselection
@ -507,12 +509,44 @@ static ULONG WINAPI enumvariant_Release(IEnumVARIANT *iface )
static HRESULT WINAPI enumvariant_Next(
IEnumVARIANT *iface,
ULONG celt,
VARIANT *rgvar,
ULONG *pceltFetched)
VARIANT *var,
ULONG *fetched)
{
enumvariant *This = impl_from_IEnumVARIANT( iface );
FIXME("(%p)->(%u %p %p): stub\n", This, celt, rgvar, pceltFetched);
return E_NOTIMPL;
IXMLDOMNode *node;
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(
@ -561,6 +595,7 @@ static HRESULT create_enumvariant(IXMLDOMSelection *selection, BOOL own, IUnknow
This->ref = 0;
This->selection = selection;
This->own = own;
This->pos = 0;
if (This->own)
IXMLDOMSelection_AddRef(selection);

View File

@ -1728,6 +1728,15 @@ SZ_EMAIL_DTD
" <attachment id=\"patch1\">0001-msxml3-tests-DTD-validation.patch</attachment>"
"</email>";
static const char xpath_simple_list[] =
"<?xml version=\"1.0\"?>"
"<root>"
" <a/>"
" <b/>"
" <c/>"
" <d/>"
"</root>";
static const WCHAR szNonExistentFile[] = {
'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;
IEnumVARIANT *enum1, *enum2, *enum3;
IDispatch *disp;
IXMLDOMNodeList *list;
IXMLDOMDocument *doc;
IXMLDOMNode *node;
IDispatch *disp;
VARIANT_BOOL b;
HRESULT hr;
VARIANT v;
BSTR name;
ULONG ret;
LONG len;
doc = create_document(&IID_IXMLDOMDocument);
@ -10150,7 +10164,86 @@ static void test_selection(void)
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);
free_bstrs();
}