Gijs Vermeulen : msxml3: Support retrieving more than one element in IEnumVARIANT::Next() for IXMLElementCollection.

Alexandre Julliard julliard at winehq.org
Wed Sep 16 15:37:33 CDT 2020


Module: wine
Branch: master
Commit: 49eac508b59ca41fd9a10731c5038bd4b799015b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=49eac508b59ca41fd9a10731c5038bd4b799015b

Author: Gijs Vermeulen <gijsvrm at gmail.com>
Date:   Sun Sep 13 14:14:41 2020 +0200

msxml3: Support retrieving more than one element in IEnumVARIANT::Next() for IXMLElementCollection.

Signed-off-by: Gijs Vermeulen <gijsvrm at gmail.com>
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msxml3/tests/xmldoc.c | 51 ++++++++++++++++++++++++++++++++++++++--------
 dlls/msxml3/xmlelem.c      | 24 +++++++++++++---------
 2 files changed, 56 insertions(+), 19 deletions(-)

diff --git a/dlls/msxml3/tests/xmldoc.c b/dlls/msxml3/tests/xmldoc.c
index 693af19571..8854e0e2fa 100644
--- a/dlls/msxml3/tests/xmldoc.c
+++ b/dlls/msxml3/tests/xmldoc.c
@@ -656,7 +656,7 @@ static void test_xmlelem_collection(void)
     WCHAR path[MAX_PATH];
     LONG length, type;
     ULONG num_vars;
-    VARIANT var, dummy, vIndex, vName;
+    VARIANT var[3], dummy, vIndex, vName;
     BSTR url, str;
     static const CHAR szBankXML[] = "bank.xml";
     static const WCHAR szNumber[] = {'N','U','M','B','E','R',0};
@@ -738,16 +738,16 @@ static void test_xmlelem_collection(void)
     IUnknown_Release(unk);
 
     /* <Number>1234</Number> */
-    hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars);
+    hr = IEnumVARIANT_Next(enumVar, 1, &var[0], &num_vars);
     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
-    ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var));
+    ok(V_VT(&var[0]) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var[0]));
     ok(num_vars == 1, "Expected 1, got %d\n", num_vars);
 
-    hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IXMLElement, (LPVOID *)&child);
+    hr = IDispatch_QueryInterface(V_DISPATCH(&var[0]), &IID_IXMLElement, (LPVOID *)&child);
     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
     ok(child != NULL, "Expected non-NULL child\n");
 
-    VariantClear(&var);
+    VariantClear(&var[0]);
 
     hr = IXMLElement_get_type(child, &type);
     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
@@ -760,11 +760,13 @@ static void test_xmlelem_collection(void)
     IXMLElement_Release(child);
 
     /* <Name>Captain Ahab</Name> */
-    hr = IEnumVARIANT_Next(enumVar, 1, &var, &num_vars);
+    hr = IEnumVARIANT_Next(enumVar, 1, &var[0], &num_vars);
     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
-    ok(V_VT(&var) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var));
+    ok(V_VT(&var[0]) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var[0]));
     ok(num_vars == 1, "Expected 1, got %d\n", num_vars);
 
+    VariantClear(&var[0]);
+
     /* try advance further, no children left */
     V_VT(&dummy) = VT_I4;
     hr = IEnumVARIANT_Next(enumVar, 1, &dummy, &num_vars);
@@ -777,11 +779,42 @@ static void test_xmlelem_collection(void)
     ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
     ok(V_VT(&dummy) == VT_EMPTY, "Expected 0, got %d\n", V_VT(&dummy));
 
-    hr = IDispatch_QueryInterface(V_DISPATCH(&var), &IID_IXMLElement, (LPVOID *)&child);
+    hr = IEnumVARIANT_Reset(enumVar);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+
+    /* retrieve multiple elements */
+    hr = IEnumVARIANT_Next(enumVar, 2, var, &num_vars);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+    ok(V_VT(&var[0]) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var[0]));
+    ok(V_VT(&var[1]) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var[1]));
+    ok(num_vars == 2, "Expected 2, got %d\n", num_vars);
+
+    V_VT(&dummy) = VT_I4;
+    hr = IEnumVARIANT_Next(enumVar, 1, &dummy, &num_vars);
+    ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
+    ok(V_VT(&dummy) == VT_EMPTY, "Expected 0, got %d\n", V_VT(&dummy));
+    ok(num_vars == 0, "Expected 0, got %d\n", num_vars);
+
+    hr = IEnumVARIANT_Reset(enumVar);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+
+    VariantClear(&var[1]);
+    VariantClear(&var[0]);
+
+    /* request more elements than available */
+    hr = IEnumVARIANT_Next(enumVar, 3, var, &num_vars);
+    ok(hr == S_FALSE, "Expected S_FALSE, got %08x\n", hr);
+    ok(V_VT(&var[0]) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var[0]));
+    ok(V_VT(&var[1]) == VT_DISPATCH, "Expected VT_DISPATCH, got %d\n", V_VT(&var[1]));
+    ok(V_VT(&var[2]) == VT_EMPTY, "Expected 0, got %d\n", V_VT(&var[2]));
+    ok(num_vars == 2, "Expected 2, got %d\n", num_vars);
+
+    hr = IDispatch_QueryInterface(V_DISPATCH(&var[1]), &IID_IXMLElement, (LPVOID *)&child);
     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
     ok(child != NULL, "Expected non-NULL child\n");
 
-    VariantClear(&var);
+    VariantClear(&var[1]);
+    VariantClear(&var[0]);
 
     hr = IXMLElement_get_type(child, &type);
     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
diff --git a/dlls/msxml3/xmlelem.c b/dlls/msxml3/xmlelem.c
index 96b2007ce3..3addcbd19b 100644
--- a/dlls/msxml3/xmlelem.c
+++ b/dlls/msxml3/xmlelem.c
@@ -753,28 +753,32 @@ static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Next(
     IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *fetched)
 {
     xmlelem_collection *This = impl_from_IEnumVARIANT(iface);
-    xmlNodePtr ptr = This->current;
+    HRESULT hr;
 
     TRACE("(%p)->(%d %p %p)\n", This, celt, rgVar, fetched);
 
     if (!rgVar)
         return E_INVALIDARG;
 
-    /* FIXME: handle celt */
-    if (fetched)
-        *fetched = 1;
+    if (fetched) *fetched = 0;
 
-    if (This->current)
-        This->current = This->current->next;
-    else
+    if (!This->current)
     {
         V_VT(rgVar) = VT_EMPTY;
-        if (fetched) *fetched = 0;
         return S_FALSE;
     }
 
-    V_VT(rgVar) = VT_DISPATCH;
-    return XMLElement_create(ptr, (LPVOID *)&V_DISPATCH(rgVar), FALSE);
+    while (celt > 0 && This->current)
+    {
+        V_VT(rgVar) = VT_DISPATCH;
+        hr = XMLElement_create(This->current, (void **)&V_DISPATCH(rgVar), FALSE);
+        if (FAILED(hr)) return hr;
+        This->current = This->current->next;
+        if (--celt && This->current) ++rgVar;
+        if (fetched) ++*fetched;
+    }
+
+    return celt == 0 ? S_OK : S_FALSE;
 }
 
 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Skip(




More information about the wine-cvs mailing list