ntdll: move relocations from mapping into loader
[wine/kumbayo.git] / dlls / msxml3 / xmlelem.c
blob5af43a77c913058bc3e27059375ff42550b5d8d6
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 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "ole2.h"
30 #include "msxml2.h"
31 #include "ocidl.h"
33 #include "wine/debug.h"
35 #include "msxml_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
39 #ifdef HAVE_LIBXML2
41 /**********************************************************************
42 * IXMLElement
44 typedef struct _xmlelem
46 const IXMLElementVtbl *lpVtbl;
47 LONG ref;
48 xmlNodePtr node;
49 } xmlelem;
51 static inline xmlelem *impl_from_IXMLElement(IXMLElement *iface)
53 return (xmlelem *)((char*)iface - FIELD_OFFSET(xmlelem, lpVtbl));
56 static HRESULT WINAPI xmlelem_QueryInterface(IXMLElement *iface, REFIID riid, void** ppvObject)
58 xmlelem *This = impl_from_IXMLElement(iface);
60 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
62 if (IsEqualGUID(riid, &IID_IUnknown) ||
63 IsEqualGUID(riid, &IID_IXMLElement))
65 *ppvObject = iface;
67 else
69 FIXME("interface %s not implemented\n", debugstr_guid(riid));
70 return E_NOINTERFACE;
73 IXMLElement_AddRef(iface);
75 return S_OK;
78 static ULONG WINAPI xmlelem_AddRef(IXMLElement *iface)
80 xmlelem *This = impl_from_IXMLElement(iface);
81 TRACE("%p\n", This);
82 return InterlockedIncrement(&This->ref);
85 static ULONG WINAPI xmlelem_Release(IXMLElement *iface)
87 xmlelem *This = impl_from_IXMLElement(iface);
88 LONG ref;
90 TRACE("%p\n", This);
92 ref = InterlockedDecrement(&This->ref);
93 if (ref == 0)
95 HeapFree(GetProcessHeap(), 0, This);
98 return ref;
101 static HRESULT WINAPI xmlelem_GetTypeInfoCount(IXMLElement *iface, UINT* pctinfo)
103 FIXME("\n");
104 return E_NOTIMPL;
107 static HRESULT WINAPI xmlelem_GetTypeInfo(IXMLElement *iface, UINT iTInfo,
108 LCID lcid, ITypeInfo** ppTInfo)
110 FIXME("\n");
111 return E_NOTIMPL;
114 static HRESULT WINAPI xmlelem_GetIDsOfNames(IXMLElement *iface, REFIID riid,
115 LPOLESTR* rgszNames, UINT cNames,
116 LCID lcid, DISPID* rgDispId)
118 FIXME("\n");
119 return E_NOTIMPL;
122 static HRESULT WINAPI xmlelem_Invoke(IXMLElement *iface, DISPID dispIdMember,
123 REFIID riid, LCID lcid, WORD wFlags,
124 DISPPARAMS* pDispParams, VARIANT* pVarResult,
125 EXCEPINFO* pExcepInfo, UINT* puArgErr)
127 FIXME("\n");
128 return E_NOTIMPL;
131 static inline BSTR str_dup_upper(BSTR str)
133 INT len = (lstrlenW(str) + 1) * sizeof(WCHAR);
134 BSTR p = SysAllocStringLen(NULL, len);
135 if (p)
137 memcpy(p, str, len);
138 CharUpperW(p);
140 return p;
143 static HRESULT WINAPI xmlelem_get_tagName(IXMLElement *iface, BSTR *p)
145 xmlelem *This = impl_from_IXMLElement(iface);
146 BSTR temp;
148 TRACE("(%p, %p)\n", iface, p);
150 if (!p)
151 return E_INVALIDARG;
153 temp = bstr_from_xmlChar(This->node->name);
154 *p = str_dup_upper(temp);
155 SysFreeString(temp);
157 TRACE("returning %s\n", debugstr_w(*p));
159 return S_OK;
162 static HRESULT WINAPI xmlelem_put_tagName(IXMLElement *iface, BSTR p)
164 FIXME("(%p, %p): stub\n", iface, p);
166 if (!p)
167 return E_INVALIDARG;
169 return E_NOTIMPL;
172 static HRESULT WINAPI xmlelem_get_parent(IXMLElement *iface, IXMLElement **parent)
174 xmlelem *This = impl_from_IXMLElement(iface);
176 TRACE("(%p, %p)\n", iface, parent);
178 if (!parent)
179 return E_INVALIDARG;
181 *parent = NULL;
183 if (!This->node->parent)
184 return S_FALSE;
186 return XMLElement_create((IUnknown *)iface, This->node->parent, (LPVOID *)parent);
189 static HRESULT WINAPI xmlelem_setAttribute(IXMLElement *iface, BSTR strPropertyName,
190 VARIANT PropertyValue)
192 xmlelem *This = impl_from_IXMLElement(iface);
193 xmlChar *name, *value;
194 xmlAttrPtr attr;
196 TRACE("(%p, %s)\n", iface, debugstr_w(strPropertyName));
198 if (!strPropertyName || V_VT(&PropertyValue) != VT_BSTR)
199 return E_INVALIDARG;
201 name = xmlChar_from_wchar(strPropertyName);
202 value = xmlChar_from_wchar(V_BSTR(&PropertyValue));
203 attr = xmlSetProp(This->node, name, value);
205 HeapFree(GetProcessHeap(), 0, name);
206 HeapFree(GetProcessHeap(), 0, value);
207 return (attr) ? S_OK : S_FALSE;
210 static HRESULT WINAPI xmlelem_getAttribute(IXMLElement *iface, BSTR strPropertyName,
211 VARIANT *PropertyValue)
213 xmlelem *This = impl_from_IXMLElement(iface);
214 xmlChar *val = NULL, *name;
215 xmlAttrPtr ptr;
217 TRACE("(%p, %s, %p)\n", iface, debugstr_w(strPropertyName), PropertyValue);
219 if (!PropertyValue)
220 return E_INVALIDARG;
222 VariantInit(PropertyValue);
223 V_BSTR(PropertyValue) = NULL;
225 if (!strPropertyName)
226 return E_INVALIDARG;
228 name = xmlChar_from_wchar(strPropertyName);
229 ptr = This->node->properties;
230 while (ptr)
232 if (!lstrcmpiA((LPSTR)name, (LPCSTR)ptr->name))
234 val = xmlNodeListGetString(ptr->doc, ptr->children, 1);
235 break;
238 ptr = ptr->next;
241 if (val)
243 V_VT(PropertyValue) = VT_BSTR;
244 V_BSTR(PropertyValue) = bstr_from_xmlChar(val);
247 HeapFree(GetProcessHeap(), 0, name);
248 xmlFree(val);
249 TRACE("returning %s\n", debugstr_w(V_BSTR(PropertyValue)));
250 return (val) ? S_OK : S_FALSE;
253 static HRESULT WINAPI xmlelem_removeAttribute(IXMLElement *iface, BSTR strPropertyName)
255 xmlelem *This = impl_from_IXMLElement(iface);
256 xmlChar *name;
257 xmlAttrPtr attr;
258 int res;
259 HRESULT hr = S_FALSE;
261 TRACE("(%p, %s)\n", iface, debugstr_w(strPropertyName));
263 if (!strPropertyName)
264 return E_INVALIDARG;
266 name = xmlChar_from_wchar(strPropertyName);
267 attr = xmlHasProp(This->node, name);
268 if (!attr)
269 goto done;
271 res = xmlRemoveProp(attr);
273 if (res == 0)
274 hr = S_OK;
276 done:
277 HeapFree(GetProcessHeap(), 0, name);
278 return hr;
281 static HRESULT WINAPI xmlelem_get_children(IXMLElement *iface, IXMLElementCollection **p)
283 xmlelem *This = impl_from_IXMLElement(iface);
285 TRACE("(%p, %p)\n", iface, p);
287 if (!p)
288 return E_INVALIDARG;
290 return XMLElementCollection_create((IUnknown *)iface, This->node->children, (LPVOID *)p);
293 static long type_libxml_to_msxml(xmlElementType type)
295 switch (type)
297 case XML_ELEMENT_NODE:
298 return XMLELEMTYPE_ELEMENT;
299 case XML_TEXT_NODE:
300 return XMLELEMTYPE_TEXT;
301 case XML_COMMENT_NODE:
302 return XMLELEMTYPE_COMMENT;
303 case XML_DOCUMENT_NODE:
304 return XMLELEMTYPE_DOCUMENT;
305 case XML_DTD_NODE:
306 return XMLELEMTYPE_DTD;
307 case XML_PI_NODE:
308 return XMLELEMTYPE_PI;
309 default:
310 break;
313 return XMLELEMTYPE_OTHER;
316 static HRESULT WINAPI xmlelem_get_type(IXMLElement *iface, long *p)
318 xmlelem *This = impl_from_IXMLElement(iface);
320 TRACE("(%p, %p)\n", This, p);
322 if (!p)
323 return E_INVALIDARG;
325 *p = type_libxml_to_msxml(This->node->type);
326 TRACE("returning %ld\n", *p);
327 return S_OK;
330 static HRESULT WINAPI xmlelem_get_text(IXMLElement *iface, BSTR *p)
332 xmlelem *This = impl_from_IXMLElement(iface);
333 xmlChar *content;
335 TRACE("(%p, %p)\n", iface, p);
337 if (!p)
338 return E_INVALIDARG;
340 content = xmlNodeGetContent(This->node);
341 *p = bstr_from_xmlChar(content);
342 TRACE("returning %s\n", debugstr_w(*p));
344 xmlFree(content);
345 return S_OK;
348 static HRESULT WINAPI xmlelem_put_text(IXMLElement *iface, BSTR p)
350 xmlelem *This = impl_from_IXMLElement(iface);
351 xmlChar *content;
353 TRACE("(%p, %s)\n", iface, debugstr_w(p));
355 /* FIXME: test which types can be used */
356 if (This->node->type == XML_ELEMENT_NODE)
357 return E_NOTIMPL;
359 content = xmlChar_from_wchar(p);
360 xmlNodeSetContent(This->node, content);
362 HeapFree( GetProcessHeap(), 0, content);
364 return S_OK;
367 static HRESULT WINAPI xmlelem_addChild(IXMLElement *iface, IXMLElement *pChildElem,
368 long lIndex, long lreserved)
370 xmlelem *This = impl_from_IXMLElement(iface);
371 xmlelem *childElem = impl_from_IXMLElement(pChildElem);
372 xmlNodePtr child;
374 TRACE("(%p, %p, %ld, %ld)\n", iface, pChildElem, lIndex, lreserved);
376 if (lIndex == 0)
377 child = xmlAddChild(This->node, childElem->node);
378 else
379 child = xmlAddNextSibling(This->node, childElem->node->last);
381 return (child) ? S_OK : S_FALSE;
384 static HRESULT WINAPI xmlelem_removeChild(IXMLElement *iface, IXMLElement *pChildElem)
386 FIXME("(%p, %p): stub\n", iface, pChildElem);
387 return E_NOTIMPL;
390 static const struct IXMLElementVtbl xmlelem_vtbl =
392 xmlelem_QueryInterface,
393 xmlelem_AddRef,
394 xmlelem_Release,
395 xmlelem_GetTypeInfoCount,
396 xmlelem_GetTypeInfo,
397 xmlelem_GetIDsOfNames,
398 xmlelem_Invoke,
399 xmlelem_get_tagName,
400 xmlelem_put_tagName,
401 xmlelem_get_parent,
402 xmlelem_setAttribute,
403 xmlelem_getAttribute,
404 xmlelem_removeAttribute,
405 xmlelem_get_children,
406 xmlelem_get_type,
407 xmlelem_get_text,
408 xmlelem_put_text,
409 xmlelem_addChild,
410 xmlelem_removeChild
413 HRESULT XMLElement_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj)
415 xmlelem *elem;
417 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
419 if (!ppObj)
420 return E_INVALIDARG;
422 *ppObj = NULL;
424 elem = HeapAlloc(GetProcessHeap(), 0, sizeof (*elem));
425 if(!elem)
426 return E_OUTOFMEMORY;
428 elem->lpVtbl = &xmlelem_vtbl;
429 elem->ref = 1;
430 elem->node = node;
432 *ppObj = &elem->lpVtbl;
434 TRACE("returning iface %p\n", *ppObj);
435 return S_OK;
438 /************************************************************************
439 * IXMLElementCollection
441 typedef struct _xmlelem_collection
443 const IXMLElementCollectionVtbl *lpVtbl;
444 const IEnumVARIANTVtbl *lpvtblIEnumVARIANT;
445 LONG ref;
446 LONG length;
447 xmlNodePtr node;
449 /* IEnumVARIANT members */
450 xmlNodePtr current;
451 } xmlelem_collection;
453 static inline xmlelem_collection *impl_from_IXMLElementCollection(IXMLElementCollection *iface)
455 return (xmlelem_collection *)((char*)iface - FIELD_OFFSET(xmlelem_collection, lpVtbl));
458 static inline xmlelem_collection *impl_from_IEnumVARIANT(IEnumVARIANT *iface)
460 return (xmlelem_collection *)((char*)iface - FIELD_OFFSET(xmlelem_collection, lpvtblIEnumVARIANT));
463 static HRESULT WINAPI xmlelem_collection_QueryInterface(IXMLElementCollection *iface, REFIID riid, void** ppvObject)
465 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
467 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
469 if (IsEqualGUID(riid, &IID_IUnknown) ||
470 IsEqualGUID(riid, &IID_IXMLElementCollection))
472 *ppvObject = iface;
474 else if (IsEqualGUID(riid, &IID_IEnumVARIANT))
476 *ppvObject = (IEnumVARIANT *)&(This->lpvtblIEnumVARIANT);
478 else
480 FIXME("interface %s not implemented\n", debugstr_guid(riid));
481 return E_NOINTERFACE;
484 IXMLElementCollection_AddRef(iface);
486 return S_OK;
489 static ULONG WINAPI xmlelem_collection_AddRef(IXMLElementCollection *iface)
491 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
492 TRACE("%p\n", This);
493 return InterlockedIncrement(&This->ref);
496 static ULONG WINAPI xmlelem_collection_Release(IXMLElementCollection *iface)
498 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
499 LONG ref;
501 TRACE("%p\n", This);
503 ref = InterlockedDecrement(&This->ref);
504 if (ref == 0)
506 HeapFree(GetProcessHeap(), 0, This);
509 return ref;
512 static HRESULT WINAPI xmlelem_collection_GetTypeInfoCount(IXMLElementCollection *iface, UINT* pctinfo)
514 FIXME("\n");
515 return E_NOTIMPL;
518 static HRESULT WINAPI xmlelem_collection_GetTypeInfo(IXMLElementCollection *iface, UINT iTInfo,
519 LCID lcid, ITypeInfo** ppTInfo)
521 FIXME("\n");
522 return E_NOTIMPL;
525 static HRESULT WINAPI xmlelem_collection_GetIDsOfNames(IXMLElementCollection *iface, REFIID riid,
526 LPOLESTR* rgszNames, UINT cNames,
527 LCID lcid, DISPID* rgDispId)
529 FIXME("\n");
530 return E_NOTIMPL;
533 static HRESULT WINAPI xmlelem_collection_Invoke(IXMLElementCollection *iface, DISPID dispIdMember,
534 REFIID riid, LCID lcid, WORD wFlags,
535 DISPPARAMS* pDispParams, VARIANT* pVarResult,
536 EXCEPINFO* pExcepInfo, UINT* puArgErr)
538 FIXME("\n");
539 return E_NOTIMPL;
542 static HRESULT WINAPI xmlelem_collection_put_length(IXMLElementCollection *iface, long v)
544 TRACE("(%p, %ld)\n", iface, v);
545 return E_FAIL;
548 static HRESULT WINAPI xmlelem_collection_get_length(IXMLElementCollection *iface, long *p)
550 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
552 TRACE("(%p, %p)\n", iface, p);
554 if (!p)
555 return E_INVALIDARG;
557 *p = This->length;
558 return S_OK;
561 static HRESULT WINAPI xmlelem_collection_get__newEnum(IXMLElementCollection *iface, IUnknown **ppUnk)
563 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
565 TRACE("(%p, %p)\n", iface, ppUnk);
567 if (!ppUnk)
568 return E_INVALIDARG;
570 *ppUnk = (IUnknown *)This;
571 IUnknown_AddRef(*ppUnk);
572 return S_OK;
575 static HRESULT WINAPI xmlelem_collection_item(IXMLElementCollection *iface, VARIANT var1,
576 VARIANT var2, IDispatch **ppDisp)
578 xmlelem_collection *This = impl_from_IXMLElementCollection(iface);
579 xmlNodePtr ptr = This->node;
580 int index, i;
582 TRACE("(%p, %p)\n", iface, ppDisp);
584 if (!ppDisp)
585 return E_INVALIDARG;
587 *ppDisp = NULL;
589 index = V_I4(&var1);
590 if (index < 0)
591 return E_INVALIDARG;
592 if (index >= This->length)
593 return E_FAIL;
595 for (i = 0; i < index; i++)
596 ptr = ptr->next;
598 return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)ppDisp);
601 static const struct IXMLElementCollectionVtbl xmlelem_collection_vtbl =
603 xmlelem_collection_QueryInterface,
604 xmlelem_collection_AddRef,
605 xmlelem_collection_Release,
606 xmlelem_collection_GetTypeInfoCount,
607 xmlelem_collection_GetTypeInfo,
608 xmlelem_collection_GetIDsOfNames,
609 xmlelem_collection_Invoke,
610 xmlelem_collection_put_length,
611 xmlelem_collection_get_length,
612 xmlelem_collection_get__newEnum,
613 xmlelem_collection_item
616 /************************************************************************
617 * xmlelem_collection implementation of IEnumVARIANT.
619 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_QueryInterface(
620 IEnumVARIANT *iface, REFIID riid, LPVOID *ppvObj)
622 xmlelem_collection *this = impl_from_IEnumVARIANT(iface);
623 return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);
626 static ULONG WINAPI xmlelem_collection_IEnumVARIANT_AddRef(
627 IEnumVARIANT *iface)
629 xmlelem_collection *this = impl_from_IEnumVARIANT(iface);
630 return IXMLDocument_AddRef((IXMLDocument *)this);
633 static ULONG WINAPI xmlelem_collection_IEnumVARIANT_Release(
634 IEnumVARIANT *iface)
636 xmlelem_collection *this = impl_from_IEnumVARIANT(iface);
637 return IXMLDocument_Release((IXMLDocument *)this);
640 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Next(
641 IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
643 xmlelem_collection *This = impl_from_IEnumVARIANT(iface);
644 xmlNodePtr ptr = This->current;
646 TRACE("(%p, %d, %p, %p)\n", iface, celt, rgVar, pCeltFetched);
648 if (!rgVar)
649 return E_INVALIDARG;
651 /* FIXME: handle celt */
652 if (pCeltFetched)
653 *pCeltFetched = 1;
655 This->current = This->current->next;
657 V_VT(rgVar) = VT_DISPATCH;
658 return XMLElement_create((IUnknown *)iface, ptr, (LPVOID *)&V_DISPATCH(rgVar));
661 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Skip(
662 IEnumVARIANT *iface, ULONG celt)
664 FIXME("(%p, %d): stub\n", iface, celt);
665 return E_NOTIMPL;
668 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Reset(
669 IEnumVARIANT *iface)
671 xmlelem_collection *This = impl_from_IEnumVARIANT(iface);
672 This->current = This->node;
673 return S_OK;
676 static HRESULT WINAPI xmlelem_collection_IEnumVARIANT_Clone(
677 IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
679 FIXME("(%p, %p): stub\n", iface, ppEnum);
680 return E_NOTIMPL;
683 static const struct IEnumVARIANTVtbl xmlelem_collection_IEnumVARIANTvtbl =
685 xmlelem_collection_IEnumVARIANT_QueryInterface,
686 xmlelem_collection_IEnumVARIANT_AddRef,
687 xmlelem_collection_IEnumVARIANT_Release,
688 xmlelem_collection_IEnumVARIANT_Next,
689 xmlelem_collection_IEnumVARIANT_Skip,
690 xmlelem_collection_IEnumVARIANT_Reset,
691 xmlelem_collection_IEnumVARIANT_Clone
694 HRESULT XMLElementCollection_create(IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj)
696 xmlelem_collection *collection;
697 xmlNodePtr ptr;
699 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
701 *ppObj = NULL;
703 if (!node)
704 return S_FALSE;
706 collection = HeapAlloc(GetProcessHeap(), 0, sizeof (*collection));
707 if(!collection)
708 return E_OUTOFMEMORY;
710 collection->lpVtbl = &xmlelem_collection_vtbl;
711 collection->lpvtblIEnumVARIANT = &xmlelem_collection_IEnumVARIANTvtbl;
712 collection->ref = 1;
713 collection->length = 0;
714 collection->node = node;
715 collection->current = node;
717 ptr = node;
718 while (ptr)
720 collection->length++;
721 ptr = ptr->next;
724 *ppObj = &collection->lpVtbl;
726 TRACE("returning iface %p\n", *ppObj);
727 return S_OK;
730 #endif