wineps: Fix a couple of typos in the path painting function.
[wine/testsucceed.git] / dlls / msxml3 / xmlelem.c
blob86fa51d8cf268872561ea0f776a5c51ff46e9421
1 /*
2 * XML Element implementation
4 * Copyright 2007 James Hawkins
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include "config.h"
25 #include <stdarg.h>
26 #ifdef HAVE_LIBXML2
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
29 #endif
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winuser.h"
34 #include "ole2.h"
35 #include "msxml6.h"
36 #include "ocidl.h"
38 #include "wine/debug.h"
40 #include "msxml_private.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
44 #ifdef HAVE_LIBXML2
46 static HRESULT XMLElementCollection_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj );
48 /**********************************************************************
49 * IXMLElement
51 typedef struct _xmlelem
53 IXMLElement IXMLElement_iface;
54 LONG ref;
55 xmlNodePtr node;
56 BOOL own;
57 } xmlelem;
59 static inline xmlelem *impl_from_IXMLElement(IXMLElement *iface)
61 return CONTAINING_RECORD(iface, xmlelem, IXMLElement_iface);
64 static HRESULT WINAPI xmlelem_QueryInterface(IXMLElement *iface, REFIID riid, void** ppvObject)
66 xmlelem *This = impl_from_IXMLElement(iface);
68 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
70 if (IsEqualGUID(riid, &IID_IUnknown) ||
71 IsEqualGUID(riid, &IID_IXMLElement))
73 *ppvObject = iface;
75 else
77 FIXME("interface %s not implemented\n", debugstr_guid(riid));
78 *ppvObject = NULL;
79 return E_NOINTERFACE;
82 IXMLElement_AddRef(iface);
84 return S_OK;
87 static ULONG WINAPI xmlelem_AddRef(IXMLElement *iface)
89 xmlelem *This = impl_from_IXMLElement(iface);
90 TRACE("%p\n", This);
91 return InterlockedIncrement(&This->ref);
94 static ULONG WINAPI xmlelem_Release(IXMLElement *iface)
96 xmlelem *This = impl_from_IXMLElement(iface);
97 LONG ref;
99 TRACE("%p\n", This);
101 ref = InterlockedDecrement(&This->ref);
102 if (ref == 0)
104 if (This->own) xmlFreeNode(This->node);
105 heap_free(This);
108 return ref;
111 static HRESULT WINAPI xmlelem_GetTypeInfoCount(IXMLElement *iface, UINT* pctinfo)
113 xmlelem *This = impl_from_IXMLElement(iface);
115 TRACE("(%p)->(%p)\n", This, pctinfo);
117 *pctinfo = 1;
119 return S_OK;
122 static HRESULT WINAPI xmlelem_GetTypeInfo(IXMLElement *iface, UINT iTInfo,
123 LCID lcid, ITypeInfo** ppTInfo)
125 xmlelem *This = impl_from_IXMLElement(iface);
126 HRESULT hr;
128 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
130 hr = get_typeinfo(IXMLElement_tid, ppTInfo);
132 return hr;
135 static HRESULT WINAPI xmlelem_GetIDsOfNames(IXMLElement *iface, REFIID riid,
136 LPOLESTR* rgszNames, UINT cNames,
137 LCID lcid, DISPID* rgDispId)
139 xmlelem *This = impl_from_IXMLElement(iface);
140 ITypeInfo *typeinfo;
141 HRESULT hr;
143 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
144 lcid, rgDispId);
146 if(!rgszNames || cNames == 0 || !rgDispId)
147 return E_INVALIDARG;
149 hr = get_typeinfo(IXMLElement_tid, &typeinfo);
150 if(SUCCEEDED(hr))
152 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
153 ITypeInfo_Release(typeinfo);
156 return hr;
159 static HRESULT WINAPI xmlelem_Invoke(IXMLElement *iface, DISPID dispIdMember,
160 REFIID riid, LCID lcid, WORD wFlags,
161 DISPPARAMS* pDispParams, VARIANT* pVarResult,
162 EXCEPINFO* pExcepInfo, UINT* puArgErr)
164 xmlelem *This = impl_from_IXMLElement(iface);
165 ITypeInfo *typeinfo;
166 HRESULT hr;
168 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
169 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
171 hr = get_typeinfo(IXMLElement_tid, &typeinfo);
172 if(SUCCEEDED(hr))
174 hr = ITypeInfo_Invoke(typeinfo, &This->IXMLElement_iface, dispIdMember, wFlags, pDispParams,
175 pVarResult, pExcepInfo, puArgErr);
176 ITypeInfo_Release(typeinfo);
179 return hr;
182 static HRESULT WINAPI xmlelem_get_tagName(IXMLElement *iface, BSTR *p)
184 xmlelem *This = impl_from_IXMLElement(iface);
186 TRACE("(%p)->(%p)\n", This, p);
188 if (!p)
189 return E_INVALIDARG;
191 *p = bstr_from_xmlChar(This->node->name);
192 CharUpperBuffW(*p, SysStringLen(*p));
194 TRACE("returning %s\n", debugstr_w(*p));
196 return S_OK;
199 static HRESULT WINAPI xmlelem_put_tagName(IXMLElement *iface, BSTR p)
201 xmlelem *This = impl_from_IXMLElement(iface);
203 FIXME("(%p)->(%s): stub\n", This, debugstr_w(p));
205 if (!p)
206 return E_INVALIDARG;
208 return E_NOTIMPL;
211 static HRESULT WINAPI xmlelem_get_parent(IXMLElement *iface, IXMLElement **parent)
213 xmlelem *This = impl_from_IXMLElement(iface);
215 TRACE("(%p)->(%p)\n", This, parent);
217 if (!parent)
218 return E_INVALIDARG;
220 *parent = NULL;
222 if (!This->node->parent)
223 return S_FALSE;
225 return XMLElement_create((IUnknown *)iface, This->node->parent, (LPVOID *)parent, FALSE);
228 static HRESULT WINAPI xmlelem_setAttribute(IXMLElement *iface, BSTR strPropertyName,
229 VARIANT PropertyValue)
231 xmlelem *This = impl_from_IXMLElement(iface);
232 xmlChar *name, *value;
233 xmlAttrPtr attr;
235 TRACE("(%p)->(%s %s)\n", This, debugstr_w(strPropertyName), debugstr_variant(&PropertyValue));
237 if (!strPropertyName || V_VT(&PropertyValue) != VT_BSTR)
238 return E_INVALIDARG;
240 name = xmlchar_from_wchar(strPropertyName);
241 value = xmlchar_from_wchar(V_BSTR(&PropertyValue));
242 attr = xmlSetProp(This->node, name, value);
244 heap_free(name);
245 heap_free(value);
246 return (attr) ? S_OK : S_FALSE;
249 static HRESULT WINAPI xmlelem_getAttribute(IXMLElement *iface, BSTR name,
250 VARIANT *value)
252 static const WCHAR xmllangW[] = { 'x','m','l',':','l','a','n','g',0 };
253 xmlelem *This = impl_from_IXMLElement(iface);
254 xmlChar *val = NULL;
256 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(name), value);
258 if (!value)
259 return E_INVALIDARG;
261 VariantInit(value);
262 V_BSTR(value) = NULL;
264 if (!name)
265 return E_INVALIDARG;
267 /* case for xml:lang attribute */
268 if (!lstrcmpiW(name, xmllangW))
270 xmlNsPtr ns;
271 ns = xmlSearchNs(This->node->doc, This->node, (xmlChar*)"xml");
272 val = xmlGetNsProp(This->node, (xmlChar*)"lang", ns->href);
274 else
276 xmlAttrPtr attr;
277 xmlChar *xml_name;
279 xml_name = xmlchar_from_wchar(name);
280 attr = This->node->properties;
281 while (attr)
283 BSTR attr_name;
285 attr_name = bstr_from_xmlChar(attr->name);
286 if (!lstrcmpiW(name, attr_name))
288 val = xmlNodeListGetString(attr->doc, attr->children, 1);
289 SysFreeString(attr_name);
290 break;
293 attr = attr->next;
294 SysFreeString(attr_name);
297 heap_free(xml_name);
300 if (val)
302 V_VT(value) = VT_BSTR;
303 V_BSTR(value) = bstr_from_xmlChar(val);
306 xmlFree(val);
307 TRACE("returning %s\n", debugstr_w(V_BSTR(value)));
308 return (val) ? S_OK : S_FALSE;
311 static HRESULT WINAPI xmlelem_removeAttribute(IXMLElement *iface, BSTR strPropertyName)
313 xmlelem *This = impl_from_IXMLElement(iface);
314 xmlChar *name;
315 xmlAttrPtr attr;
316 int res;
317 HRESULT hr = S_FALSE;
319 TRACE("(%p)->(%s)\n", This, debugstr_w(strPropertyName));
321 if (!strPropertyName)
322 return E_INVALIDARG;
324 name = xmlchar_from_wchar(strPropertyName);
325 attr = xmlHasProp(This->node, name);
326 if (!attr)
327 goto done;
329 res = xmlRemoveProp(attr);
331 if (res == 0)
332 hr = S_OK;
334 done:
335 heap_free(name);
336 return hr;
339 static HRESULT WINAPI xmlelem_get_children(IXMLElement *iface, IXMLElementCollection **p)
341 xmlelem *This = impl_from_IXMLElement(iface);
343 TRACE("(%p)->(%p)\n", This, p);
345 if (!p)
346 return E_INVALIDARG;
348 return XMLElementCollection_create((IUnknown *)iface, This->node, (LPVOID *)p);
351 static LONG type_libxml_to_msxml(xmlElementType type)
353 switch (type)
355 case XML_ELEMENT_NODE:
356 return XMLELEMTYPE_ELEMENT;
357 case XML_TEXT_NODE:
358 return XMLELEMTYPE_TEXT;
359 case XML_COMMENT_NODE:
360 return XMLELEMTYPE_COMMENT;
361 case XML_DOCUMENT_NODE:
362 return XMLELEMTYPE_DOCUMENT;
363 case XML_DTD_NODE:
364 return XMLELEMTYPE_DTD;
365 case XML_PI_NODE:
366 return XMLELEMTYPE_PI;
367 default:
368 break;
371 return XMLELEMTYPE_OTHER;
374 static HRESULT WINAPI xmlelem_get_type(IXMLElement *iface, LONG *p)
376 xmlelem *This = impl_from_IXMLElement(iface);
378 TRACE("(%p)->(%p)\n", This, p);
380 if (!p)
381 return E_INVALIDARG;
383 *p = type_libxml_to_msxml(This->node->type);
384 TRACE("returning %d\n", *p);
385 return S_OK;
388 static HRESULT WINAPI xmlelem_get_text(IXMLElement *iface, BSTR *p)
390 xmlelem *This = impl_from_IXMLElement(iface);
391 xmlChar *content;
393 TRACE("(%p)->(%p)\n", This, p);
395 if (!p)
396 return E_INVALIDARG;
398 content = xmlNodeGetContent(This->node);
399 *p = bstr_from_xmlChar(content);
400 TRACE("returning %s\n", debugstr_w(*p));
402 xmlFree(content);
403 return S_OK;
406 static HRESULT WINAPI xmlelem_put_text(IXMLElement *iface, BSTR p)
408 xmlelem *This = impl_from_IXMLElement(iface);
409 xmlChar *content;
411 TRACE("(%p)->(%s)\n", This, debugstr_w(p));
413 /* FIXME: test which types can be used */
414 if (This->node->type == XML_ELEMENT_NODE)
415 return E_NOTIMPL;
417 content = xmlchar_from_wchar(p);
418 xmlNodeSetContent(This->node, content);
420 heap_free(content);
422 return S_OK;
425 static HRESULT WINAPI xmlelem_addChild(IXMLElement *iface, IXMLElement *pChildElem,
426 LONG lIndex, LONG lreserved)
428 xmlelem *This = impl_from_IXMLElement(iface);
429 xmlelem *childElem = impl_from_IXMLElement(pChildElem);
430 xmlNodePtr child;
432 TRACE("(%p)->(%p %d %d)\n", This, pChildElem, lIndex, lreserved);
434 if (lIndex == 0)
435 child = xmlAddChild(This->node, childElem->node);
436 else
437 child = xmlAddNextSibling(This->node, childElem->node->last);
439 /* parent is responsible for child data */
440 if (child) childElem->own = FALSE;
442 return (child) ? S_OK : S_FALSE;
445 static HRESULT WINAPI xmlelem_removeChild(IXMLElement *iface, IXMLElement *pChildElem)
447 xmlelem *This = impl_from_IXMLElement(iface);
448 xmlelem *childElem = impl_from_IXMLElement(pChildElem);
450 TRACE("(%p)->(%p)\n", This, childElem);
452 if (!pChildElem)
453 return E_INVALIDARG;
455 /* only supported for This is childElem parent case */
456 if (This->node != childElem->node->parent)
457 return E_INVALIDARG;
459 xmlUnlinkNode(childElem->node);
460 /* standalone element now */
461 childElem->own = TRUE;
463 return S_OK;
466 static const struct IXMLElementVtbl xmlelem_vtbl =
468 xmlelem_QueryInterface,
469 xmlelem_AddRef,
470 xmlelem_Release,
471 xmlelem_GetTypeInfoCount,
472 xmlelem_GetTypeInfo,
473 xmlelem_GetIDsOfNames,
474 xmlelem_Invoke,
475 xmlelem_get_tagName,
476 xmlelem_put_tagName,
477 xmlelem_get_parent,
478 xmlelem_setAttribute,
479 xmlelem_getAttribute,
480 xmlelem_removeAttribute,
481 xmlelem_get_children,
482 xmlelem_get_type,
483 xmlelem_get_text,
484 xmlelem_put_text,
485 xmlelem_addChild,
486 xmlelem_removeChild
489 HRESULT XMLElement_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj, BOOL own)
491 xmlelem *elem;
493 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
495 if (!ppObj)
496 return E_INVALIDARG;
498 *ppObj = NULL;
500 elem = heap_alloc(sizeof (*elem));
501 if(!elem)
502 return E_OUTOFMEMORY;
504 elem->IXMLElement_iface.lpVtbl = &xmlelem_vtbl;
505 elem->ref = 1;
506 elem->node = node;
507 elem->own = own;
509 *ppObj = &elem->IXMLElement_iface;
511 TRACE("returning iface %p\n", *ppObj);
512 return S_OK;
515 /************************************************************************
516 * IXMLElementCollection
518 typedef struct _xmlelem_collection
520 IXMLElementCollection IXMLElementCollection_iface;
521 IEnumVARIANT IEnumVARIANT_iface;
522 LONG ref;
523 LONG length;
524 xmlNodePtr node;
526 /* IEnumVARIANT members */
527 xmlNodePtr current;
528 } xmlelem_collection;
530 static inline LONG xmlelem_collection_updatelength(xmlelem_collection *collection)
532 xmlNodePtr ptr = collection->node->children;
534 collection->length = 0;
535 while (ptr)
537 collection->length++;
538 ptr = ptr->next;
540 return collection->length;
543 static inline xmlelem_collection *impl_from_IXMLElementCollection(IXMLElementCollection *iface)
545 return CONTAINING_RECORD(iface, xmlelem_collection, IXMLElementCollection_iface);
548 static inline xmlelem_collection *impl_from_IEnumVARIANT(IEnumVARIANT *iface)
550 return CONTAINING_RECORD(iface, xmlelem_collection, IEnumVARIANT_iface);
553 static HRESULT WINAPI xmlelem_collection_QueryInterface(IXMLElementCollection *iface, REFIID riid, void** ppvObject)
555 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
557 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
559 if (IsEqualGUID(riid, &IID_IUnknown) ||
560 IsEqualGUID(riid, &IID_IXMLElementCollection))
562 *ppvObject = iface;
564 else if (IsEqualGUID(riid, &IID_IEnumVARIANT))
566 *ppvObject = &This->IEnumVARIANT_iface;
568 else
570 FIXME("interface %s not implemented\n", debugstr_guid(riid));
571 return E_NOINTERFACE;
574 IXMLElementCollection_AddRef(iface);
576 return S_OK;
579 static ULONG WINAPI xmlelem_collection_AddRef(IXMLElementCollection *iface)
581 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
582 TRACE("(%p)\n", This);
583 return InterlockedIncrement(&This->ref);
586 static ULONG WINAPI xmlelem_collection_Release(IXMLElementCollection *iface)
588 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
589 LONG ref;
591 TRACE("(%p)\n", This);
593 ref = InterlockedDecrement(&This->ref);
594 if (ref == 0)
596 heap_free(This);
599 return ref;
602 static HRESULT WINAPI xmlelem_collection_GetTypeInfoCount(IXMLElementCollection *iface, UINT* pctinfo)
604 FIXME("\n");
605 return E_NOTIMPL;
608 static HRESULT WINAPI xmlelem_collection_GetTypeInfo(IXMLElementCollection *iface, UINT iTInfo,
609 LCID lcid, ITypeInfo** ppTInfo)
611 FIXME("\n");
612 return E_NOTIMPL;
615 static HRESULT WINAPI xmlelem_collection_GetIDsOfNames(IXMLElementCollection *iface, REFIID riid,
616 LPOLESTR* rgszNames, UINT cNames,
617 LCID lcid, DISPID* rgDispId)
619 FIXME("\n");
620 return E_NOTIMPL;
623 static HRESULT WINAPI xmlelem_collection_Invoke(IXMLElementCollection *iface, DISPID dispIdMember,
624 REFIID riid, LCID lcid, WORD wFlags,
625 DISPPARAMS* pDispParams, VARIANT* pVarResult,
626 EXCEPINFO* pExcepInfo, UINT* puArgErr)
628 FIXME("\n");
629 return E_NOTIMPL;
632 static HRESULT WINAPI xmlelem_collection_put_length(IXMLElementCollection *iface, LONG v)
634 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
635 TRACE("(%p)->(%d)\n", This, v);
636 return E_FAIL;
639 static HRESULT WINAPI xmlelem_collection_get_length(IXMLElementCollection *iface, LONG *p)
641 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
643 TRACE("(%p)->(%p)\n", This, p);
645 if (!p)
646 return E_INVALIDARG;
648 *p = xmlelem_collection_updatelength(This);
649 return S_OK;
652 static HRESULT WINAPI xmlelem_collection_get__newEnum(IXMLElementCollection *iface, IUnknown **ppUnk)
654 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
656 TRACE("(%p)->(%p)\n", This, ppUnk);
658 if (!ppUnk)
659 return E_INVALIDARG;
661 *ppUnk = (IUnknown *)This;
662 IUnknown_AddRef(*ppUnk);
663 return S_OK;
666 static HRESULT WINAPI xmlelem_collection_item(IXMLElementCollection *iface, VARIANT var1,
667 VARIANT var2, IDispatch **ppDisp)
669 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
670 xmlNodePtr ptr = This->node->children;
671 int index, i;
673 TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&var1), debugstr_variant(&var2), ppDisp);
675 if (!ppDisp)
676 return E_INVALIDARG;
678 *ppDisp = NULL;
680 index = V_I4(&var1);
681 if (index < 0)
682 return E_INVALIDARG;
684 xmlelem_collection_updatelength(This);
685 if (index >= This->length)
686 return E_FAIL;
688 for (i = 0; i < index; i++)
689 ptr = ptr->next;
691 return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)ppDisp, FALSE);
694 static const struct IXMLElementCollectionVtbl xmlelem_collection_vtbl =
696 xmlelem_collection_QueryInterface,
697 xmlelem_collection_AddRef,
698 xmlelem_collection_Release,
699 xmlelem_collection_GetTypeInfoCount,
700 xmlelem_collection_GetTypeInfo,
701 xmlelem_collection_GetIDsOfNames,
702 xmlelem_collection_Invoke,
703 xmlelem_collection_put_length,
704 xmlelem_collection_get_length,
705 xmlelem_collection_get__newEnum,
706 xmlelem_collection_item
709 /************************************************************************
710 * xmlelem_collection implementation of IEnumVARIANT.
712 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_QueryInterface(
713 IEnumVARIANT *iface, REFIID riid, LPVOID *ppvObj)
715 xmlelem_collection *this = impl_from_IEnumVARIANT(iface);
716 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
719 static ULONG WINAPI xmlelem_collection_IEnumVARIANT_AddRef(
720 IEnumVARIANT *iface)
722 xmlelem_collection *this = impl_from_IEnumVARIANT(iface);
723 return IXMLDocument_AddRef((IXMLDocument *)this);
726 static ULONG WINAPI xmlelem_collection_IEnumVARIANT_Release(
727 IEnumVARIANT *iface)
729 xmlelem_collection *this = impl_from_IEnumVARIANT(iface);
730 return IXMLDocument_Release((IXMLDocument *)this);
733 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Next(
734 IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *fetched)
736 xmlelem_collection *This = impl_from_IEnumVARIANT(iface);
737 xmlNodePtr ptr = This->current;
739 TRACE("(%p)->(%d %p %p)\n", This, celt, rgVar, fetched);
741 if (!rgVar)
742 return E_INVALIDARG;
744 /* FIXME: handle celt */
745 if (fetched)
746 *fetched = 1;
748 if (This->current)
749 This->current = This->current->next;
750 else
752 V_VT(rgVar) = VT_EMPTY;
753 if (fetched) *fetched = 0;
754 return S_FALSE;
757 V_VT(rgVar) = VT_DISPATCH;
758 return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)&V_DISPATCH(rgVar), FALSE);
761 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Skip(
762 IEnumVARIANT *iface, ULONG celt)
764 xmlelem_collection *This = impl_from_IEnumVARIANT(iface);
765 FIXME("(%p)->(%d): stub\n", This, celt);
766 return E_NOTIMPL;
769 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Reset(
770 IEnumVARIANT *iface)
772 xmlelem_collection *This = impl_from_IEnumVARIANT(iface);
773 TRACE("(%p)\n", This);
774 This->current = This->node->children;
775 return S_OK;
778 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Clone(
779 IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
781 xmlelem_collection *This = impl_from_IEnumVARIANT(iface);
782 FIXME("(%p)->(%p): stub\n", This, ppEnum);
783 return E_NOTIMPL;
786 static const struct IEnumVARIANTVtbl xmlelem_collection_IEnumVARIANTvtbl =
788 xmlelem_collection_IEnumVARIANT_QueryInterface,
789 xmlelem_collection_IEnumVARIANT_AddRef,
790 xmlelem_collection_IEnumVARIANT_Release,
791 xmlelem_collection_IEnumVARIANT_Next,
792 xmlelem_collection_IEnumVARIANT_Skip,
793 xmlelem_collection_IEnumVARIANT_Reset,
794 xmlelem_collection_IEnumVARIANT_Clone
797 static HRESULT XMLElementCollection_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj)
799 xmlelem_collection *collection;
801 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
803 *ppObj = NULL;
805 if (!node->children)
806 return S_FALSE;
808 collection = heap_alloc(sizeof (*collection));
809 if(!collection)
810 return E_OUTOFMEMORY;
812 collection->IXMLElementCollection_iface.lpVtbl = &xmlelem_collection_vtbl;
813 collection->IEnumVARIANT_iface.lpVtbl = &xmlelem_collection_IEnumVARIANTvtbl;
814 collection->ref = 1;
815 collection->length = 0;
816 collection->node = node;
817 collection->current = node->children;
818 xmlelem_collection_updatelength(collection);
820 *ppObj = &collection->IXMLElementCollection_iface;
822 TRACE("returning iface %p\n", *ppObj);
823 return S_OK;
826 #endif