From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/msxml3/Makefile.in | 1 - dlls/msxml3/msxml_private.h | 2 - dlls/msxml3/xmldoc.c | 804 ++++++++++++++++++++++++++++++++++ dlls/msxml3/xmlelem.c | 840 ------------------------------------ 4 files changed, 804 insertions(+), 843 deletions(-) delete mode 100644 dlls/msxml3/xmlelem.c
diff --git a/dlls/msxml3/Makefile.in b/dlls/msxml3/Makefile.in index 7e59a223143..78cf5b27417 100644 --- a/dlls/msxml3/Makefile.in +++ b/dlls/msxml3/Makefile.in @@ -35,7 +35,6 @@ SOURCES = \ version.rc \ xdr.c \ xmldoc.c \ - xmlelem.c \ xmlparser.c \ xmlparser.idl \ xmlview.c \ diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index ea492bc6b36..63d85d3590e 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -162,8 +162,6 @@ extern void xmldoc_link_xmldecl(xmlDocPtr doc, xmlNodePtr node); extern xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc); extern MSXML_VERSION xmldoc_version( xmlDocPtr doc );
-extern HRESULT XMLElement_create( xmlNodePtr node, LPVOID *ppObj, BOOL own ); - extern void wineXmlCallbackLog(char const* caller, xmlErrorLevel lvl, char const* msg, va_list ap); extern void wineXmlCallbackError(char const* caller, const xmlError* err);
diff --git a/dlls/msxml3/xmldoc.c b/dlls/msxml3/xmldoc.c index 9e2eeecf28e..1b71607f23c 100644 --- a/dlls/msxml3/xmldoc.c +++ b/dlls/msxml3/xmldoc.c @@ -40,6 +40,810 @@
WINE_DEFAULT_DEBUG_CHANNEL(msxml);
+static HRESULT XMLElementCollection_create( xmlNodePtr node, LPVOID *ppObj ); + +/********************************************************************** + * IXMLElement2 + */ +typedef struct _xmlelem +{ + IXMLElement2 IXMLElement2_iface; + LONG ref; + xmlNodePtr node; + BOOL own; +} xmlelem; + +static inline xmlelem *impl_from_IXMLElement2(IXMLElement2 *iface) +{ + return CONTAINING_RECORD(iface, xmlelem, IXMLElement2_iface); +} + +static HRESULT WINAPI xmlelem_QueryInterface(IXMLElement2 *iface, REFIID riid, void** ppvObject) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IDispatch) || + IsEqualGUID(riid, &IID_IXMLElement) || + IsEqualGUID(riid, &IID_IXMLElement2)) + { + *ppvObject = iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + *ppvObject = NULL; + return E_NOINTERFACE; + } + + IXMLElement2_AddRef(iface); + + return S_OK; +} + +static ULONG WINAPI xmlelem_AddRef(IXMLElement2 *iface) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + TRACE("%p\n", This); + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI xmlelem_Release(IXMLElement2 *iface) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + LONG ref; + + TRACE("%p\n", This); + + ref = InterlockedDecrement(&This->ref); + if (ref == 0) + { + if (This->own) xmlFreeNode(This->node); + free(This); + } + + return ref; +} + +static HRESULT WINAPI xmlelem_GetTypeInfoCount(IXMLElement2 *iface, UINT* pctinfo) +{ + TRACE("%p, %p.\n", iface, pctinfo); + + *pctinfo = 1; + + return S_OK; +} + +static HRESULT WINAPI xmlelem_GetTypeInfo(IXMLElement2 *iface, UINT iTInfo, + LCID lcid, ITypeInfo** ppTInfo) +{ + TRACE("%p, %u, %lx, %p.\n", iface, iTInfo, lcid, ppTInfo); + + return get_typeinfo(IXMLElement2_tid, ppTInfo); +} + +static HRESULT WINAPI xmlelem_GetIDsOfNames(IXMLElement2 *iface, REFIID riid, + LPOLESTR* rgszNames, UINT cNames, + LCID lcid, DISPID* rgDispId) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("%p, %s, %p, %u, %lx, %p.\n", iface, debugstr_guid(riid), rgszNames, cNames, + lcid, rgDispId); + + if(!rgszNames || cNames == 0 || !rgDispId) + return E_INVALIDARG; + + hr = get_typeinfo(IXMLElement2_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI xmlelem_Invoke(IXMLElement2 *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, + DISPPARAMS* pDispParams, VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, UINT* puArgErr) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE("%p, %ld, %s, %lx, %d, %p, %p, %p, %p.\n", iface, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + + hr = get_typeinfo(IXMLElement2_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI xmlelem_get_tagName(IXMLElement2 *iface, BSTR *p) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + + TRACE("(%p)->(%p)\n", This, p); + + if (!p) + return E_INVALIDARG; + + if (*This->node->name) { + *p = bstr_from_xmlChar(This->node->name); + CharUpperBuffW(*p, SysStringLen(*p)); + }else { + *p = NULL; + } + + TRACE("returning %s\n", debugstr_w(*p)); + + return S_OK; +} + +static HRESULT WINAPI xmlelem_put_tagName(IXMLElement2 *iface, BSTR p) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + + FIXME("(%p)->(%s): stub\n", This, debugstr_w(p)); + + if (!p) + return E_INVALIDARG; + + return E_NOTIMPL; +} + +static HRESULT XMLElement_create(xmlNodePtr node, LPVOID *ppObj, BOOL own); + +static HRESULT WINAPI xmlelem_get_parent(IXMLElement2 *iface, IXMLElement2 **parent) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + + TRACE("(%p)->(%p)\n", This, parent); + + if (!parent) + return E_INVALIDARG; + + *parent = NULL; + + if (!This->node->parent) + return S_FALSE; + + return XMLElement_create(This->node->parent, (LPVOID *)parent, FALSE); +} + +static HRESULT WINAPI xmlelem_setAttribute(IXMLElement2 *iface, BSTR strPropertyName, + VARIANT PropertyValue) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + xmlChar *name, *value; + xmlAttrPtr attr; + + TRACE("(%p)->(%s %s)\n", This, debugstr_w(strPropertyName), debugstr_variant(&PropertyValue)); + + if (!strPropertyName || V_VT(&PropertyValue) != VT_BSTR) + return E_INVALIDARG; + + name = xmlchar_from_wchar(strPropertyName); + value = xmlchar_from_wchar(V_BSTR(&PropertyValue)); + attr = xmlSetProp(This->node, name, value); + + free(name); + free(value); + return (attr) ? S_OK : S_FALSE; +} + +static HRESULT WINAPI xmlelem_getAttribute(IXMLElement2 *iface, BSTR name, + VARIANT *value) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + xmlChar *val = NULL; + + TRACE("(%p)->(%s, %p)\n", This, debugstr_w(name), value); + + if (!value) + return E_INVALIDARG; + + VariantInit(value); + V_BSTR(value) = NULL; + + if (!name) + return E_INVALIDARG; + + /* case for xml:lang attribute */ + if (!lstrcmpiW(name, L"xml:lang")) + { + xmlNsPtr ns; + ns = xmlSearchNs(This->node->doc, This->node, (xmlChar*)"xml"); + val = xmlGetNsProp(This->node, (xmlChar*)"lang", ns->href); + } + else + { + xmlAttrPtr attr; + xmlChar *xml_name; + + xml_name = xmlchar_from_wchar(name); + attr = This->node->properties; + while (attr) + { + BSTR attr_name; + + attr_name = bstr_from_xmlChar(attr->name); + if (!lstrcmpiW(name, attr_name)) + { + val = xmlNodeListGetString(attr->doc, attr->children, 1); + SysFreeString(attr_name); + break; + } + + attr = attr->next; + SysFreeString(attr_name); + } + + free(xml_name); + } + + if (val) + { + V_VT(value) = VT_BSTR; + V_BSTR(value) = bstr_from_xmlChar(val); + } + + xmlFree(val); + TRACE("returning %s\n", debugstr_w(V_BSTR(value))); + return (val) ? S_OK : S_FALSE; +} + +static HRESULT WINAPI xmlelem_removeAttribute(IXMLElement2 *iface, BSTR strPropertyName) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + xmlChar *name; + xmlAttrPtr attr; + int res; + HRESULT hr = S_FALSE; + + TRACE("(%p)->(%s)\n", This, debugstr_w(strPropertyName)); + + if (!strPropertyName) + return E_INVALIDARG; + + name = xmlchar_from_wchar(strPropertyName); + attr = xmlHasProp(This->node, name); + if (!attr) + goto done; + + res = xmlRemoveProp(attr); + + if (res == 0) + hr = S_OK; + +done: + free(name); + return hr; +} + +static HRESULT WINAPI xmlelem_get_children(IXMLElement2 *iface, IXMLElementCollection **p) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + + TRACE("(%p)->(%p)\n", This, p); + + if (!p) + return E_INVALIDARG; + + return XMLElementCollection_create(This->node, (LPVOID *)p); +} + +static LONG type_libxml_to_msxml(xmlElementType type) +{ + switch (type) + { + case XML_ELEMENT_NODE: + return XMLELEMTYPE_ELEMENT; + case XML_TEXT_NODE: + return XMLELEMTYPE_TEXT; + case XML_COMMENT_NODE: + return XMLELEMTYPE_COMMENT; + case XML_DOCUMENT_NODE: + return XMLELEMTYPE_DOCUMENT; + case XML_DTD_NODE: + return XMLELEMTYPE_DTD; + case XML_PI_NODE: + return XMLELEMTYPE_PI; + default: + break; + } + + return XMLELEMTYPE_OTHER; +} + +static HRESULT WINAPI xmlelem_get_type(IXMLElement2 *iface, LONG *p) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + + TRACE("(%p)->(%p)\n", This, p); + + if (!p) + return E_INVALIDARG; + + *p = type_libxml_to_msxml(This->node->type); + TRACE("returning %ld\n", *p); + return S_OK; +} + +static HRESULT WINAPI xmlelem_get_text(IXMLElement2 *iface, BSTR *p) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + xmlChar *content; + + TRACE("(%p)->(%p)\n", This, p); + + if (!p) + return E_INVALIDARG; + + content = xmlNodeGetContent(This->node); + *p = bstr_from_xmlChar(content); + TRACE("returning %s\n", debugstr_w(*p)); + + xmlFree(content); + return S_OK; +} + +static HRESULT WINAPI xmlelem_put_text(IXMLElement2 *iface, BSTR p) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + xmlChar *content; + + TRACE("(%p)->(%s)\n", This, debugstr_w(p)); + + /* FIXME: test which types can be used */ + if (This->node->type == XML_ELEMENT_NODE) + return E_NOTIMPL; + + content = xmlchar_from_wchar(p); + xmlNodeSetContent(This->node, content); + + free(content); + + return S_OK; +} + +static HRESULT WINAPI xmlelem_addChild(IXMLElement2 *iface, IXMLElement2 *pChildElem, + LONG lIndex, LONG lreserved) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + xmlelem *childElem = impl_from_IXMLElement2(pChildElem); + xmlNodePtr child; + + TRACE("%p, %p, %ld, %ld.\n", iface, pChildElem, lIndex, lreserved); + + if (lIndex == 0) + child = xmlAddChild(This->node, childElem->node); + else + child = xmlAddNextSibling(This->node, childElem->node->last); + + /* parent is responsible for child data */ + if (child) childElem->own = FALSE; + + return (child) ? S_OK : S_FALSE; +} + +static HRESULT WINAPI xmlelem_removeChild(IXMLElement2 *iface, IXMLElement2 *pChildElem) +{ + xmlelem *This = impl_from_IXMLElement2(iface); + xmlelem *childElem = impl_from_IXMLElement2(pChildElem); + + TRACE("(%p)->(%p)\n", This, childElem); + + if (!pChildElem) + return E_INVALIDARG; + + /* only supported for This is childElem parent case */ + if (This->node != childElem->node->parent) + return E_INVALIDARG; + + xmlUnlinkNode(childElem->node); + /* standalone element now */ + childElem->own = TRUE; + + return S_OK; +} + +static HRESULT WINAPI xmlelem_attributes(IXMLElement2 *iface, IXMLElementCollection **p) +{ + FIXME("%p, %p stub\n", iface, p); + + return E_NOTIMPL; +} + +static const struct IXMLElement2Vtbl xmlelem_vtbl = +{ + xmlelem_QueryInterface, + xmlelem_AddRef, + xmlelem_Release, + xmlelem_GetTypeInfoCount, + xmlelem_GetTypeInfo, + xmlelem_GetIDsOfNames, + xmlelem_Invoke, + xmlelem_get_tagName, + xmlelem_put_tagName, + xmlelem_get_parent, + xmlelem_setAttribute, + xmlelem_getAttribute, + xmlelem_removeAttribute, + xmlelem_get_children, + xmlelem_get_type, + xmlelem_get_text, + xmlelem_put_text, + xmlelem_addChild, + xmlelem_removeChild, + xmlelem_attributes, +}; + +static HRESULT XMLElement_create(xmlNodePtr node, LPVOID *ppObj, BOOL own) +{ + xmlelem *elem; + + TRACE("(%p)\n", ppObj); + + if (!ppObj) + return E_INVALIDARG; + + *ppObj = NULL; + + elem = malloc(sizeof(*elem)); + if(!elem) + return E_OUTOFMEMORY; + + elem->IXMLElement2_iface.lpVtbl = &xmlelem_vtbl; + elem->ref = 1; + elem->node = node; + elem->own = own; + + *ppObj = &elem->IXMLElement2_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} + +/************************************************************************ + * IXMLElementCollection + */ +typedef struct _xmlelem_collection +{ + IXMLElementCollection IXMLElementCollection_iface; + IEnumVARIANT IEnumVARIANT_iface; + LONG ref; + LONG length; + xmlNodePtr node; + + /* IEnumVARIANT members */ + xmlNodePtr current; +} xmlelem_collection; + +static inline LONG xmlelem_collection_updatelength(xmlelem_collection *collection) +{ + xmlNodePtr ptr = collection->node->children; + + collection->length = 0; + while (ptr) + { + collection->length++; + ptr = ptr->next; + } + return collection->length; +} + +static inline xmlelem_collection *impl_from_IXMLElementCollection(IXMLElementCollection *iface) +{ + return CONTAINING_RECORD(iface, xmlelem_collection, IXMLElementCollection_iface); +} + +static inline xmlelem_collection *impl_from_IEnumVARIANT(IEnumVARIANT *iface) +{ + return CONTAINING_RECORD(iface, xmlelem_collection, IEnumVARIANT_iface); +} + +static HRESULT WINAPI xmlelem_collection_QueryInterface(IXMLElementCollection *iface, REFIID riid, void** ppvObject) +{ + xmlelem_collection *This = impl_from_IXMLElementCollection(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IXMLElementCollection)) + { + *ppvObject = iface; + } + else if (IsEqualGUID(riid, &IID_IEnumVARIANT)) + { + *ppvObject = &This->IEnumVARIANT_iface; + } + else + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + *ppvObject = NULL; + return E_NOINTERFACE; + } + + IXMLElementCollection_AddRef(iface); + + return S_OK; +} + +static ULONG WINAPI xmlelem_collection_AddRef(IXMLElementCollection *iface) +{ + xmlelem_collection *This = impl_from_IXMLElementCollection(iface); + TRACE("(%p)\n", This); + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI xmlelem_collection_Release(IXMLElementCollection *iface) +{ + xmlelem_collection *This = impl_from_IXMLElementCollection(iface); + LONG ref; + + TRACE("(%p)\n", This); + + ref = InterlockedDecrement(&This->ref); + if (ref == 0) + { + free(This); + } + + return ref; +} + +static HRESULT WINAPI xmlelem_collection_GetTypeInfoCount(IXMLElementCollection *iface, UINT* pctinfo) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI xmlelem_collection_GetTypeInfo(IXMLElementCollection *iface, UINT iTInfo, + LCID lcid, ITypeInfo** ppTInfo) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI xmlelem_collection_GetIDsOfNames(IXMLElementCollection *iface, REFIID riid, + LPOLESTR* rgszNames, UINT cNames, + LCID lcid, DISPID* rgDispId) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI xmlelem_collection_Invoke(IXMLElementCollection *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, + DISPPARAMS* pDispParams, VARIANT* pVarResult, + EXCEPINFO* pExcepInfo, UINT* puArgErr) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI xmlelem_collection_put_length(IXMLElementCollection *iface, LONG v) +{ + TRACE("%p, %ld.\n", iface, v); + + return E_FAIL; +} + +static HRESULT WINAPI xmlelem_collection_get_length(IXMLElementCollection *iface, LONG *p) +{ + xmlelem_collection *This = impl_from_IXMLElementCollection(iface); + + TRACE("(%p)->(%p)\n", This, p); + + if (!p) + return E_INVALIDARG; + + *p = xmlelem_collection_updatelength(This); + return S_OK; +} + +static HRESULT WINAPI xmlelem_collection_get__newEnum(IXMLElementCollection *iface, IUnknown **ppUnk) +{ + xmlelem_collection *This = impl_from_IXMLElementCollection(iface); + + TRACE("(%p)->(%p)\n", This, ppUnk); + + if (!ppUnk) + return E_INVALIDARG; + + IXMLElementCollection_AddRef(iface); + *ppUnk = (IUnknown *)&This->IEnumVARIANT_iface; + return S_OK; +} + +static HRESULT WINAPI xmlelem_collection_item(IXMLElementCollection *iface, VARIANT var1, + VARIANT var2, IDispatch **ppDisp) +{ + xmlelem_collection *This = impl_from_IXMLElementCollection(iface); + xmlNodePtr ptr = This->node->children; + int index, i; + + TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&var1), debugstr_variant(&var2), ppDisp); + + if (!ppDisp) + return E_INVALIDARG; + + *ppDisp = NULL; + + index = V_I4(&var1); + if (index < 0) + return E_INVALIDARG; + + xmlelem_collection_updatelength(This); + if (index >= This->length) + return E_FAIL; + + for (i = 0; i < index; i++) + ptr = ptr->next; + + return XMLElement_create(ptr, (LPVOID *)ppDisp, FALSE); +} + +static const struct IXMLElementCollectionVtbl xmlelem_collection_vtbl = +{ + xmlelem_collection_QueryInterface, + xmlelem_collection_AddRef, + xmlelem_collection_Release, + xmlelem_collection_GetTypeInfoCount, + xmlelem_collection_GetTypeInfo, + xmlelem_collection_GetIDsOfNames, + xmlelem_collection_Invoke, + xmlelem_collection_put_length, + xmlelem_collection_get_length, + xmlelem_collection_get__newEnum, + xmlelem_collection_item +}; + +/************************************************************************ + * xmlelem_collection implementation of IEnumVARIANT. + */ +static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_QueryInterface( + IEnumVARIANT *iface, REFIID riid, LPVOID *ppvObj) +{ + xmlelem_collection *this = impl_from_IEnumVARIANT(iface); + + TRACE("(%p)->(%s %p)\n", this, debugstr_guid(riid), ppvObj); + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IEnumVARIANT)) + { + *ppvObj = iface; + IEnumVARIANT_AddRef(iface); + return S_OK; + } + + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + *ppvObj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI xmlelem_collection_IEnumVARIANT_AddRef( + IEnumVARIANT *iface) +{ + xmlelem_collection *this = impl_from_IEnumVARIANT(iface); + return IXMLElementCollection_AddRef(&this->IXMLElementCollection_iface); +} + +static ULONG WINAPI xmlelem_collection_IEnumVARIANT_Release( + IEnumVARIANT *iface) +{ + xmlelem_collection *this = impl_from_IEnumVARIANT(iface); + return IXMLElementCollection_Release(&this->IXMLElementCollection_iface); +} + +static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Next( + IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *fetched) +{ + xmlelem_collection *This = impl_from_IEnumVARIANT(iface); + HRESULT hr; + + TRACE("%p, %lu, %p, %p.\n", iface, celt, rgVar, fetched); + + if (!rgVar) + return E_INVALIDARG; + + if (fetched) *fetched = 0; + + if (!This->current) + { + V_VT(rgVar) = VT_EMPTY; + return S_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 (fetched) ++*fetched; + rgVar++; + celt--; + } + if (!celt) return S_OK; + V_VT(rgVar) = VT_EMPTY; + return S_FALSE; +} + +static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Skip( + IEnumVARIANT *iface, ULONG celt) +{ + FIXME("%p, %lu: stub\n", iface, celt); + return E_NOTIMPL; +} + +static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Reset( + IEnumVARIANT *iface) +{ + xmlelem_collection *This = impl_from_IEnumVARIANT(iface); + TRACE("(%p)\n", This); + This->current = This->node->children; + return S_OK; +} + +static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Clone( + IEnumVARIANT *iface, IEnumVARIANT **ppEnum) +{ + xmlelem_collection *This = impl_from_IEnumVARIANT(iface); + FIXME("(%p)->(%p): stub\n", This, ppEnum); + return E_NOTIMPL; +} + +static const struct IEnumVARIANTVtbl xmlelem_collection_IEnumVARIANTvtbl = +{ + xmlelem_collection_IEnumVARIANT_QueryInterface, + xmlelem_collection_IEnumVARIANT_AddRef, + xmlelem_collection_IEnumVARIANT_Release, + xmlelem_collection_IEnumVARIANT_Next, + xmlelem_collection_IEnumVARIANT_Skip, + xmlelem_collection_IEnumVARIANT_Reset, + xmlelem_collection_IEnumVARIANT_Clone +}; + +static HRESULT XMLElementCollection_create(xmlNodePtr node, LPVOID *ppObj) +{ + xmlelem_collection *collection; + + TRACE("(%p)\n", ppObj); + + *ppObj = NULL; + + if (!node->children) + return S_FALSE; + + collection = malloc(sizeof(*collection)); + if(!collection) + return E_OUTOFMEMORY; + + collection->IXMLElementCollection_iface.lpVtbl = &xmlelem_collection_vtbl; + collection->IEnumVARIANT_iface.lpVtbl = &xmlelem_collection_IEnumVARIANTvtbl; + collection->ref = 1; + collection->length = 0; + collection->node = node; + collection->current = node->children; + xmlelem_collection_updatelength(collection); + + *ppObj = &collection->IXMLElementCollection_iface; + + TRACE("returning iface %p\n", *ppObj); + return S_OK; +} + /* FIXME: IXMLDocument needs to implement * - IXMLError * - IPersistMoniker diff --git a/dlls/msxml3/xmlelem.c b/dlls/msxml3/xmlelem.c deleted file mode 100644 index e6a569ac5f2..00000000000 --- a/dlls/msxml3/xmlelem.c +++ /dev/null @@ -1,840 +0,0 @@ -/* - * XML Element implementation - * - * Copyright 2007 James Hawkins - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#define COBJMACROS - -#include <stdarg.h> -#include <libxml/parser.h> -#include <libxml/xmlerror.h> - -#include "windef.h" -#include "winbase.h" -#include "winuser.h" -#include "ole2.h" -#include "msxml6.h" -#include "ocidl.h" - -#include "wine/debug.h" - -#include "msxml_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(msxml); - -static HRESULT XMLElementCollection_create( xmlNodePtr node, LPVOID *ppObj ); - -/********************************************************************** - * IXMLElement2 - */ -typedef struct _xmlelem -{ - IXMLElement2 IXMLElement2_iface; - LONG ref; - xmlNodePtr node; - BOOL own; -} xmlelem; - -static inline xmlelem *impl_from_IXMLElement2(IXMLElement2 *iface) -{ - return CONTAINING_RECORD(iface, xmlelem, IXMLElement2_iface); -} - -static HRESULT WINAPI xmlelem_QueryInterface(IXMLElement2 *iface, REFIID riid, void** ppvObject) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); - - if (IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IDispatch) || - IsEqualGUID(riid, &IID_IXMLElement) || - IsEqualGUID(riid, &IID_IXMLElement2)) - { - *ppvObject = iface; - } - else - { - FIXME("interface %s not implemented\n", debugstr_guid(riid)); - *ppvObject = NULL; - return E_NOINTERFACE; - } - - IXMLElement2_AddRef(iface); - - return S_OK; -} - -static ULONG WINAPI xmlelem_AddRef(IXMLElement2 *iface) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - TRACE("%p\n", This); - return InterlockedIncrement(&This->ref); -} - -static ULONG WINAPI xmlelem_Release(IXMLElement2 *iface) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - LONG ref; - - TRACE("%p\n", This); - - ref = InterlockedDecrement(&This->ref); - if (ref == 0) - { - if (This->own) xmlFreeNode(This->node); - free(This); - } - - return ref; -} - -static HRESULT WINAPI xmlelem_GetTypeInfoCount(IXMLElement2 *iface, UINT* pctinfo) -{ - TRACE("%p, %p.\n", iface, pctinfo); - - *pctinfo = 1; - - return S_OK; -} - -static HRESULT WINAPI xmlelem_GetTypeInfo(IXMLElement2 *iface, UINT iTInfo, - LCID lcid, ITypeInfo** ppTInfo) -{ - TRACE("%p, %u, %lx, %p.\n", iface, iTInfo, lcid, ppTInfo); - - return get_typeinfo(IXMLElement2_tid, ppTInfo); -} - -static HRESULT WINAPI xmlelem_GetIDsOfNames(IXMLElement2 *iface, REFIID riid, - LPOLESTR* rgszNames, UINT cNames, - LCID lcid, DISPID* rgDispId) -{ - ITypeInfo *typeinfo; - HRESULT hr; - - TRACE("%p, %s, %p, %u, %lx, %p.\n", iface, debugstr_guid(riid), rgszNames, cNames, - lcid, rgDispId); - - if(!rgszNames || cNames == 0 || !rgDispId) - return E_INVALIDARG; - - hr = get_typeinfo(IXMLElement2_tid, &typeinfo); - if(SUCCEEDED(hr)) - { - hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); - ITypeInfo_Release(typeinfo); - } - - return hr; -} - -static HRESULT WINAPI xmlelem_Invoke(IXMLElement2 *iface, DISPID dispIdMember, - REFIID riid, LCID lcid, WORD wFlags, - DISPPARAMS* pDispParams, VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, UINT* puArgErr) -{ - ITypeInfo *typeinfo; - HRESULT hr; - - TRACE("%p, %ld, %s, %lx, %d, %p, %p, %p, %p.\n", iface, dispIdMember, debugstr_guid(riid), - lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - - hr = get_typeinfo(IXMLElement2_tid, &typeinfo); - if(SUCCEEDED(hr)) - { - hr = ITypeInfo_Invoke(typeinfo, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); - ITypeInfo_Release(typeinfo); - } - - return hr; -} - -static HRESULT WINAPI xmlelem_get_tagName(IXMLElement2 *iface, BSTR *p) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - - TRACE("(%p)->(%p)\n", This, p); - - if (!p) - return E_INVALIDARG; - - if (*This->node->name) { - *p = bstr_from_xmlChar(This->node->name); - CharUpperBuffW(*p, SysStringLen(*p)); - }else { - *p = NULL; - } - - TRACE("returning %s\n", debugstr_w(*p)); - - return S_OK; -} - -static HRESULT WINAPI xmlelem_put_tagName(IXMLElement2 *iface, BSTR p) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - - FIXME("(%p)->(%s): stub\n", This, debugstr_w(p)); - - if (!p) - return E_INVALIDARG; - - return E_NOTIMPL; -} - -static HRESULT WINAPI xmlelem_get_parent(IXMLElement2 *iface, IXMLElement2 **parent) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - - TRACE("(%p)->(%p)\n", This, parent); - - if (!parent) - return E_INVALIDARG; - - *parent = NULL; - - if (!This->node->parent) - return S_FALSE; - - return XMLElement_create(This->node->parent, (LPVOID *)parent, FALSE); -} - -static HRESULT WINAPI xmlelem_setAttribute(IXMLElement2 *iface, BSTR strPropertyName, - VARIANT PropertyValue) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - xmlChar *name, *value; - xmlAttrPtr attr; - - TRACE("(%p)->(%s %s)\n", This, debugstr_w(strPropertyName), debugstr_variant(&PropertyValue)); - - if (!strPropertyName || V_VT(&PropertyValue) != VT_BSTR) - return E_INVALIDARG; - - name = xmlchar_from_wchar(strPropertyName); - value = xmlchar_from_wchar(V_BSTR(&PropertyValue)); - attr = xmlSetProp(This->node, name, value); - - free(name); - free(value); - return (attr) ? S_OK : S_FALSE; -} - -static HRESULT WINAPI xmlelem_getAttribute(IXMLElement2 *iface, BSTR name, - VARIANT *value) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - xmlChar *val = NULL; - - TRACE("(%p)->(%s, %p)\n", This, debugstr_w(name), value); - - if (!value) - return E_INVALIDARG; - - VariantInit(value); - V_BSTR(value) = NULL; - - if (!name) - return E_INVALIDARG; - - /* case for xml:lang attribute */ - if (!lstrcmpiW(name, L"xml:lang")) - { - xmlNsPtr ns; - ns = xmlSearchNs(This->node->doc, This->node, (xmlChar*)"xml"); - val = xmlGetNsProp(This->node, (xmlChar*)"lang", ns->href); - } - else - { - xmlAttrPtr attr; - xmlChar *xml_name; - - xml_name = xmlchar_from_wchar(name); - attr = This->node->properties; - while (attr) - { - BSTR attr_name; - - attr_name = bstr_from_xmlChar(attr->name); - if (!lstrcmpiW(name, attr_name)) - { - val = xmlNodeListGetString(attr->doc, attr->children, 1); - SysFreeString(attr_name); - break; - } - - attr = attr->next; - SysFreeString(attr_name); - } - - free(xml_name); - } - - if (val) - { - V_VT(value) = VT_BSTR; - V_BSTR(value) = bstr_from_xmlChar(val); - } - - xmlFree(val); - TRACE("returning %s\n", debugstr_w(V_BSTR(value))); - return (val) ? S_OK : S_FALSE; -} - -static HRESULT WINAPI xmlelem_removeAttribute(IXMLElement2 *iface, BSTR strPropertyName) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - xmlChar *name; - xmlAttrPtr attr; - int res; - HRESULT hr = S_FALSE; - - TRACE("(%p)->(%s)\n", This, debugstr_w(strPropertyName)); - - if (!strPropertyName) - return E_INVALIDARG; - - name = xmlchar_from_wchar(strPropertyName); - attr = xmlHasProp(This->node, name); - if (!attr) - goto done; - - res = xmlRemoveProp(attr); - - if (res == 0) - hr = S_OK; - -done: - free(name); - return hr; -} - -static HRESULT WINAPI xmlelem_get_children(IXMLElement2 *iface, IXMLElementCollection **p) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - - TRACE("(%p)->(%p)\n", This, p); - - if (!p) - return E_INVALIDARG; - - return XMLElementCollection_create(This->node, (LPVOID *)p); -} - -static LONG type_libxml_to_msxml(xmlElementType type) -{ - switch (type) - { - case XML_ELEMENT_NODE: - return XMLELEMTYPE_ELEMENT; - case XML_TEXT_NODE: - return XMLELEMTYPE_TEXT; - case XML_COMMENT_NODE: - return XMLELEMTYPE_COMMENT; - case XML_DOCUMENT_NODE: - return XMLELEMTYPE_DOCUMENT; - case XML_DTD_NODE: - return XMLELEMTYPE_DTD; - case XML_PI_NODE: - return XMLELEMTYPE_PI; - default: - break; - } - - return XMLELEMTYPE_OTHER; -} - -static HRESULT WINAPI xmlelem_get_type(IXMLElement2 *iface, LONG *p) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - - TRACE("(%p)->(%p)\n", This, p); - - if (!p) - return E_INVALIDARG; - - *p = type_libxml_to_msxml(This->node->type); - TRACE("returning %ld\n", *p); - return S_OK; -} - -static HRESULT WINAPI xmlelem_get_text(IXMLElement2 *iface, BSTR *p) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - xmlChar *content; - - TRACE("(%p)->(%p)\n", This, p); - - if (!p) - return E_INVALIDARG; - - content = xmlNodeGetContent(This->node); - *p = bstr_from_xmlChar(content); - TRACE("returning %s\n", debugstr_w(*p)); - - xmlFree(content); - return S_OK; -} - -static HRESULT WINAPI xmlelem_put_text(IXMLElement2 *iface, BSTR p) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - xmlChar *content; - - TRACE("(%p)->(%s)\n", This, debugstr_w(p)); - - /* FIXME: test which types can be used */ - if (This->node->type == XML_ELEMENT_NODE) - return E_NOTIMPL; - - content = xmlchar_from_wchar(p); - xmlNodeSetContent(This->node, content); - - free(content); - - return S_OK; -} - -static HRESULT WINAPI xmlelem_addChild(IXMLElement2 *iface, IXMLElement2 *pChildElem, - LONG lIndex, LONG lreserved) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - xmlelem *childElem = impl_from_IXMLElement2(pChildElem); - xmlNodePtr child; - - TRACE("%p, %p, %ld, %ld.\n", iface, pChildElem, lIndex, lreserved); - - if (lIndex == 0) - child = xmlAddChild(This->node, childElem->node); - else - child = xmlAddNextSibling(This->node, childElem->node->last); - - /* parent is responsible for child data */ - if (child) childElem->own = FALSE; - - return (child) ? S_OK : S_FALSE; -} - -static HRESULT WINAPI xmlelem_removeChild(IXMLElement2 *iface, IXMLElement2 *pChildElem) -{ - xmlelem *This = impl_from_IXMLElement2(iface); - xmlelem *childElem = impl_from_IXMLElement2(pChildElem); - - TRACE("(%p)->(%p)\n", This, childElem); - - if (!pChildElem) - return E_INVALIDARG; - - /* only supported for This is childElem parent case */ - if (This->node != childElem->node->parent) - return E_INVALIDARG; - - xmlUnlinkNode(childElem->node); - /* standalone element now */ - childElem->own = TRUE; - - return S_OK; -} - -static HRESULT WINAPI xmlelem_attributes(IXMLElement2 *iface, IXMLElementCollection **p) -{ - FIXME("%p, %p stub\n", iface, p); - - return E_NOTIMPL; -} - -static const struct IXMLElement2Vtbl xmlelem_vtbl = -{ - xmlelem_QueryInterface, - xmlelem_AddRef, - xmlelem_Release, - xmlelem_GetTypeInfoCount, - xmlelem_GetTypeInfo, - xmlelem_GetIDsOfNames, - xmlelem_Invoke, - xmlelem_get_tagName, - xmlelem_put_tagName, - xmlelem_get_parent, - xmlelem_setAttribute, - xmlelem_getAttribute, - xmlelem_removeAttribute, - xmlelem_get_children, - xmlelem_get_type, - xmlelem_get_text, - xmlelem_put_text, - xmlelem_addChild, - xmlelem_removeChild, - xmlelem_attributes, -}; - -HRESULT XMLElement_create(xmlNodePtr node, LPVOID *ppObj, BOOL own) -{ - xmlelem *elem; - - TRACE("(%p)\n", ppObj); - - if (!ppObj) - return E_INVALIDARG; - - *ppObj = NULL; - - elem = malloc(sizeof(*elem)); - if(!elem) - return E_OUTOFMEMORY; - - elem->IXMLElement2_iface.lpVtbl = &xmlelem_vtbl; - elem->ref = 1; - elem->node = node; - elem->own = own; - - *ppObj = &elem->IXMLElement2_iface; - - TRACE("returning iface %p\n", *ppObj); - return S_OK; -} - -/************************************************************************ - * IXMLElementCollection - */ -typedef struct _xmlelem_collection -{ - IXMLElementCollection IXMLElementCollection_iface; - IEnumVARIANT IEnumVARIANT_iface; - LONG ref; - LONG length; - xmlNodePtr node; - - /* IEnumVARIANT members */ - xmlNodePtr current; -} xmlelem_collection; - -static inline LONG xmlelem_collection_updatelength(xmlelem_collection *collection) -{ - xmlNodePtr ptr = collection->node->children; - - collection->length = 0; - while (ptr) - { - collection->length++; - ptr = ptr->next; - } - return collection->length; -} - -static inline xmlelem_collection *impl_from_IXMLElementCollection(IXMLElementCollection *iface) -{ - return CONTAINING_RECORD(iface, xmlelem_collection, IXMLElementCollection_iface); -} - -static inline xmlelem_collection *impl_from_IEnumVARIANT(IEnumVARIANT *iface) -{ - return CONTAINING_RECORD(iface, xmlelem_collection, IEnumVARIANT_iface); -} - -static HRESULT WINAPI xmlelem_collection_QueryInterface(IXMLElementCollection *iface, REFIID riid, void** ppvObject) -{ - xmlelem_collection *This = impl_from_IXMLElementCollection(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); - - if (IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IXMLElementCollection)) - { - *ppvObject = iface; - } - else if (IsEqualGUID(riid, &IID_IEnumVARIANT)) - { - *ppvObject = &This->IEnumVARIANT_iface; - } - else - { - FIXME("interface %s not implemented\n", debugstr_guid(riid)); - *ppvObject = NULL; - return E_NOINTERFACE; - } - - IXMLElementCollection_AddRef(iface); - - return S_OK; -} - -static ULONG WINAPI xmlelem_collection_AddRef(IXMLElementCollection *iface) -{ - xmlelem_collection *This = impl_from_IXMLElementCollection(iface); - TRACE("(%p)\n", This); - return InterlockedIncrement(&This->ref); -} - -static ULONG WINAPI xmlelem_collection_Release(IXMLElementCollection *iface) -{ - xmlelem_collection *This = impl_from_IXMLElementCollection(iface); - LONG ref; - - TRACE("(%p)\n", This); - - ref = InterlockedDecrement(&This->ref); - if (ref == 0) - { - free(This); - } - - return ref; -} - -static HRESULT WINAPI xmlelem_collection_GetTypeInfoCount(IXMLElementCollection *iface, UINT* pctinfo) -{ - FIXME("\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI xmlelem_collection_GetTypeInfo(IXMLElementCollection *iface, UINT iTInfo, - LCID lcid, ITypeInfo** ppTInfo) -{ - FIXME("\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI xmlelem_collection_GetIDsOfNames(IXMLElementCollection *iface, REFIID riid, - LPOLESTR* rgszNames, UINT cNames, - LCID lcid, DISPID* rgDispId) -{ - FIXME("\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI xmlelem_collection_Invoke(IXMLElementCollection *iface, DISPID dispIdMember, - REFIID riid, LCID lcid, WORD wFlags, - DISPPARAMS* pDispParams, VARIANT* pVarResult, - EXCEPINFO* pExcepInfo, UINT* puArgErr) -{ - FIXME("\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI xmlelem_collection_put_length(IXMLElementCollection *iface, LONG v) -{ - TRACE("%p, %ld.\n", iface, v); - - return E_FAIL; -} - -static HRESULT WINAPI xmlelem_collection_get_length(IXMLElementCollection *iface, LONG *p) -{ - xmlelem_collection *This = impl_from_IXMLElementCollection(iface); - - TRACE("(%p)->(%p)\n", This, p); - - if (!p) - return E_INVALIDARG; - - *p = xmlelem_collection_updatelength(This); - return S_OK; -} - -static HRESULT WINAPI xmlelem_collection_get__newEnum(IXMLElementCollection *iface, IUnknown **ppUnk) -{ - xmlelem_collection *This = impl_from_IXMLElementCollection(iface); - - TRACE("(%p)->(%p)\n", This, ppUnk); - - if (!ppUnk) - return E_INVALIDARG; - - IXMLElementCollection_AddRef(iface); - *ppUnk = (IUnknown *)&This->IEnumVARIANT_iface; - return S_OK; -} - -static HRESULT WINAPI xmlelem_collection_item(IXMLElementCollection *iface, VARIANT var1, - VARIANT var2, IDispatch **ppDisp) -{ - xmlelem_collection *This = impl_from_IXMLElementCollection(iface); - xmlNodePtr ptr = This->node->children; - int index, i; - - TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&var1), debugstr_variant(&var2), ppDisp); - - if (!ppDisp) - return E_INVALIDARG; - - *ppDisp = NULL; - - index = V_I4(&var1); - if (index < 0) - return E_INVALIDARG; - - xmlelem_collection_updatelength(This); - if (index >= This->length) - return E_FAIL; - - for (i = 0; i < index; i++) - ptr = ptr->next; - - return XMLElement_create(ptr, (LPVOID *)ppDisp, FALSE); -} - -static const struct IXMLElementCollectionVtbl xmlelem_collection_vtbl = -{ - xmlelem_collection_QueryInterface, - xmlelem_collection_AddRef, - xmlelem_collection_Release, - xmlelem_collection_GetTypeInfoCount, - xmlelem_collection_GetTypeInfo, - xmlelem_collection_GetIDsOfNames, - xmlelem_collection_Invoke, - xmlelem_collection_put_length, - xmlelem_collection_get_length, - xmlelem_collection_get__newEnum, - xmlelem_collection_item -}; - -/************************************************************************ - * xmlelem_collection implementation of IEnumVARIANT. - */ -static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_QueryInterface( - IEnumVARIANT *iface, REFIID riid, LPVOID *ppvObj) -{ - xmlelem_collection *this = impl_from_IEnumVARIANT(iface); - - TRACE("(%p)->(%s %p)\n", this, debugstr_guid(riid), ppvObj); - - if (IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IEnumVARIANT)) - { - *ppvObj = iface; - IEnumVARIANT_AddRef(iface); - return S_OK; - } - - FIXME("interface %s not implemented\n", debugstr_guid(riid)); - *ppvObj = NULL; - return E_NOINTERFACE; -} - -static ULONG WINAPI xmlelem_collection_IEnumVARIANT_AddRef( - IEnumVARIANT *iface) -{ - xmlelem_collection *this = impl_from_IEnumVARIANT(iface); - return IXMLElementCollection_AddRef(&this->IXMLElementCollection_iface); -} - -static ULONG WINAPI xmlelem_collection_IEnumVARIANT_Release( - IEnumVARIANT *iface) -{ - xmlelem_collection *this = impl_from_IEnumVARIANT(iface); - return IXMLElementCollection_Release(&this->IXMLElementCollection_iface); -} - -static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Next( - IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *fetched) -{ - xmlelem_collection *This = impl_from_IEnumVARIANT(iface); - HRESULT hr; - - TRACE("%p, %lu, %p, %p.\n", iface, celt, rgVar, fetched); - - if (!rgVar) - return E_INVALIDARG; - - if (fetched) *fetched = 0; - - if (!This->current) - { - V_VT(rgVar) = VT_EMPTY; - return S_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 (fetched) ++*fetched; - rgVar++; - celt--; - } - if (!celt) return S_OK; - V_VT(rgVar) = VT_EMPTY; - return S_FALSE; -} - -static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Skip( - IEnumVARIANT *iface, ULONG celt) -{ - FIXME("%p, %lu: stub\n", iface, celt); - return E_NOTIMPL; -} - -static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Reset( - IEnumVARIANT *iface) -{ - xmlelem_collection *This = impl_from_IEnumVARIANT(iface); - TRACE("(%p)\n", This); - This->current = This->node->children; - return S_OK; -} - -static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Clone( - IEnumVARIANT *iface, IEnumVARIANT **ppEnum) -{ - xmlelem_collection *This = impl_from_IEnumVARIANT(iface); - FIXME("(%p)->(%p): stub\n", This, ppEnum); - return E_NOTIMPL; -} - -static const struct IEnumVARIANTVtbl xmlelem_collection_IEnumVARIANTvtbl = -{ - xmlelem_collection_IEnumVARIANT_QueryInterface, - xmlelem_collection_IEnumVARIANT_AddRef, - xmlelem_collection_IEnumVARIANT_Release, - xmlelem_collection_IEnumVARIANT_Next, - xmlelem_collection_IEnumVARIANT_Skip, - xmlelem_collection_IEnumVARIANT_Reset, - xmlelem_collection_IEnumVARIANT_Clone -}; - -static HRESULT XMLElementCollection_create(xmlNodePtr node, LPVOID *ppObj) -{ - xmlelem_collection *collection; - - TRACE("(%p)\n", ppObj); - - *ppObj = NULL; - - if (!node->children) - return S_FALSE; - - collection = malloc(sizeof(*collection)); - if(!collection) - return E_OUTOFMEMORY; - - collection->IXMLElementCollection_iface.lpVtbl = &xmlelem_collection_vtbl; - collection->IEnumVARIANT_iface.lpVtbl = &xmlelem_collection_IEnumVARIANTvtbl; - collection->ref = 1; - collection->length = 0; - collection->node = node; - collection->current = node->children; - xmlelem_collection_updatelength(collection); - - *ppObj = &collection->IXMLElementCollection_iface; - - TRACE("returning iface %p\n", *ppObj); - return S_OK; -}
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/msxml3/tests/xmldoc.c | 115 ++++++++++++++++++++++++++++++++++--- 1 file changed, 108 insertions(+), 7 deletions(-)
diff --git a/dlls/msxml3/tests/xmldoc.c b/dlls/msxml3/tests/xmldoc.c index 33669cfaba6..cc1fa49beff 100644 --- a/dlls/msxml3/tests/xmldoc.c +++ b/dlls/msxml3/tests/xmldoc.c @@ -207,13 +207,6 @@ static void test_xmldoc(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(element != NULL, "Expected non-NULL element\n");
- /* ::root() returns new instance each time */ - hr = IXMLDocument_get_root(doc, &child); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - ok(child != NULL, "Expected non-NULL element\n"); - ok(child != element, "Expected new element instance\n"); - IXMLElement_Release(child); - hr = IXMLElement_get_type(element, &type); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(type == XMLELEMTYPE_ELEMENT, "Unexpected type %ld.\n", type); @@ -1296,6 +1289,113 @@ static void test_xmldoc_doctype(void) IXMLDocument_Release(doc); }
+static const char doc_data8[] = + "<?xml version=\"1.0\"?><a><b><c/></b><e/></a>"; + +static void test_xmldoc_root(void) +{ + IXMLElement *element, *element2; + IXMLElementCollection *c, *c2; + IXMLElement *child, *parent; + IXMLDocument *doc; + LONG type, count; + IDispatch *disp; + HRESULT hr; + VARIANT v; + BSTR s; + + hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDocument, (void **)&doc); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDocument_get_root(doc, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + element = (void *)1; + hr = IXMLDocument_get_root(doc, &element); + ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); + ok(!element, "Unexpected pointer.\n"); + + hr = load_document(doc, doc_data8, sizeof(doc_data8) - 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDocument_get_root(doc, &element); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + parent = (void *)1; + hr = IXMLElement_get_parent(element, &parent); + todo_wine + ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!parent, "Unexpected pointer.\n"); + + hr = IXMLDocument_get_root(doc, &element2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(element != element2, "Unexpected pointer.\n"); + + hr = IXMLElement_get_type(element, &type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(type == XMLELEMTYPE_ELEMENT, "Unexpected type %ld.\n", type); + + hr = IXMLElement_get_tagName(element, &s); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(s, L"A"), "Unexpected name %s.\n", wine_dbgstr_w(s)); + SysFreeString(s); + + s = SysAllocString(L"d"); + hr = IXMLElement_put_tagName(element, s); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(s); + + hr = IXMLElement_get_tagName(element2, &s); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!wcscmp(s, L"D"), "Unexpected name %s.\n", wine_dbgstr_w(s)); + SysFreeString(s); + + s = SysAllocString(L"text"); + hr = IXMLElement_put_text(element, s); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); + SysFreeString(s); + + hr = IXMLElement_get_children(element, &c); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLElement_get_children(element, &c2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(c != c2, "Unexpected instance.\n"); + + hr = IXMLElementCollection_get_length(c, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 2, "Unexpected count %ld.\n", count); + + V_VT(&v) = VT_I4; + V_I4(&v) = 0; + hr = IXMLElementCollection_item(c, v, v, &disp); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDispatch_QueryInterface(disp, &IID_IXMLElement, (void **)&child); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLElement_removeChild(element, child); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IXMLElement_Release(child); + IDispatch_Release(disp); + + hr = IXMLElementCollection_get_length(c, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %ld.\n", count); + + hr = IXMLElementCollection_get_length(c2, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %ld.\n", count); + + IXMLElementCollection_Release(c2); + IXMLElementCollection_Release(c); + + IXMLElement_Release(element2); + IXMLElement_Release(element); + + IXMLDocument_Release(doc); +} + START_TEST(xmldoc) { HRESULT hr; @@ -1313,6 +1413,7 @@ START_TEST(xmldoc) test_xmldoc_charset(); test_xmldoc_version(); test_xmldoc_doctype(); + test_xmldoc_root(); test_createElement(); test_persiststreaminit(); test_xmlelem();
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/msxml3/tests/xmldoc.c | 73 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+)
diff --git a/dlls/msxml3/tests/xmldoc.c b/dlls/msxml3/tests/xmldoc.c index cc1fa49beff..ab8433f95f4 100644 --- a/dlls/msxml3/tests/xmldoc.c +++ b/dlls/msxml3/tests/xmldoc.c @@ -1396,6 +1396,78 @@ static void test_xmldoc_root(void) IXMLDocument_Release(doc); }
+static const char doc_data9[] = + "<?xml version=\"1.0\"?><a attr1="value0" attr2="value1" />"; + +static void test_xmlelem_attributes(void) +{ + IXMLElementCollection *c; + IXMLAttribute *attr; + IXMLElement2 *root; + IXMLDocument2 *doc; + IDispatch *disp; + VARIANT v, v2; + HRESULT hr; + BSTR s; + + hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDocument2, (void **)&doc); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = load_document((IXMLDocument *)doc, doc_data9, sizeof(doc_data9) - 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDocument2_get_root(doc, &root); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLElement2_get_attributes(root, &c); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + { + IXMLDocument2_Release(doc); + return; + } + + V_VT(&v) = VT_I4; + V_I4(&v) = 0; + V_VT(&v2) = VT_NULL; + hr = IXMLElementCollection_item(c, v, v2, &disp); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDispatch_QueryInterface(disp, &IID_IXMLAttribute, (void **)&attr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLAttribute_get_name(attr, &s); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(s, L"ATTR1"), "Unexpected name %s.\n", wine_dbgstr_w(s)); + SysFreeString(s); + IXMLAttribute_Release(attr); + IDispatch_Release(disp); + + s = SysAllocString(L"aTtr1"); + hr = IXMLElement2_removeAttribute(root, s); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(s); + + V_VT(&v) = VT_I4; + V_I4(&v) = 0; + V_VT(&v2) = VT_NULL; + hr = IXMLElementCollection_item(c, v, v2, &disp); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDispatch_QueryInterface(disp, &IID_IXMLAttribute, (void **)&attr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLAttribute_get_name(attr, &s); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(s, L"ATTR2"), "Unexpected name %s.\n", wine_dbgstr_w(s)); + SysFreeString(s); + IXMLAttribute_Release(attr); + IDispatch_Release(disp); + + IXMLElementCollection_Release(c); + + IXMLElement2_Release(root); + + IXMLDocument2_Release(doc); +} + START_TEST(xmldoc) { HRESULT hr; @@ -1419,6 +1491,7 @@ START_TEST(xmldoc) test_xmlelem(); test_xmlelem_collection(); test_xmlelem_children(); + test_xmlelem_attributes();
CoUninitialize(); }
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/msxml3/tests/xmldoc.c | 60 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+)
diff --git a/dlls/msxml3/tests/xmldoc.c b/dlls/msxml3/tests/xmldoc.c index ab8433f95f4..77e3bf1f0b8 100644 --- a/dlls/msxml3/tests/xmldoc.c +++ b/dlls/msxml3/tests/xmldoc.c @@ -1468,6 +1468,65 @@ static void test_xmlelem_attributes(void) IXMLDocument2_Release(doc); }
+static const char doc_data10[] = + "<?xml version=\"1.0\"?><a><!-- sometext --></a>"; + +static void test_comments(void) +{ + IXMLElement *root, *child; + IXMLElementCollection *c; + IXMLDocument *doc; + LONG type, count; + IDispatch *disp; + HRESULT hr; + VARIANT v; + BSTR s; + + hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDocument, (void **)&doc); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = load_document(doc, doc_data10, sizeof(doc_data10) - 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDocument_get_root(doc, &root); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLElement_get_children(root, &c); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLElementCollection_get_length(c, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %ld.\n", count); + + V_VT(&v) = VT_I4; + V_I4(&v) = 0; + hr = IXMLElementCollection_item(c, v, v, &disp); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDispatch_QueryInterface(disp, &IID_IXMLElement, (void **)&child); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLElement_get_type(child, &type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(type == XMLELEMTYPE_COMMENT, "Unexpected type %ld.\n", type); + + s = (void *)1; + hr = IXMLElement_get_tagName(child, &s); + todo_wine + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!s, "Unexpected pointer %p.\n", s); + + s = NULL; + hr = IXMLElement_get_text(child, &s); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(s, L" sometext "), "Unexpected text %s.\n", debugstr_w(s)); + SysFreeString(s); + + IXMLElement_Release(child); + IDispatch_Release(disp); + + IXMLDocument_Release(doc); +} + START_TEST(xmldoc) { HRESULT hr; @@ -1492,6 +1551,7 @@ START_TEST(xmldoc) test_xmlelem_collection(); test_xmlelem_children(); test_xmlelem_attributes(); + test_comments();
CoUninitialize(); }
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/msxml3/tests/xmldoc.c | 162 +++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+)
diff --git a/dlls/msxml3/tests/xmldoc.c b/dlls/msxml3/tests/xmldoc.c index 77e3bf1f0b8..0ef154f5566 100644 --- a/dlls/msxml3/tests/xmldoc.c +++ b/dlls/msxml3/tests/xmldoc.c @@ -1527,6 +1527,166 @@ static void test_comments(void) IXMLDocument_Release(doc); }
+static const char doc_data11[] = + "<?xml version=\"1.0\"?><a><?pi0 sometext ?></a>"; + +static void test_pi(void) +{ + IXMLElement *root, *child, *parent; + IXMLElementCollection *c; + IXMLDocument *doc; + LONG type, count; + IDispatch *disp; + HRESULT hr; + VARIANT v; + BSTR s; + + hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDocument, (void **)&doc); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = load_document(doc, doc_data11, sizeof(doc_data11) - 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDocument_get_root(doc, &root); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLElement_get_children(root, &c); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLElementCollection_get_length(c, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(count == 2, "Unexpected count %ld.\n", count); + + V_VT(&v) = VT_I4; + V_I4(&v) = 0; + hr = IXMLElementCollection_item(c, v, v, &disp); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDispatch_QueryInterface(disp, &IID_IXMLElement, (void **)&child); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLElement_get_type(child, &type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(type == XMLELEMTYPE_PI, "Unexpected type %ld.\n", type); + + s = NULL; + hr = IXMLElement_get_tagName(child, &s); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(s, L"PI0"), "Unexpected name %s.\n", debugstr_w(s)); + SysFreeString(s); + + s = NULL; + hr = IXMLElement_get_text(child, &s); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(s && !*s, "Unexpected text %s.\n", debugstr_w(s)); + SysFreeString(s); + + IXMLElement_Release(child); + IDispatch_Release(disp); + + V_VT(&v) = VT_I4; + V_I4(&v) = 1; + hr = IXMLElementCollection_item(c, v, v, &disp); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); +if (hr == S_OK) +{ + hr = IDispatch_QueryInterface(disp, &IID_IXMLElement, (void **)&child); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLElement_get_type(child, &type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(type == XMLELEMTYPE_TEXT, "Unexpected type %ld.\n", type); + + s = (void *)1; + hr = IXMLElement_get_tagName(child, &s); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); + ok(!s, "Unexpected name %s.\n", debugstr_w(s)); + + s = NULL; + hr = IXMLElement_get_text(child, &s); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(s, L"sometext "), "Unexpected text %s.\n", debugstr_w(s)); + SysFreeString(s); + + hr = IXMLElement_get_parent(child, &parent); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLElement_get_type(parent, &type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(type == XMLELEMTYPE_ELEMENT, "Unexpected type %ld.\n", type); + s = NULL; + hr = IXMLElement_get_tagName(parent, &s); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(s, L"A"), "Unexpected name %s.\n", debugstr_w(s)); + SysFreeString(s); + IXMLElement_Release(parent); + + IXMLElement_Release(child); + IDispatch_Release(disp); +} + + IXMLDocument_Release(doc); +} + +static const char doc_data12[] = + "<?xml version=\"1.0\"?><a><![CDATA[ cdata-text ]]></a>"; + +static void test_cdata(void) +{ + IXMLElement *root, *child; + IXMLElementCollection *c; + IXMLDocument *doc; + LONG type, count; + IDispatch *disp; + HRESULT hr; + VARIANT v; + BSTR s; + + hr = CoCreateInstance(&CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDocument, (void **)&doc); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = load_document(doc, doc_data12, sizeof(doc_data12) - 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLDocument_get_root(doc, &root); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLElement_get_children(root, &c); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IXMLElementCollection_get_length(c, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == 1, "Unexpected count %ld.\n", count); + + V_VT(&v) = VT_I4; + V_I4(&v) = 0; + hr = IXMLElementCollection_item(c, v, v, &disp); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDispatch_QueryInterface(disp, &IID_IXMLElement, (void **)&child); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IXMLElement_get_type(child, &type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(type == XMLELEMTYPE_TEXT, "Unexpected type %ld.\n", type); + +if (type == XMLELEMTYPE_TEXT) +{ + s = (void *)1; + hr = IXMLElement_get_tagName(child, &s); + ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); + ok(!s, "Unexpected pointer %p.\n", s); + + s = NULL; + hr = IXMLElement_get_text(child, &s); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!wcscmp(s, L" cdata-text "), "Unexpected text %s.\n", debugstr_w(s)); + SysFreeString(s); +} + IXMLElement_Release(child); + IDispatch_Release(disp); + + IXMLDocument_Release(doc); +} + START_TEST(xmldoc) { HRESULT hr; @@ -1552,6 +1712,8 @@ START_TEST(xmldoc) test_xmlelem_children(); test_xmlelem_attributes(); test_comments(); + test_pi(); + test_cdata();
CoUninitialize(); }
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/msxml3/xmldoc.c | 4 ++-- include/msxml.idl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/msxml3/xmldoc.c b/dlls/msxml3/xmldoc.c index 1b71607f23c..e1bde531ce2 100644 --- a/dlls/msxml3/xmldoc.c +++ b/dlls/msxml3/xmldoc.c @@ -1258,7 +1258,7 @@ static HRESULT WINAPI xmldoc_get_doctype(IXMLDocument2 *iface, BSTR *p) return S_OK; }
-static HRESULT WINAPI xmldoc_get_dtdURl(IXMLDocument2 *iface, BSTR *p) +static HRESULT WINAPI xmldoc_get_dtdURL(IXMLDocument2 *iface, BSTR *p) { FIXME("(%p, %p): stub\n", iface, p); return E_NOTIMPL; @@ -1349,7 +1349,7 @@ static const struct IXMLDocument2Vtbl xmldoc_vtbl = xmldoc_put_charset, xmldoc_get_version, xmldoc_get_doctype, - xmldoc_get_dtdURl, + xmldoc_get_dtdURL, xmldoc_createElement, xmldoc_get_async, xmldoc_put_async, diff --git a/include/msxml.idl b/include/msxml.idl index 375bb64cd7c..283a0f48bb6 100644 --- a/include/msxml.idl +++ b/include/msxml.idl @@ -164,7 +164,7 @@ interface IXMLDocument : IDispatch HRESULT doctype( [retval, out] BSTR *p );
[propget, id(DISPID_XMLDOCUMENT_DTDURL)] - HRESULT dtdURl( [retval, out] BSTR *p ); + HRESULT dtdURL( [retval, out] BSTR *p );
[id(DISPID_XMLDOCUMENT_CREATEELEMENT)] HRESULT createElement(
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/msxml3/tests/xmldoc.c | 104 ++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-)
diff --git a/dlls/msxml3/tests/xmldoc.c b/dlls/msxml3/tests/xmldoc.c index 0ef154f5566..06cfadbee8e 100644 --- a/dlls/msxml3/tests/xmldoc.c +++ b/dlls/msxml3/tests/xmldoc.c @@ -915,10 +915,10 @@ cleanup:
static void test_xmlelem(void) { + IXMLElement *child, *child2, *child3, *child4; HRESULT hr; IXMLDocument *doc = NULL; IXMLElement *element = NULL, *parent; - IXMLElement *child, *child2; IXMLElementCollection *children; VARIANT vType, vName; VARIANT vIndex, vValue; @@ -1108,7 +1108,109 @@ static void test_xmlelem(void) ok(!lstrcmpW(str, L"next"), "Expected 'val'\n"); SysFreeString(str);
+ V_VT(&vType) = VT_I4; + V_I4(&vType) = XMLELEMTYPE_ELEMENT; + V_VT(&vName) = VT_NULL; + hr = IXMLDocument_createElement(doc, vType, vName, &child3); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!child3, "Expected non-NULL child\n"); + str = SysAllocString(L"e2"); + hr = IXMLElement_put_tagName(child3, str); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(str); + hr = IXMLElement_addChild(element, child3, 0, -1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + V_VT(&vType) = VT_I4; + V_I4(&vType) = XMLELEMTYPE_TEXT; + V_VT(&vName) = VT_NULL; + hr = IXMLDocument_createElement(doc, vType, vName, &child4); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!child4, "Expected non-NULL child\n"); + + str = SysAllocString(L"text4"); + hr = IXMLElement_put_text(child4, str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(str); + hr = IXMLElement_addChild(child3, child4, 0, -1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IXMLElement_Release(child4); + + IXMLElement_Release(child3); + + hr = IXMLElement_get_text(element, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!lstrcmpW(str, L"text4next"), "Unexpected text %s.\n", debugstr_w(str)); + SysFreeString(str); + + hr = IXMLElementCollection_get_length(children, &num_child); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(num_child == 2, "Unexpected length %ld.\n", num_child); + + V_VT(&vType) = VT_I4; + V_I4(&vType) = XMLELEMTYPE_TEXT; + V_VT(&vName) = VT_NULL; + hr = IXMLDocument_createElement(doc, vType, vName, &child3); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!child3, "Expected non-NULL child\n"); + str = SysAllocString(L"text3"); + hr = IXMLElement_put_text(child3, str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(str); + hr = IXMLElement_addChild(element, child3, 0, -1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IXMLElement_Release(child3); + + hr = IXMLElementCollection_get_length(children, &num_child); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(num_child == 3, "Unexpected length %ld.\n", num_child); + + hr = IXMLElement_get_text(element, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!lstrcmpW(str, L"text3text4next"), "Unexpected text %s.\n", debugstr_w(str)); + SysFreeString(str); + + IXMLElement_Release(child2); + + /* Check order */ + V_VT(&vIndex) = VT_I4; + V_I4(&vIndex) = 0; + V_VT(&vName) = VT_ERROR; + V_ERROR(&vName) = DISP_E_PARAMNOTFOUND; + hr = IXMLElementCollection_item(children, vIndex, vName, (IDispatch **)&child2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!child2, "Expected non-NULL child\n"); + hr = IXMLElement_get_type(child2, &type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(type == XMLELEMTYPE_TEXT, "Unexpected type %ld.\n", type); + hr = IXMLElement_get_text(child2, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(!lstrcmpW(str, L"text3"), "Unexpected text %s.\n", debugstr_w(str)); + SysFreeString(str); + IXMLElement_Release(child2); + + V_VT(&vIndex) = VT_I4; + V_I4(&vIndex) = 1; + V_VT(&vName) = VT_ERROR; + V_ERROR(&vName) = DISP_E_PARAMNOTFOUND; + hr = IXMLElementCollection_item(children, vIndex, vName, (IDispatch **)&child2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!child2, "Expected non-NULL child\n"); + hr = IXMLElement_get_type(child2, &type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(type == XMLELEMTYPE_ELEMENT, "Unexpected type %ld.\n", type); + hr = IXMLElement_get_text(child2, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!lstrcmpW(str, L"text4"), "Unexpected text %s.\n", debugstr_w(str)); + SysFreeString(str); + IXMLElement_Release(child2); + IXMLElementCollection_Release(children); IXMLElement_Release(parent); IXMLElement_Release(child);