msxml3: Added node_query_inerface function for common xmlnode child objects implement...
[wine] / dlls / msxml3 / attribute.c
1 /*
2  *    DOM Attribute implementation
3  *
4  * Copyright 2006 Huw Davies
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 "ole2.h"
30 #include "msxml6.h"
31
32 #include "msxml_private.h"
33
34 #include "wine/debug.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
37
38 #ifdef HAVE_LIBXML2
39
40 typedef struct _domattr
41 {
42     xmlnode node;
43     const struct IXMLDOMAttributeVtbl *lpVtbl;
44     LONG ref;
45 } domattr;
46
47 static inline domattr *impl_from_IXMLDOMAttribute( IXMLDOMAttribute *iface )
48 {
49     return (domattr *)((char*)iface - FIELD_OFFSET(domattr, lpVtbl));
50 }
51
52 static HRESULT WINAPI domattr_QueryInterface(
53     IXMLDOMAttribute *iface,
54     REFIID riid,
55     void** ppvObject )
56 {
57     domattr *This = impl_from_IXMLDOMAttribute( iface );
58     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
59
60     if ( IsEqualGUID( riid, &IID_IXMLDOMAttribute ) ||
61          IsEqualGUID( riid, &IID_IDispatch ) ||
62          IsEqualGUID( riid, &IID_IUnknown ) )
63     {
64         *ppvObject = iface;
65     }
66     else if ( IsEqualGUID( riid, &IID_IXMLDOMNode ) )
67     {
68         *ppvObject = IXMLDOMNode_from_impl(&This->node);
69     }
70     else if(node_query_interface(&This->node, riid, ppvObject))
71     {
72         return *ppvObject ? S_OK : E_NOINTERFACE;
73     }
74     else
75     {
76         FIXME("Unsupported interface %s\n", debugstr_guid(riid));
77         return E_NOINTERFACE;
78     }
79
80     IXMLDOMText_AddRef((IUnknown*)*ppvObject);
81     return S_OK;
82 }
83
84 static ULONG WINAPI domattr_AddRef(
85     IXMLDOMAttribute *iface )
86 {
87     domattr *This = impl_from_IXMLDOMAttribute( iface );
88     return InterlockedIncrement( &This->ref );
89 }
90
91 static ULONG WINAPI domattr_Release(
92     IXMLDOMAttribute *iface )
93 {
94     domattr *This = impl_from_IXMLDOMAttribute( iface );
95     ULONG ref;
96
97     ref = InterlockedDecrement( &This->ref );
98     if ( ref == 0 )
99     {
100         destroy_xmlnode(&This->node);
101         heap_free( This );
102     }
103
104     return ref;
105 }
106
107 static HRESULT WINAPI domattr_GetTypeInfoCount(
108     IXMLDOMAttribute *iface,
109     UINT* pctinfo )
110 {
111     domattr *This = impl_from_IXMLDOMAttribute( iface );
112
113     TRACE("(%p)->(%p)\n", This, pctinfo);
114
115     *pctinfo = 1;
116
117     return S_OK;
118 }
119
120 static HRESULT WINAPI domattr_GetTypeInfo(
121     IXMLDOMAttribute *iface,
122     UINT iTInfo, LCID lcid,
123     ITypeInfo** ppTInfo )
124 {
125     domattr *This = impl_from_IXMLDOMAttribute( iface );
126     HRESULT hr;
127
128     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
129
130     hr = get_typeinfo(IXMLDOMAttribute_tid, ppTInfo);
131
132     return hr;
133 }
134
135 static HRESULT WINAPI domattr_GetIDsOfNames(
136     IXMLDOMAttribute *iface,
137     REFIID riid, LPOLESTR* rgszNames,
138     UINT cNames, LCID lcid, DISPID* rgDispId )
139 {
140     domattr *This = impl_from_IXMLDOMAttribute( iface );
141     ITypeInfo *typeinfo;
142     HRESULT hr;
143
144     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
145           lcid, rgDispId);
146
147     if(!rgszNames || cNames == 0 || !rgDispId)
148         return E_INVALIDARG;
149
150     hr = get_typeinfo(IXMLDOMAttribute_tid, &typeinfo);
151     if(SUCCEEDED(hr))
152     {
153         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
154         ITypeInfo_Release(typeinfo);
155     }
156
157     return hr;
158 }
159
160 static HRESULT WINAPI domattr_Invoke(
161     IXMLDOMAttribute *iface,
162     DISPID dispIdMember, REFIID riid, LCID lcid,
163     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
164     EXCEPINFO* pExcepInfo, UINT* puArgErr )
165 {
166     domattr *This = impl_from_IXMLDOMAttribute( iface );
167     ITypeInfo *typeinfo;
168     HRESULT hr;
169
170     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
171           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
172
173     hr = get_typeinfo(IXMLDOMAttribute_tid, &typeinfo);
174     if(SUCCEEDED(hr))
175     {
176         hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
177                 pVarResult, pExcepInfo, puArgErr);
178         ITypeInfo_Release(typeinfo);
179     }
180     return hr;
181 }
182
183 static HRESULT WINAPI domattr_get_nodeName(
184     IXMLDOMAttribute *iface,
185     BSTR* p )
186 {
187     domattr *This = impl_from_IXMLDOMAttribute( iface );
188     return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), p );
189 }
190
191 static HRESULT WINAPI domattr_get_nodeValue(
192     IXMLDOMAttribute *iface,
193     VARIANT* var1 )
194 {
195     domattr *This = impl_from_IXMLDOMAttribute( iface );
196     return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), var1 );
197 }
198
199 static HRESULT WINAPI domattr_put_nodeValue(
200     IXMLDOMAttribute *iface,
201     VARIANT var1 )
202 {
203     domattr *This = impl_from_IXMLDOMAttribute( iface );
204     return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), var1 );
205 }
206
207 static HRESULT WINAPI domattr_get_nodeType(
208     IXMLDOMAttribute *iface,
209     DOMNodeType* domNodeType )
210 {
211     domattr *This = impl_from_IXMLDOMAttribute( iface );
212     return IXMLDOMNode_get_nodeType( IXMLDOMNode_from_impl(&This->node), domNodeType );
213 }
214
215 static HRESULT WINAPI domattr_get_parentNode(
216     IXMLDOMAttribute *iface,
217     IXMLDOMNode** parent )
218 {
219     domattr *This = impl_from_IXMLDOMAttribute( iface );
220     TRACE("(%p)->(%p)\n", This, parent);
221     if (!parent) return E_INVALIDARG;
222     *parent = NULL;
223     return S_FALSE;
224 }
225
226 static HRESULT WINAPI domattr_get_childNodes(
227     IXMLDOMAttribute *iface,
228     IXMLDOMNodeList** outList)
229 {
230     domattr *This = impl_from_IXMLDOMAttribute( iface );
231     return IXMLDOMNode_get_childNodes( IXMLDOMNode_from_impl(&This->node), outList );
232 }
233
234 static HRESULT WINAPI domattr_get_firstChild(
235     IXMLDOMAttribute *iface,
236     IXMLDOMNode** domNode)
237 {
238     domattr *This = impl_from_IXMLDOMAttribute( iface );
239     return IXMLDOMNode_get_firstChild( IXMLDOMNode_from_impl(&This->node), domNode );
240 }
241
242 static HRESULT WINAPI domattr_get_lastChild(
243     IXMLDOMAttribute *iface,
244     IXMLDOMNode** domNode)
245 {
246     domattr *This = impl_from_IXMLDOMAttribute( iface );
247     return IXMLDOMNode_get_lastChild( IXMLDOMNode_from_impl(&This->node), domNode );
248 }
249
250 static HRESULT WINAPI domattr_get_previousSibling(
251     IXMLDOMAttribute *iface,
252     IXMLDOMNode** domNode)
253 {
254     domattr *This = impl_from_IXMLDOMAttribute( iface );
255     return IXMLDOMNode_get_previousSibling( IXMLDOMNode_from_impl(&This->node), domNode );
256 }
257
258 static HRESULT WINAPI domattr_get_nextSibling(
259     IXMLDOMAttribute *iface,
260     IXMLDOMNode** domNode)
261 {
262     domattr *This = impl_from_IXMLDOMAttribute( iface );
263     return IXMLDOMNode_get_nextSibling( IXMLDOMNode_from_impl(&This->node), domNode );
264 }
265
266 static HRESULT WINAPI domattr_get_attributes(
267     IXMLDOMAttribute *iface,
268     IXMLDOMNamedNodeMap** attributeMap)
269 {
270     domattr *This = impl_from_IXMLDOMAttribute( iface );
271     return IXMLDOMNode_get_attributes( IXMLDOMNode_from_impl(&This->node), attributeMap );
272 }
273
274 static HRESULT WINAPI domattr_insertBefore(
275     IXMLDOMAttribute *iface,
276     IXMLDOMNode* newNode, VARIANT var1,
277     IXMLDOMNode** outOldNode)
278 {
279     domattr *This = impl_from_IXMLDOMAttribute( iface );
280     return IXMLDOMNode_insertBefore( IXMLDOMNode_from_impl(&This->node), newNode, var1, outOldNode );
281 }
282
283 static HRESULT WINAPI domattr_replaceChild(
284     IXMLDOMAttribute *iface,
285     IXMLDOMNode* newNode,
286     IXMLDOMNode* oldNode,
287     IXMLDOMNode** outOldNode)
288 {
289     domattr *This = impl_from_IXMLDOMAttribute( iface );
290     return IXMLDOMNode_replaceChild( IXMLDOMNode_from_impl(&This->node), newNode, oldNode, outOldNode );
291 }
292
293 static HRESULT WINAPI domattr_removeChild(
294     IXMLDOMAttribute *iface,
295     IXMLDOMNode* domNode, IXMLDOMNode** oldNode)
296 {
297     domattr *This = impl_from_IXMLDOMAttribute( iface );
298     return IXMLDOMNode_removeChild( IXMLDOMNode_from_impl(&This->node), domNode, oldNode );
299 }
300
301 static HRESULT WINAPI domattr_appendChild(
302     IXMLDOMAttribute *iface,
303     IXMLDOMNode* newNode, IXMLDOMNode** outNewNode)
304 {
305     domattr *This = impl_from_IXMLDOMAttribute( iface );
306     return IXMLDOMNode_appendChild( IXMLDOMNode_from_impl(&This->node), newNode, outNewNode );
307 }
308
309 static HRESULT WINAPI domattr_hasChildNodes(
310     IXMLDOMAttribute *iface,
311     VARIANT_BOOL* pbool)
312 {
313     domattr *This = impl_from_IXMLDOMAttribute( iface );
314     return IXMLDOMNode_hasChildNodes( IXMLDOMNode_from_impl(&This->node), pbool );
315 }
316
317 static HRESULT WINAPI domattr_get_ownerDocument(
318     IXMLDOMAttribute *iface,
319     IXMLDOMDocument** domDocument)
320 {
321     domattr *This = impl_from_IXMLDOMAttribute( iface );
322     return IXMLDOMNode_get_ownerDocument( IXMLDOMNode_from_impl(&This->node), domDocument );
323 }
324
325 static HRESULT WINAPI domattr_cloneNode(
326     IXMLDOMAttribute *iface,
327     VARIANT_BOOL pbool, IXMLDOMNode** outNode)
328 {
329     domattr *This = impl_from_IXMLDOMAttribute( iface );
330     return IXMLDOMNode_cloneNode( IXMLDOMNode_from_impl(&This->node), pbool, outNode );
331 }
332
333 static HRESULT WINAPI domattr_get_nodeTypeString(
334     IXMLDOMAttribute *iface,
335     BSTR* p)
336 {
337     domattr *This = impl_from_IXMLDOMAttribute( iface );
338     return IXMLDOMNode_get_nodeTypeString( IXMLDOMNode_from_impl(&This->node), p );
339 }
340
341 static HRESULT WINAPI domattr_get_text(
342     IXMLDOMAttribute *iface,
343     BSTR* p)
344 {
345     domattr *This = impl_from_IXMLDOMAttribute( iface );
346     return IXMLDOMNode_get_text( IXMLDOMNode_from_impl(&This->node), p );
347 }
348
349 static HRESULT WINAPI domattr_put_text(
350     IXMLDOMAttribute *iface,
351     BSTR p)
352 {
353     domattr *This = impl_from_IXMLDOMAttribute( iface );
354     return IXMLDOMNode_put_text( IXMLDOMNode_from_impl(&This->node), p );
355 }
356
357 static HRESULT WINAPI domattr_get_specified(
358     IXMLDOMAttribute *iface,
359     VARIANT_BOOL* pbool)
360 {
361     domattr *This = impl_from_IXMLDOMAttribute( iface );
362     return IXMLDOMNode_get_specified( IXMLDOMNode_from_impl(&This->node), pbool );
363 }
364
365 static HRESULT WINAPI domattr_get_definition(
366     IXMLDOMAttribute *iface,
367     IXMLDOMNode** domNode)
368 {
369     domattr *This = impl_from_IXMLDOMAttribute( iface );
370     return IXMLDOMNode_get_definition( IXMLDOMNode_from_impl(&This->node), domNode );
371 }
372
373 static HRESULT WINAPI domattr_get_nodeTypedValue(
374     IXMLDOMAttribute *iface,
375     VARIANT* var1)
376 {
377     domattr *This = impl_from_IXMLDOMAttribute( iface );
378     return IXMLDOMNode_get_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), var1 );
379 }
380
381 static HRESULT WINAPI domattr_put_nodeTypedValue(
382     IXMLDOMAttribute *iface,
383     VARIANT var1)
384 {
385     domattr *This = impl_from_IXMLDOMAttribute( iface );
386     return IXMLDOMNode_put_nodeTypedValue( IXMLDOMNode_from_impl(&This->node), var1 );
387 }
388
389 static HRESULT WINAPI domattr_get_dataType(
390     IXMLDOMAttribute *iface,
391     VARIANT* var1)
392 {
393     domattr *This = impl_from_IXMLDOMAttribute( iface );
394     return IXMLDOMNode_get_dataType( IXMLDOMNode_from_impl(&This->node), var1 );
395 }
396
397 static HRESULT WINAPI domattr_put_dataType(
398     IXMLDOMAttribute *iface,
399     BSTR p)
400 {
401     domattr *This = impl_from_IXMLDOMAttribute( iface );
402     return IXMLDOMNode_put_dataType( IXMLDOMNode_from_impl(&This->node), p );
403 }
404
405 static HRESULT WINAPI domattr_get_xml(
406     IXMLDOMAttribute *iface,
407     BSTR* p)
408 {
409     domattr *This = impl_from_IXMLDOMAttribute( iface );
410     return IXMLDOMNode_get_xml( IXMLDOMNode_from_impl(&This->node), p );
411 }
412
413 static HRESULT WINAPI domattr_transformNode(
414     IXMLDOMAttribute *iface,
415     IXMLDOMNode* domNode, BSTR* p)
416 {
417     domattr *This = impl_from_IXMLDOMAttribute( iface );
418     return IXMLDOMNode_transformNode( IXMLDOMNode_from_impl(&This->node), domNode, p );
419 }
420
421 static HRESULT WINAPI domattr_selectNodes(
422     IXMLDOMAttribute *iface,
423     BSTR p, IXMLDOMNodeList** outList)
424 {
425     domattr *This = impl_from_IXMLDOMAttribute( iface );
426     return IXMLDOMNode_selectNodes( IXMLDOMNode_from_impl(&This->node), p, outList );
427 }
428
429 static HRESULT WINAPI domattr_selectSingleNode(
430     IXMLDOMAttribute *iface,
431     BSTR p, IXMLDOMNode** outNode)
432 {
433     domattr *This = impl_from_IXMLDOMAttribute( iface );
434     return IXMLDOMNode_selectSingleNode( IXMLDOMNode_from_impl(&This->node), p, outNode );
435 }
436
437 static HRESULT WINAPI domattr_get_parsed(
438     IXMLDOMAttribute *iface,
439     VARIANT_BOOL* pbool)
440 {
441     domattr *This = impl_from_IXMLDOMAttribute( iface );
442     return IXMLDOMNode_get_parsed( IXMLDOMNode_from_impl(&This->node), pbool );
443 }
444
445 static HRESULT WINAPI domattr_get_namespaceURI(
446     IXMLDOMAttribute *iface,
447     BSTR* p)
448 {
449     domattr *This = impl_from_IXMLDOMAttribute( iface );
450     return IXMLDOMNode_get_namespaceURI( IXMLDOMNode_from_impl(&This->node), p );
451 }
452
453 static HRESULT WINAPI domattr_get_prefix(
454     IXMLDOMAttribute *iface,
455     BSTR* p)
456 {
457     domattr *This = impl_from_IXMLDOMAttribute( iface );
458     return IXMLDOMNode_get_prefix( IXMLDOMNode_from_impl(&This->node), p );
459 }
460
461 static HRESULT WINAPI domattr_get_baseName(
462     IXMLDOMAttribute *iface,
463     BSTR* p)
464 {
465     domattr *This = impl_from_IXMLDOMAttribute( iface );
466     return IXMLDOMNode_get_baseName( IXMLDOMNode_from_impl(&This->node), p );
467 }
468
469 static HRESULT WINAPI domattr_transformNodeToObject(
470     IXMLDOMAttribute *iface,
471     IXMLDOMNode* domNode, VARIANT var1)
472 {
473     domattr *This = impl_from_IXMLDOMAttribute( iface );
474     return IXMLDOMNode_transformNodeToObject( IXMLDOMNode_from_impl(&This->node), domNode, var1 );
475 }
476
477 static HRESULT WINAPI domattr_get_name(
478     IXMLDOMAttribute *iface,
479     BSTR *p)
480 {
481     /* name property returns the same value as nodeName */
482     domattr *This = impl_from_IXMLDOMAttribute( iface );
483     return IXMLDOMNode_get_nodeName( IXMLDOMNode_from_impl(&This->node), p );
484 }
485
486 static HRESULT WINAPI domattr_get_value(
487     IXMLDOMAttribute *iface,
488     VARIANT *var1)
489 {
490     domattr *This = impl_from_IXMLDOMAttribute( iface );
491     return IXMLDOMNode_get_nodeValue( IXMLDOMNode_from_impl(&This->node), var1 );
492 }
493
494 static HRESULT WINAPI domattr_put_value(
495     IXMLDOMAttribute *iface,
496     VARIANT var1)
497 {
498     domattr *This = impl_from_IXMLDOMAttribute( iface );
499     return IXMLDOMNode_put_nodeValue( IXMLDOMNode_from_impl(&This->node), var1 );
500 }
501
502 static const struct IXMLDOMAttributeVtbl domattr_vtbl =
503 {
504     domattr_QueryInterface,
505     domattr_AddRef,
506     domattr_Release,
507     domattr_GetTypeInfoCount,
508     domattr_GetTypeInfo,
509     domattr_GetIDsOfNames,
510     domattr_Invoke,
511     domattr_get_nodeName,
512     domattr_get_nodeValue,
513     domattr_put_nodeValue,
514     domattr_get_nodeType,
515     domattr_get_parentNode,
516     domattr_get_childNodes,
517     domattr_get_firstChild,
518     domattr_get_lastChild,
519     domattr_get_previousSibling,
520     domattr_get_nextSibling,
521     domattr_get_attributes,
522     domattr_insertBefore,
523     domattr_replaceChild,
524     domattr_removeChild,
525     domattr_appendChild,
526     domattr_hasChildNodes,
527     domattr_get_ownerDocument,
528     domattr_cloneNode,
529     domattr_get_nodeTypeString,
530     domattr_get_text,
531     domattr_put_text,
532     domattr_get_specified,
533     domattr_get_definition,
534     domattr_get_nodeTypedValue,
535     domattr_put_nodeTypedValue,
536     domattr_get_dataType,
537     domattr_put_dataType,
538     domattr_get_xml,
539     domattr_transformNode,
540     domattr_selectNodes,
541     domattr_selectSingleNode,
542     domattr_get_parsed,
543     domattr_get_namespaceURI,
544     domattr_get_prefix,
545     domattr_get_baseName,
546     domattr_transformNodeToObject,
547     domattr_get_name,
548     domattr_get_value,
549     domattr_put_value
550 };
551
552 IUnknown* create_attribute( xmlNodePtr attribute )
553 {
554     domattr *This;
555
556     This = heap_alloc( sizeof *This );
557     if ( !This )
558         return NULL;
559
560     This->lpVtbl = &domattr_vtbl;
561     This->ref = 1;
562
563     init_xmlnode(&This->node, attribute, (IXMLDOMNode*)&This->lpVtbl, NULL);
564
565     return (IUnknown*) &This->lpVtbl;
566 }
567
568 #endif