Nikolay Sivov : msxml3: Implement IEnumVARIANT::Next() for IXMLDOMSelection .
Alexandre Julliard
julliard at winehq.org
Mon Oct 31 12:49:03 CDT 2011
Module: wine
Branch: master
Commit: 4bb9da77767602e3fb798654da0920b7f157691c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4bb9da77767602e3fb798654da0920b7f157691c
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Sun Oct 30 10:57:09 2011 +0300
msxml3: Implement IEnumVARIANT::Next() for IXMLDOMSelection.
---
dlls/msxml3/selection.c | 43 ++++++++++++++++++--
dlls/msxml3/tests/domdoc.c | 95 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 133 insertions(+), 5 deletions(-)
diff --git a/dlls/msxml3/selection.c b/dlls/msxml3/selection.c
index 0e62a68..31137f3 100644
--- a/dlls/msxml3/selection.c
+++ b/dlls/msxml3/selection.c
@@ -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);
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index 62ccb4e..ee2128b 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -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();
}
More information about the wine-cvs
mailing list