Module: wine Branch: master Commit: 1625dae7e3bc5de76e0445b3e5f91e33ad78f4e8 URL: http://source.winehq.org/git/wine.git/?a=commit;h=1625dae7e3bc5de76e0445b3e5...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Tue Jul 3 10:06:59 2012 +0400
msxml3: Added _newEnum() support for IXMLDOMNamedNodeMap.
---
dlls/msxml3/nodemap.c | 32 +++++++++++-- dlls/msxml3/tests/domdoc.c | 114 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 4 deletions(-)
diff --git a/dlls/msxml3/nodemap.c b/dlls/msxml3/nodemap.c index 6fac505..c6be169 100644 --- a/dlls/msxml3/nodemap.c +++ b/dlls/msxml3/nodemap.c @@ -44,7 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
#ifdef HAVE_LIBXML2
-typedef struct _xmlnodemap +typedef struct { DispatchEx dispex; IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface; @@ -53,10 +53,22 @@ typedef struct _xmlnodemap
xmlNodePtr node; LONG iterator; + IEnumVARIANT *enumvariant;
const struct nodemap_funcs *funcs; } xmlnodemap;
+static HRESULT nodemap_get_item(IUnknown *iface, LONG index, VARIANT *item) +{ + V_VT(item) = VT_DISPATCH; + return IXMLDOMNamedNodeMap_get_item((IXMLDOMNamedNodeMap*)iface, index, (IXMLDOMNode**)&V_DISPATCH(item)); +} + +static const struct enumvariant_funcs nodemap_enumvariant = { + nodemap_get_item, + NULL +}; + static inline xmlnodemap *impl_from_IXMLDOMNamedNodeMap( IXMLDOMNamedNodeMap *iface ) { return CONTAINING_RECORD(iface, xmlnodemap, IXMLDOMNamedNodeMap_iface); @@ -80,6 +92,16 @@ static HRESULT WINAPI xmlnodemap_QueryInterface( { *ppvObject = iface; } + else if (IsEqualGUID( riid, &IID_IEnumVARIANT )) + { + if (!This->enumvariant) + { + HRESULT hr = create_enumvariant((IUnknown*)iface, FALSE, &nodemap_enumvariant, &This->enumvariant); + if (FAILED(hr)) return hr; + } + + return IEnumVARIANT_QueryInterface(This->enumvariant, &IID_IEnumVARIANT, ppvObject); + } else if (dispex_query_interface(&This->dispex, riid, ppvObject)) { return *ppvObject ? S_OK : E_NOINTERFACE; @@ -119,6 +141,7 @@ static ULONG WINAPI xmlnodemap_Release( if ( ref == 0 ) { xmldoc_release( This->node->doc ); + if (This->enumvariant) IEnumVARIANT_Release(This->enumvariant); release_dispex(&This->dispex); heap_free( This ); } @@ -275,11 +298,11 @@ static HRESULT WINAPI xmlnodemap_reset(
static HRESULT WINAPI xmlnodemap__newEnum( IXMLDOMNamedNodeMap *iface, - IUnknown** ppUnk) + IUnknown** enumv) { xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface ); - FIXME("(%p)->(%p)\n", This, ppUnk); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, enumv); + return create_enumvariant((IUnknown*)iface, TRUE, &nodemap_enumvariant, (IEnumVARIANT**)enumv); }
static const struct IXMLDOMNamedNodeMapVtbl XMLDOMNamedNodeMapVtbl = @@ -423,6 +446,7 @@ IXMLDOMNamedNodeMap *create_nodemap(xmlNodePtr node, const struct nodemap_funcs This->node = node; This->ref = 1; This->iterator = 0; + This->enumvariant = NULL; This->funcs = funcs;
init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNamedNodeMap_iface, &xmlnodemap_dispex); diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 4b68e74..9919f4e 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -1749,6 +1749,11 @@ static const char default_ns_doc[] = { " d="d attr" />" };
+static const char attributes_map[] = { + "<?xml version=\"1.0\"?>" + "<a attr1="value1" attr2="value2" attr3="value3" attr4="value4" />" +}; + static const WCHAR nonexistent_fileW[] = { 'c', ':', '\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0 }; @@ -12176,6 +12181,114 @@ static void test_putref_schemas(void) IXMLDOMDocument2_Release(doc); }
+static void test_namedmap_newenum(void) +{ + IEnumVARIANT *enum1, *enum2, *enum3; + IXMLDOMNamedNodeMap *map; + IUnknown *unk1, *unk2; + IXMLDOMDocument *doc; + IXMLDOMElement *elem; + IXMLDOMNode *node; + VARIANT_BOOL b; + HRESULT hr; + VARIANT v; + BSTR str; + + doc = create_document(&IID_IXMLDOMDocument); + + hr = IXMLDOMDocument_loadXML(doc, _bstr_(attributes_map), &b); + EXPECT_HR(hr, S_OK); + + hr = IXMLDOMDocument_get_documentElement(doc, &elem); + EXPECT_HR(hr, S_OK); + + hr = IXMLDOMElement_get_attributes(elem, &map); + EXPECT_HR(hr, S_OK); + IXMLDOMElement_Release(elem); + + enum1 = NULL; + EXPECT_REF(map, 1); + hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IEnumVARIANT, (void**)&enum1); + EXPECT_HR(hr, S_OK); + ok(enum1 != NULL, "got %p\n", enum1); + EXPECT_REF(map, 1); + EXPECT_REF(enum1, 2); + + enum2 = NULL; + hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IEnumVARIANT, (void**)&enum2); + EXPECT_HR(hr, S_OK); + ok(enum2 == enum1, "got %p\n", enum2); + + IEnumVARIANT_Release(enum2); + + EXPECT_REF(map, 1); + hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum2); + EXPECT_HR(hr, S_OK); + EXPECT_REF(map, 2); + EXPECT_REF(enum2, 1); + ok(enum2 != enum1, "got %p, %p\n", enum2, enum1); + + IEnumVARIANT_Release(enum1); + + /* enumerator created with _newEnum() doesn't share IUnknown* with main object */ + hr = IXMLDOMNamedNodeMap_QueryInterface(map, &IID_IUnknown, (void**)&unk1); + EXPECT_HR(hr, S_OK); + hr = IEnumVARIANT_QueryInterface(enum2, &IID_IUnknown, (void**)&unk2); + EXPECT_HR(hr, S_OK); + EXPECT_REF(map, 3); + EXPECT_REF(enum2, 2); + ok(unk1 != unk2, "got %p, %p\n", unk1, unk2); + IUnknown_Release(unk1); + IUnknown_Release(unk2); + + hr = IXMLDOMNamedNodeMap__newEnum(map, (IUnknown**)&enum3); + EXPECT_HR(hr, S_OK); + ok(enum2 != enum3, "got %p, %p\n", enum2, enum3); + IEnumVARIANT_Release(enum3); + + /* iteration tests */ + hr = IXMLDOMNamedNodeMap_get_item(map, 0, &node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &str); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(str, _bstr_("attr1")), "got %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); + + hr = IXMLDOMNamedNodeMap_nextNode(map, &node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &str); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(str, _bstr_("attr1")), "got %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); + + V_VT(&v) = VT_EMPTY; + hr = IEnumVARIANT_Next(enum2, 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, &str); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(str, _bstr_("attr1")), "got node name %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); + VariantClear(&v); + + hr = IXMLDOMNamedNodeMap_nextNode(map, &node); + EXPECT_HR(hr, S_OK); + hr = IXMLDOMNode_get_nodeName(node, &str); + EXPECT_HR(hr, S_OK); + ok(!lstrcmpW(str, _bstr_("attr2")), "got %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + IXMLDOMNode_Release(node); + + IEnumVARIANT_Release(enum2); + IXMLDOMNamedNodeMap_Release(map); + IXMLDOMDocument_Release(doc); +} + START_TEST(domdoc) { IXMLDOMDocument *doc; @@ -12256,6 +12369,7 @@ START_TEST(domdoc) test_get_namespaces(); test_put_data(); test_putref_schemas(); + test_namedmap_newenum();
test_xsltemplate();