msxml3: Added _newEnum() support for IXMLDOMNamedNodeMap.
This commit is contained in:
parent
56e3b22f6c
commit
1625dae7e3
|
@ -44,7 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
|
||||||
|
|
||||||
#ifdef HAVE_LIBXML2
|
#ifdef HAVE_LIBXML2
|
||||||
|
|
||||||
typedef struct _xmlnodemap
|
typedef struct
|
||||||
{
|
{
|
||||||
DispatchEx dispex;
|
DispatchEx dispex;
|
||||||
IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface;
|
IXMLDOMNamedNodeMap IXMLDOMNamedNodeMap_iface;
|
||||||
|
@ -53,10 +53,22 @@ typedef struct _xmlnodemap
|
||||||
|
|
||||||
xmlNodePtr node;
|
xmlNodePtr node;
|
||||||
LONG iterator;
|
LONG iterator;
|
||||||
|
IEnumVARIANT *enumvariant;
|
||||||
|
|
||||||
const struct nodemap_funcs *funcs;
|
const struct nodemap_funcs *funcs;
|
||||||
} xmlnodemap;
|
} 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 )
|
static inline xmlnodemap *impl_from_IXMLDOMNamedNodeMap( IXMLDOMNamedNodeMap *iface )
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, xmlnodemap, IXMLDOMNamedNodeMap_iface);
|
return CONTAINING_RECORD(iface, xmlnodemap, IXMLDOMNamedNodeMap_iface);
|
||||||
|
@ -80,6 +92,16 @@ static HRESULT WINAPI xmlnodemap_QueryInterface(
|
||||||
{
|
{
|
||||||
*ppvObject = iface;
|
*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))
|
else if (dispex_query_interface(&This->dispex, riid, ppvObject))
|
||||||
{
|
{
|
||||||
return *ppvObject ? S_OK : E_NOINTERFACE;
|
return *ppvObject ? S_OK : E_NOINTERFACE;
|
||||||
|
@ -119,6 +141,7 @@ static ULONG WINAPI xmlnodemap_Release(
|
||||||
if ( ref == 0 )
|
if ( ref == 0 )
|
||||||
{
|
{
|
||||||
xmldoc_release( This->node->doc );
|
xmldoc_release( This->node->doc );
|
||||||
|
if (This->enumvariant) IEnumVARIANT_Release(This->enumvariant);
|
||||||
release_dispex(&This->dispex);
|
release_dispex(&This->dispex);
|
||||||
heap_free( This );
|
heap_free( This );
|
||||||
}
|
}
|
||||||
|
@ -275,11 +298,11 @@ static HRESULT WINAPI xmlnodemap_reset(
|
||||||
|
|
||||||
static HRESULT WINAPI xmlnodemap__newEnum(
|
static HRESULT WINAPI xmlnodemap__newEnum(
|
||||||
IXMLDOMNamedNodeMap *iface,
|
IXMLDOMNamedNodeMap *iface,
|
||||||
IUnknown** ppUnk)
|
IUnknown** enumv)
|
||||||
{
|
{
|
||||||
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
xmlnodemap *This = impl_from_IXMLDOMNamedNodeMap( iface );
|
||||||
FIXME("(%p)->(%p)\n", This, ppUnk);
|
TRACE("(%p)->(%p)\n", This, enumv);
|
||||||
return E_NOTIMPL;
|
return create_enumvariant((IUnknown*)iface, TRUE, &nodemap_enumvariant, (IEnumVARIANT**)enumv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct IXMLDOMNamedNodeMapVtbl XMLDOMNamedNodeMapVtbl =
|
static const struct IXMLDOMNamedNodeMapVtbl XMLDOMNamedNodeMapVtbl =
|
||||||
|
@ -423,6 +446,7 @@ IXMLDOMNamedNodeMap *create_nodemap(xmlNodePtr node, const struct nodemap_funcs
|
||||||
This->node = node;
|
This->node = node;
|
||||||
This->ref = 1;
|
This->ref = 1;
|
||||||
This->iterator = 0;
|
This->iterator = 0;
|
||||||
|
This->enumvariant = NULL;
|
||||||
This->funcs = funcs;
|
This->funcs = funcs;
|
||||||
|
|
||||||
init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNamedNodeMap_iface, &xmlnodemap_dispex);
|
init_dispex(&This->dispex, (IUnknown*)&This->IXMLDOMNamedNodeMap_iface, &xmlnodemap_dispex);
|
||||||
|
|
|
@ -1749,6 +1749,11 @@ static const char default_ns_doc[] = {
|
||||||
" d=\"d attr\" />"
|
" 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[] = {
|
static const WCHAR nonexistent_fileW[] = {
|
||||||
'c', ':', '\\', 'N', 'o', 'n', 'e', 'x', 'i', 's', 't', 'e', 'n', 't', '.', 'x', 'm', 'l', 0
|
'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);
|
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)
|
START_TEST(domdoc)
|
||||||
{
|
{
|
||||||
IXMLDOMDocument *doc;
|
IXMLDOMDocument *doc;
|
||||||
|
@ -12256,6 +12369,7 @@ START_TEST(domdoc)
|
||||||
test_get_namespaces();
|
test_get_namespaces();
|
||||||
test_put_data();
|
test_put_data();
|
||||||
test_putref_schemas();
|
test_putref_schemas();
|
||||||
|
test_namedmap_newenum();
|
||||||
|
|
||||||
test_xsltemplate();
|
test_xsltemplate();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue