wined3d: Register map cleanups.
[wine] / dlls / msxml3 / element.c
1 /*
2  *    DOM Document implementation
3  *
4  * Copyright 2005 Mike McCormack
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #define COBJMACROS
22
23 #include "config.h"
24
25 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winnls.h"
30 #include "ole2.h"
31 #include "msxml2.h"
32
33 #include "msxml_private.h"
34
35 #include "wine/debug.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
38
39 #ifdef HAVE_LIBXML2
40
41 typedef struct _domelem
42 {
43     const struct IXMLDOMElementVtbl *lpVtbl;
44     LONG ref;
45     IUnknown *node_unk;
46     IXMLDOMNode *node;
47 } domelem;
48
49 static inline domelem *impl_from_IXMLDOMElement( IXMLDOMElement *iface )
50 {
51     return (domelem *)((char*)iface - FIELD_OFFSET(domelem, lpVtbl));
52 }
53
54 static inline xmlNodePtr get_element( domelem *This )
55 {
56     return xmlNodePtr_from_domnode( This->node, XML_ELEMENT_NODE );
57 }
58
59 static HRESULT WINAPI domelem_QueryInterface(
60     IXMLDOMElement *iface,
61     REFIID riid,
62     void** ppvObject )
63 {
64     domelem *This = impl_from_IXMLDOMElement( iface );
65     TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
66
67     if ( IsEqualGUID( riid, &IID_IXMLDOMElement ) ||
68          IsEqualGUID( riid, &IID_IUnknown ) )
69     {
70         *ppvObject = iface;
71     }
72     else if ( IsEqualGUID( riid, &IID_IDispatch ) ||
73               IsEqualGUID( riid, &IID_IXMLDOMNode ) )
74     {
75         return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
76     }
77     else
78     {
79         FIXME("interface %s not implemented\n", debugstr_guid(riid));
80         return E_NOINTERFACE;
81     }
82
83     IXMLDOMElement_AddRef( iface );
84
85     return S_OK;
86 }
87
88 static ULONG WINAPI domelem_AddRef(
89     IXMLDOMElement *iface )
90 {
91     domelem *This = impl_from_IXMLDOMElement( iface );
92     return InterlockedIncrement( &This->ref );
93 }
94
95 static ULONG WINAPI domelem_Release(
96     IXMLDOMElement *iface )
97 {
98     domelem *This = impl_from_IXMLDOMElement( iface );
99     ULONG ref;
100
101     ref = InterlockedDecrement( &This->ref );
102     if ( ref == 0 )
103     {
104         IUnknown_Release( This->node_unk );
105         HeapFree( GetProcessHeap(), 0, This );
106     }
107
108     return ref;
109 }
110
111 static HRESULT WINAPI domelem_GetTypeInfoCount(
112     IXMLDOMElement *iface,
113     UINT* pctinfo )
114 {
115     FIXME("\n");
116     return E_NOTIMPL;
117 }
118
119 static HRESULT WINAPI domelem_GetTypeInfo(
120     IXMLDOMElement *iface,
121     UINT iTInfo, LCID lcid,
122     ITypeInfo** ppTInfo )
123 {
124     FIXME("\n");
125     return E_NOTIMPL;
126 }
127
128 static HRESULT WINAPI domelem_GetIDsOfNames(
129     IXMLDOMElement *iface,
130     REFIID riid, LPOLESTR* rgszNames,
131     UINT cNames, LCID lcid, DISPID* rgDispId )
132 {
133     FIXME("\n");
134     return E_NOTIMPL;
135 }
136
137 static HRESULT WINAPI domelem_Invoke(
138     IXMLDOMElement *iface,
139     DISPID dispIdMember, REFIID riid, LCID lcid,
140     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
141     EXCEPINFO* pExcepInfo, UINT* puArgErr )
142 {
143     FIXME("\n");
144     return E_NOTIMPL;
145 }
146
147 static HRESULT WINAPI domelem_get_nodeName(
148     IXMLDOMElement *iface,
149     BSTR* p )
150 {
151     domelem *This = impl_from_IXMLDOMElement( iface );
152     return IXMLDOMNode_get_nodeName( This->node, p );
153 }
154
155 static HRESULT WINAPI domelem_get_nodeValue(
156     IXMLDOMElement *iface,
157     VARIANT* var1 )
158 {
159     domelem *This = impl_from_IXMLDOMElement( iface );
160     return IXMLDOMNode_get_nodeValue( This->node, var1 );
161 }
162
163 static HRESULT WINAPI domelem_put_nodeValue(
164     IXMLDOMElement *iface,
165     VARIANT var1 )
166 {
167     domelem *This = impl_from_IXMLDOMElement( iface );
168     return IXMLDOMNode_put_nodeValue( This->node, var1 );
169 }
170
171 static HRESULT WINAPI domelem_get_nodeType(
172     IXMLDOMElement *iface,
173     DOMNodeType* domNodeType )
174 {
175     domelem *This = impl_from_IXMLDOMElement( iface );
176     return IXMLDOMNode_get_nodeType( This->node, domNodeType );
177 }
178
179 static HRESULT WINAPI domelem_get_parentNode(
180     IXMLDOMElement *iface,
181     IXMLDOMNode** parent )
182 {
183     domelem *This = impl_from_IXMLDOMElement( iface );
184     return IXMLDOMNode_get_parentNode( This->node, parent );
185 }
186
187 static HRESULT WINAPI domelem_get_childNodes(
188     IXMLDOMElement *iface,
189     IXMLDOMNodeList** outList)
190 {
191     domelem *This = impl_from_IXMLDOMElement( iface );
192     return IXMLDOMNode_get_childNodes( This->node, outList );
193 }
194
195 static HRESULT WINAPI domelem_get_firstChild(
196     IXMLDOMElement *iface,
197     IXMLDOMNode** domNode)
198 {
199     domelem *This = impl_from_IXMLDOMElement( iface );
200     return IXMLDOMNode_get_firstChild( This->node, domNode );
201 }
202
203 static HRESULT WINAPI domelem_get_lastChild(
204     IXMLDOMElement *iface,
205     IXMLDOMNode** domNode)
206 {
207     domelem *This = impl_from_IXMLDOMElement( iface );
208     return IXMLDOMNode_get_lastChild( This->node, domNode );
209 }
210
211 static HRESULT WINAPI domelem_get_previousSibling(
212     IXMLDOMElement *iface,
213     IXMLDOMNode** domNode)
214 {
215     domelem *This = impl_from_IXMLDOMElement( iface );
216     return IXMLDOMNode_get_previousSibling( This->node, domNode );
217 }
218
219 static HRESULT WINAPI domelem_get_nextSibling(
220     IXMLDOMElement *iface,
221     IXMLDOMNode** domNode)
222 {
223     domelem *This = impl_from_IXMLDOMElement( iface );
224     return IXMLDOMNode_get_nextSibling( This->node, domNode );
225 }
226
227 static HRESULT WINAPI domelem_get_attributes(
228     IXMLDOMElement *iface,
229     IXMLDOMNamedNodeMap** attributeMap)
230 {
231     domelem *This = impl_from_IXMLDOMElement( iface );
232     return IXMLDOMNode_get_attributes( This->node, attributeMap );
233 }
234
235 static HRESULT WINAPI domelem_insertBefore(
236     IXMLDOMElement *iface,
237     IXMLDOMNode* newNode, VARIANT var1,
238     IXMLDOMNode** outOldNode)
239 {
240     domelem *This = impl_from_IXMLDOMElement( iface );
241     return IXMLDOMNode_insertBefore( This->node, newNode, var1, outOldNode );
242 }
243
244 static HRESULT WINAPI domelem_replaceChild(
245     IXMLDOMElement *iface,
246     IXMLDOMNode* newNode,
247     IXMLDOMNode* oldNode,
248     IXMLDOMNode** outOldNode)
249 {
250     domelem *This = impl_from_IXMLDOMElement( iface );
251     return IXMLDOMNode_replaceChild( This->node, newNode, oldNode, outOldNode );
252 }
253
254 static HRESULT WINAPI domelem_removeChild(
255     IXMLDOMElement *iface,
256     IXMLDOMNode* domNode, IXMLDOMNode** oldNode)
257 {
258     domelem *This = impl_from_IXMLDOMElement( iface );
259     return IXMLDOMNode_removeChild( This->node, domNode, oldNode );
260 }
261
262 static HRESULT WINAPI domelem_appendChild(
263     IXMLDOMElement *iface,
264     IXMLDOMNode* newNode, IXMLDOMNode** outNewNode)
265 {
266     domelem *This = impl_from_IXMLDOMElement( iface );
267     return IXMLDOMNode_appendChild( This->node, newNode, outNewNode );
268 }
269
270 static HRESULT WINAPI domelem_hasChildNodes(
271     IXMLDOMElement *iface,
272     VARIANT_BOOL* pbool)
273 {
274     domelem *This = impl_from_IXMLDOMElement( iface );
275     return IXMLDOMNode_hasChildNodes( This->node, pbool );
276 }
277
278 static HRESULT WINAPI domelem_get_ownerDocument(
279     IXMLDOMElement *iface,
280     IXMLDOMDocument** domDocument)
281 {
282     domelem *This = impl_from_IXMLDOMElement( iface );
283     return IXMLDOMNode_get_ownerDocument( This->node, domDocument );
284 }
285
286 static HRESULT WINAPI domelem_cloneNode(
287     IXMLDOMElement *iface,
288     VARIANT_BOOL pbool, IXMLDOMNode** outNode)
289 {
290     domelem *This = impl_from_IXMLDOMElement( iface );
291     return IXMLDOMNode_cloneNode( This->node, pbool, outNode );
292 }
293
294 static HRESULT WINAPI domelem_get_nodeTypeString(
295     IXMLDOMElement *iface,
296     BSTR* p)
297 {
298     domelem *This = impl_from_IXMLDOMElement( iface );
299     return IXMLDOMNode_get_nodeTypeString( This->node, p );
300 }
301
302 static HRESULT WINAPI domelem_get_text(
303     IXMLDOMElement *iface,
304     BSTR* p)
305 {
306     domelem *This = impl_from_IXMLDOMElement( iface );
307     return IXMLDOMNode_get_text( This->node, p );
308 }
309
310 static HRESULT WINAPI domelem_put_text(
311     IXMLDOMElement *iface,
312     BSTR p)
313 {
314     domelem *This = impl_from_IXMLDOMElement( iface );
315     return IXMLDOMNode_put_text( This->node, p );
316 }
317
318 static HRESULT WINAPI domelem_get_specified(
319     IXMLDOMElement *iface,
320     VARIANT_BOOL* pbool)
321 {
322     domelem *This = impl_from_IXMLDOMElement( iface );
323     return IXMLDOMNode_get_specified( This->node, pbool );
324 }
325
326 static HRESULT WINAPI domelem_get_definition(
327     IXMLDOMElement *iface,
328     IXMLDOMNode** domNode)
329 {
330     domelem *This = impl_from_IXMLDOMElement( iface );
331     return IXMLDOMNode_get_definition( This->node, domNode );
332 }
333
334 static HRESULT WINAPI domelem_get_nodeTypedValue(
335     IXMLDOMElement *iface,
336     VARIANT* var1)
337 {
338     domelem *This = impl_from_IXMLDOMElement( iface );
339     return IXMLDOMNode_get_nodeTypedValue( This->node, var1 );
340 }
341
342 static HRESULT WINAPI domelem_put_nodeTypedValue(
343     IXMLDOMElement *iface,
344     VARIANT var1)
345 {
346     domelem *This = impl_from_IXMLDOMElement( iface );
347     return IXMLDOMNode_put_nodeTypedValue( This->node, var1 );
348 }
349
350 static HRESULT WINAPI domelem_get_dataType(
351     IXMLDOMElement *iface,
352     VARIANT* var1)
353 {
354     domelem *This = impl_from_IXMLDOMElement( iface );
355     return IXMLDOMNode_get_dataType( This->node, var1 );
356 }
357
358 static HRESULT WINAPI domelem_put_dataType(
359     IXMLDOMElement *iface,
360     BSTR p)
361 {
362     domelem *This = impl_from_IXMLDOMElement( iface );
363     return IXMLDOMNode_put_dataType( This->node, p );
364 }
365
366 static HRESULT WINAPI domelem_get_xml(
367     IXMLDOMElement *iface,
368     BSTR* p)
369 {
370     domelem *This = impl_from_IXMLDOMElement( iface );
371     return IXMLDOMNode_get_xml( This->node, p );
372 }
373
374 static HRESULT WINAPI domelem_transformNode(
375     IXMLDOMElement *iface,
376     IXMLDOMNode* domNode, BSTR* p)
377 {
378     domelem *This = impl_from_IXMLDOMElement( iface );
379     return IXMLDOMNode_transformNode( This->node, domNode, p );
380 }
381
382 static HRESULT WINAPI domelem_selectNodes(
383     IXMLDOMElement *iface,
384     BSTR p, IXMLDOMNodeList** outList)
385 {
386     domelem *This = impl_from_IXMLDOMElement( iface );
387     return IXMLDOMNode_selectNodes( This->node, p, outList );
388 }
389
390 static HRESULT WINAPI domelem_selectSingleNode(
391     IXMLDOMElement *iface,
392     BSTR p, IXMLDOMNode** outNode)
393 {
394     domelem *This = impl_from_IXMLDOMElement( iface );
395     return IXMLDOMNode_selectSingleNode( This->node, p, outNode );
396 }
397
398 static HRESULT WINAPI domelem_get_parsed(
399     IXMLDOMElement *iface,
400     VARIANT_BOOL* pbool)
401 {
402     domelem *This = impl_from_IXMLDOMElement( iface );
403     return IXMLDOMNode_get_parsed( This->node, pbool );
404 }
405
406 static HRESULT WINAPI domelem_get_namespaceURI(
407     IXMLDOMElement *iface,
408     BSTR* p)
409 {
410     domelem *This = impl_from_IXMLDOMElement( iface );
411     return IXMLDOMNode_get_namespaceURI( This->node, p );
412 }
413
414 static HRESULT WINAPI domelem_get_prefix(
415     IXMLDOMElement *iface,
416     BSTR* p)
417 {
418     domelem *This = impl_from_IXMLDOMElement( iface );
419     return IXMLDOMNode_get_prefix( This->node, p );
420 }
421
422 static HRESULT WINAPI domelem_get_baseName(
423     IXMLDOMElement *iface,
424     BSTR* p)
425 {
426     domelem *This = impl_from_IXMLDOMElement( iface );
427     return IXMLDOMNode_get_baseName( This->node, p );
428 }
429
430 static HRESULT WINAPI domelem_transformNodeToObject(
431     IXMLDOMElement *iface,
432     IXMLDOMNode* domNode, VARIANT var1)
433 {
434     domelem *This = impl_from_IXMLDOMElement( iface );
435     return IXMLDOMNode_transformNodeToObject( This->node, domNode, var1 );
436 }
437
438 static HRESULT WINAPI domelem_get_tagName(
439     IXMLDOMElement *iface,
440     BSTR* p)
441 {
442     domelem *This = impl_from_IXMLDOMElement( iface );
443     xmlNodePtr element;
444     DWORD len;
445     DWORD offset = 0;
446     LPWSTR str;
447
448     TRACE("%p\n", This );
449
450     if ( !This->node )
451         return E_FAIL;
452
453     element = get_element( This );
454     if ( !element )
455         return E_FAIL;
456
457     len = MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) element->name, -1, NULL, 0 );
458     if (element->ns)
459         len += MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) element->ns->prefix, -1, NULL, 0 );
460     str = (LPWSTR) HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
461     if ( !str )
462         return E_OUTOFMEMORY;
463     if (element->ns)
464     {
465         offset = MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) element->ns->prefix, -1, str, len );
466         str[offset - 1] = ':';
467     }
468     MultiByteToWideChar( CP_UTF8, 0, (LPCSTR) element->name, -1, str + offset, len - offset );
469     *p = SysAllocString( str );
470     HeapFree( GetProcessHeap(), 0, str );
471
472     return S_OK;
473 }
474
475 static HRESULT WINAPI domelem_getAttribute(
476     IXMLDOMElement *iface,
477     BSTR name, VARIANT* value)
478 {
479     domelem *This = impl_from_IXMLDOMElement( iface );
480     xmlNodePtr element;
481     xmlChar *xml_name, *xml_value;
482     HRESULT hr = E_FAIL;
483
484     TRACE("(%p)->(%s,%p)\n", This, debugstr_w(name), value);
485
486     element = get_element( This );
487     if ( !element )
488         return E_FAIL;
489
490     VariantInit(value);
491     xml_name = xmlChar_from_wchar( name );
492     xml_value = xmlGetNsProp(element, xml_name, NULL);
493     HeapFree(GetProcessHeap(), 0, xml_name);
494     if(xml_value)
495     {
496         V_VT(value) = VT_BSTR;
497         V_BSTR(value) = bstr_from_xmlChar( xml_value );
498         xmlFree(xml_value);
499         hr = S_OK;
500     }
501
502     return hr;
503 }
504
505 static HRESULT WINAPI domelem_setAttribute(
506     IXMLDOMElement *iface,
507     BSTR name, VARIANT value)
508 {
509     domelem *This = impl_from_IXMLDOMElement( iface );
510     xmlNodePtr element;
511     xmlChar *xml_name, *xml_value;
512     HRESULT hr;
513     VARIANT var;
514
515     TRACE("(%p)->(%s, var)\n", This, debugstr_w(name));
516
517     element = get_element( This );
518     if ( !element )
519         return E_FAIL;
520
521     VariantInit(&var);
522     hr = VariantChangeType(&var, &value, 0, VT_BSTR);
523     if(hr != S_OK)
524     {
525         FIXME("VariantChangeType failed\n");
526         return hr;
527     }
528
529     xml_name = xmlChar_from_wchar( name );
530     xml_value = xmlChar_from_wchar( V_BSTR(&var) );
531
532     if(!xmlSetNsProp(element, NULL,  xml_name, xml_value))
533         hr = E_FAIL;
534
535     HeapFree(GetProcessHeap(), 0, xml_value);
536     HeapFree(GetProcessHeap(), 0, xml_name);
537     VariantClear(&var);
538
539     return hr;
540 }
541
542 static HRESULT WINAPI domelem_removeAttribute(
543     IXMLDOMElement *iface,
544     BSTR p)
545 {
546     FIXME("\n");
547     return E_NOTIMPL;
548 }
549
550 static HRESULT WINAPI domelem_getAttributeNode(
551     IXMLDOMElement *iface,
552     BSTR p, IXMLDOMAttribute** attributeNode )
553 {
554     FIXME("\n");
555     return E_NOTIMPL;
556 }
557
558 static HRESULT WINAPI domelem_setAttributeNode(
559     IXMLDOMElement *iface,
560     IXMLDOMAttribute* domAttribute,
561     IXMLDOMAttribute** attributeNode)
562 {
563     FIXME("\n");
564     return E_NOTIMPL;
565 }
566
567 static HRESULT WINAPI domelem_removeAttributeNode(
568     IXMLDOMElement *iface,
569     IXMLDOMAttribute* domAttribute,
570     IXMLDOMAttribute** attributeNode)
571 {
572     FIXME("\n");
573     return E_NOTIMPL;
574 }
575
576 static HRESULT WINAPI domelem_getElementsByTagName(
577     IXMLDOMElement *iface,
578     BSTR p, IXMLDOMNodeList** resultList)
579 {
580     FIXME("\n");
581     return E_NOTIMPL;
582 }
583
584 static HRESULT WINAPI domelem_normalize(
585     IXMLDOMElement *iface )
586 {
587     FIXME("\n");
588     return E_NOTIMPL;
589 }
590
591 static const struct IXMLDOMElementVtbl domelem_vtbl =
592 {
593     domelem_QueryInterface,
594     domelem_AddRef,
595     domelem_Release,
596     domelem_GetTypeInfoCount,
597     domelem_GetTypeInfo,
598     domelem_GetIDsOfNames,
599     domelem_Invoke,
600     domelem_get_nodeName,
601     domelem_get_nodeValue,
602     domelem_put_nodeValue,
603     domelem_get_nodeType,
604     domelem_get_parentNode,
605     domelem_get_childNodes,
606     domelem_get_firstChild,
607     domelem_get_lastChild,
608     domelem_get_previousSibling,
609     domelem_get_nextSibling,
610     domelem_get_attributes,
611     domelem_insertBefore,
612     domelem_replaceChild,
613     domelem_removeChild,
614     domelem_appendChild,
615     domelem_hasChildNodes,
616     domelem_get_ownerDocument,
617     domelem_cloneNode,
618     domelem_get_nodeTypeString,
619     domelem_get_text,
620     domelem_put_text,
621     domelem_get_specified,
622     domelem_get_definition,
623     domelem_get_nodeTypedValue,
624     domelem_put_nodeTypedValue,
625     domelem_get_dataType,
626     domelem_put_dataType,
627     domelem_get_xml,
628     domelem_transformNode,
629     domelem_selectNodes,
630     domelem_selectSingleNode,
631     domelem_get_parsed,
632     domelem_get_namespaceURI,
633     domelem_get_prefix,
634     domelem_get_baseName,
635     domelem_transformNodeToObject,
636     domelem_get_tagName,
637     domelem_getAttribute,
638     domelem_setAttribute,
639     domelem_removeAttribute,
640     domelem_getAttributeNode,
641     domelem_setAttributeNode,
642     domelem_removeAttributeNode,
643     domelem_getElementsByTagName,
644     domelem_normalize,
645 };
646
647 IUnknown* create_element( xmlNodePtr element )
648 {
649     domelem *This;
650     HRESULT hr;
651
652     This = HeapAlloc( GetProcessHeap(), 0, sizeof *This );
653     if ( !This )
654         return NULL;
655
656     This->lpVtbl = &domelem_vtbl;
657     This->ref = 1;
658
659     This->node_unk = create_basic_node( element, (IUnknown*)&This->lpVtbl );
660     if(!This->node_unk)
661     {
662         HeapFree(GetProcessHeap(), 0, This);
663         return NULL;
664     }
665
666     hr = IUnknown_QueryInterface(This->node_unk, &IID_IXMLDOMNode, (LPVOID*)&This->node);
667     if(FAILED(hr))
668     {
669         IUnknown_Release(This->node_unk);
670         HeapFree( GetProcessHeap(), 0, This );
671         return NULL;
672     }
673     /* The ref on This->node is actually looped back into this object, so release it */
674     IXMLDOMNode_Release(This->node);
675
676     return (IUnknown*) &This->lpVtbl;
677 }
678
679 #endif