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