msxml3: Include the system libxml headers before the Windows headers.
[wine] / dlls / msxml3 / docfrag.c
1 /*
2  *    DOM Document Fragment implementation
3  *
4  * Copyright 2007 Alistair Leslie-Hughes
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 #ifdef HAVE_LIBXML2
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
29 #endif
30
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winuser.h"
34 #include "ole2.h"
35 #include "msxml6.h"
36
37 #include "msxml_private.h"
38
39 #include "wine/debug.h"
40
41 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
42
43 #ifdef HAVE_LIBXML2
44
45 typedef struct _domfrag
46 {
47     xmlnode node;
48     IXMLDOMDocumentFragment IXMLDOMDocumentFragment_iface;
49     LONG ref;
50 } domfrag;
51
52 static inline domfrag *impl_from_IXMLDOMDocumentFragment( IXMLDOMDocumentFragment *iface )
53 {
54     return CONTAINING_RECORD(iface, domfrag, IXMLDOMDocumentFragment_iface);
55 }
56
57 static HRESULT WINAPI domfrag_QueryInterface(
58     IXMLDOMDocumentFragment *iface,
59     REFIID riid,
60     void** ppvObject )
61 {
62     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
63     TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
64
65     if ( IsEqualGUID( riid, &IID_IXMLDOMDocumentFragment ) ||
66          IsEqualGUID( riid, &IID_IXMLDOMNode ) ||
67          IsEqualGUID( riid, &IID_IDispatch ) ||
68          IsEqualGUID( riid, &IID_IUnknown ) )
69     {
70         *ppvObject = iface;
71     }
72     else if(node_query_interface(&This->node, riid, ppvObject))
73     {
74         return *ppvObject ? S_OK : E_NOINTERFACE;
75     }
76     else
77     {
78         FIXME("Unsupported interface %s\n", debugstr_guid(riid));
79         return E_NOINTERFACE;
80     }
81
82     IXMLDOMText_AddRef((IUnknown*)*ppvObject);
83     return S_OK;
84 }
85
86 static ULONG WINAPI domfrag_AddRef(
87     IXMLDOMDocumentFragment *iface )
88 {
89     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
90     return InterlockedIncrement( &This->ref );
91 }
92
93 static ULONG WINAPI domfrag_Release(
94     IXMLDOMDocumentFragment *iface )
95 {
96     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
97     ULONG ref;
98
99     ref = InterlockedDecrement( &This->ref );
100     if ( ref == 0 )
101     {
102         destroy_xmlnode(&This->node);
103         heap_free( This );
104     }
105
106     return ref;
107 }
108
109 static HRESULT WINAPI domfrag_GetTypeInfoCount(
110     IXMLDOMDocumentFragment *iface,
111     UINT* pctinfo )
112 {
113     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
114
115     TRACE("(%p)->(%p)\n", This, pctinfo);
116
117     *pctinfo = 1;
118
119     return S_OK;
120 }
121
122 static HRESULT WINAPI domfrag_GetTypeInfo(
123     IXMLDOMDocumentFragment *iface,
124     UINT iTInfo, LCID lcid,
125     ITypeInfo** ppTInfo )
126 {
127     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
128     HRESULT hr;
129
130     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
131
132     hr = get_typeinfo(IXMLDOMDocumentFragment_tid, ppTInfo);
133
134     return hr;
135 }
136
137 static HRESULT WINAPI domfrag_GetIDsOfNames(
138     IXMLDOMDocumentFragment *iface,
139     REFIID riid, LPOLESTR* rgszNames,
140     UINT cNames, LCID lcid, DISPID* rgDispId )
141 {
142     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
143     ITypeInfo *typeinfo;
144     HRESULT hr;
145
146     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
147           lcid, rgDispId);
148
149     if(!rgszNames || cNames == 0 || !rgDispId)
150         return E_INVALIDARG;
151
152     hr = get_typeinfo(IXMLDOMDocumentFragment_tid, &typeinfo);
153     if(SUCCEEDED(hr))
154     {
155         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
156         ITypeInfo_Release(typeinfo);
157     }
158
159     return hr;
160 }
161
162 static HRESULT WINAPI domfrag_Invoke(
163     IXMLDOMDocumentFragment *iface,
164     DISPID dispIdMember, REFIID riid, LCID lcid,
165     WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
166     EXCEPINFO* pExcepInfo, UINT* puArgErr )
167 {
168     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
169     ITypeInfo *typeinfo;
170     HRESULT hr;
171
172     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
173           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
174
175     hr = get_typeinfo(IXMLDOMDocumentFragment_tid, &typeinfo);
176     if(SUCCEEDED(hr))
177     {
178         hr = ITypeInfo_Invoke(typeinfo, &This->IXMLDOMDocumentFragment_iface, dispIdMember,
179                 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
180         ITypeInfo_Release(typeinfo);
181     }
182
183     return hr;
184 }
185
186 static HRESULT WINAPI domfrag_get_nodeName(
187     IXMLDOMDocumentFragment *iface,
188     BSTR* p )
189 {
190     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
191
192     static const WCHAR document_fragmentW[] =
193         {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0};
194
195     TRACE("(%p)->(%p)\n", This, p);
196
197     return return_bstr(document_fragmentW, p);
198 }
199
200 static HRESULT WINAPI domfrag_get_nodeValue(
201     IXMLDOMDocumentFragment *iface,
202     VARIANT* value)
203 {
204     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
205
206     FIXME("(%p)->(%p)\n", This, value);
207
208     if(!value)
209         return E_INVALIDARG;
210
211     V_VT(value) = VT_NULL;
212     return S_FALSE;
213 }
214
215 static HRESULT WINAPI domfrag_put_nodeValue(
216     IXMLDOMDocumentFragment *iface,
217     VARIANT value)
218 {
219     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
220     TRACE("(%p)->(%s)\n", This, debugstr_variant(&value));
221     return E_FAIL;
222 }
223
224 static HRESULT WINAPI domfrag_get_nodeType(
225     IXMLDOMDocumentFragment *iface,
226     DOMNodeType* domNodeType )
227 {
228     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
229
230     TRACE("(%p)->(%p)\n", This, domNodeType);
231
232     *domNodeType = NODE_DOCUMENT_FRAGMENT;
233     return S_OK;
234 }
235
236 static HRESULT WINAPI domfrag_get_parentNode(
237     IXMLDOMDocumentFragment *iface,
238     IXMLDOMNode** parent )
239 {
240     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
241
242     TRACE("(%p)->(%p)\n", This, parent);
243
244     return node_get_parent(&This->node, parent);
245 }
246
247 static HRESULT WINAPI domfrag_get_childNodes(
248     IXMLDOMDocumentFragment *iface,
249     IXMLDOMNodeList** outList)
250 {
251     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
252
253     TRACE("(%p)->(%p)\n", This, outList);
254
255     return node_get_child_nodes(&This->node, outList);
256 }
257
258 static HRESULT WINAPI domfrag_get_firstChild(
259     IXMLDOMDocumentFragment *iface,
260     IXMLDOMNode** domNode)
261 {
262     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
263
264     TRACE("(%p)->(%p)\n", This, domNode);
265
266     return node_get_first_child(&This->node, domNode);
267 }
268
269 static HRESULT WINAPI domfrag_get_lastChild(
270     IXMLDOMDocumentFragment *iface,
271     IXMLDOMNode** domNode)
272 {
273     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
274
275     TRACE("(%p)->(%p)\n", This, domNode);
276
277     return node_get_last_child(&This->node, domNode);
278 }
279
280 static HRESULT WINAPI domfrag_get_previousSibling(
281     IXMLDOMDocumentFragment *iface,
282     IXMLDOMNode** domNode)
283 {
284     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
285
286     TRACE("(%p)->(%p)\n", This, domNode);
287
288     return return_null_node(domNode);
289 }
290
291 static HRESULT WINAPI domfrag_get_nextSibling(
292     IXMLDOMDocumentFragment *iface,
293     IXMLDOMNode** domNode)
294 {
295     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
296
297     TRACE("(%p)->(%p)\n", This, domNode);
298
299     return return_null_node(domNode);
300 }
301
302 static HRESULT WINAPI domfrag_get_attributes(
303     IXMLDOMDocumentFragment *iface,
304     IXMLDOMNamedNodeMap** attributeMap)
305 {
306     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
307
308     TRACE("(%p)->(%p)\n", This, attributeMap);
309
310     return return_null_ptr((void**)attributeMap);
311 }
312
313 static HRESULT WINAPI domfrag_insertBefore(
314     IXMLDOMDocumentFragment *iface,
315     IXMLDOMNode* newNode, VARIANT refChild,
316     IXMLDOMNode** outOldNode)
317 {
318     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
319
320     TRACE("(%p)->(%p %s %p)\n", This, newNode, debugstr_variant(&refChild), outOldNode);
321
322     /* TODO: test */
323     return node_insert_before(&This->node, newNode, &refChild, outOldNode);
324 }
325
326 static HRESULT WINAPI domfrag_replaceChild(
327     IXMLDOMDocumentFragment *iface,
328     IXMLDOMNode* newNode,
329     IXMLDOMNode* oldNode,
330     IXMLDOMNode** outOldNode)
331 {
332     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
333
334     TRACE("(%p)->(%p %p %p)\n", This, newNode, oldNode, outOldNode);
335
336     /* TODO: test */
337     return node_replace_child(&This->node, newNode, oldNode, outOldNode);
338 }
339
340 static HRESULT WINAPI domfrag_removeChild(
341     IXMLDOMDocumentFragment *iface,
342     IXMLDOMNode *child, IXMLDOMNode **oldChild)
343 {
344     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
345     TRACE("(%p)->(%p %p)\n", This, child, oldChild);
346     return node_remove_child(&This->node, child, oldChild);
347 }
348
349 static HRESULT WINAPI domfrag_appendChild(
350     IXMLDOMDocumentFragment *iface,
351     IXMLDOMNode *child, IXMLDOMNode **outChild)
352 {
353     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
354     TRACE("(%p)->(%p %p)\n", This, child, outChild);
355     return node_append_child(&This->node, child, outChild);
356 }
357
358 static HRESULT WINAPI domfrag_hasChildNodes(
359     IXMLDOMDocumentFragment *iface,
360     VARIANT_BOOL *ret)
361 {
362     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
363     TRACE("(%p)->(%p)\n", This, ret);
364     return node_has_childnodes(&This->node, ret);
365 }
366
367 static HRESULT WINAPI domfrag_get_ownerDocument(
368     IXMLDOMDocumentFragment *iface,
369     IXMLDOMDocument **doc)
370 {
371     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
372     TRACE("(%p)->(%p)\n", This, doc);
373     return node_get_owner_doc(&This->node, doc);
374 }
375
376 static HRESULT WINAPI domfrag_cloneNode(
377     IXMLDOMDocumentFragment *iface,
378     VARIANT_BOOL deep, IXMLDOMNode** outNode)
379 {
380     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
381     TRACE("(%p)->(%d %p)\n", This, deep, outNode);
382     return node_clone( &This->node, deep, outNode );
383 }
384
385 static HRESULT WINAPI domfrag_get_nodeTypeString(
386     IXMLDOMDocumentFragment *iface,
387     BSTR* p)
388 {
389     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
390     static const WCHAR documentfragmentW[] = {'d','o','c','u','m','e','n','t','f','r','a','g','m','e','n','t',0};
391
392     TRACE("(%p)->(%p)\n", This, p);
393
394     return return_bstr(documentfragmentW, p);
395 }
396
397 static HRESULT WINAPI domfrag_get_text(
398     IXMLDOMDocumentFragment *iface,
399     BSTR* p)
400 {
401     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
402     TRACE("(%p)->(%p)\n", This, p);
403     return node_get_text(&This->node, p);
404 }
405
406 static HRESULT WINAPI domfrag_put_text(
407     IXMLDOMDocumentFragment *iface,
408     BSTR p)
409 {
410     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
411     TRACE("(%p)->(%s)\n", This, debugstr_w(p));
412     return node_put_text( &This->node, p );
413 }
414
415 static HRESULT WINAPI domfrag_get_specified(
416     IXMLDOMDocumentFragment *iface,
417     VARIANT_BOOL* isSpecified)
418 {
419     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
420     FIXME("(%p)->(%p) stub!\n", This, isSpecified);
421     *isSpecified = VARIANT_TRUE;
422     return S_OK;
423 }
424
425 static HRESULT WINAPI domfrag_get_definition(
426     IXMLDOMDocumentFragment *iface,
427     IXMLDOMNode** definitionNode)
428 {
429     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
430     FIXME("(%p)->(%p)\n", This, definitionNode);
431     return E_NOTIMPL;
432 }
433
434 static HRESULT WINAPI domfrag_get_nodeTypedValue(
435     IXMLDOMDocumentFragment *iface,
436     VARIANT* var1)
437 {
438     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
439     FIXME("(%p)->(%p)\n", This, var1);
440     return return_null_var(var1);
441 }
442
443 static HRESULT WINAPI domfrag_put_nodeTypedValue(
444     IXMLDOMDocumentFragment *iface,
445     VARIANT typedValue)
446 {
447     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
448     FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue));
449     return E_NOTIMPL;
450 }
451
452 static HRESULT WINAPI domfrag_get_dataType(
453     IXMLDOMDocumentFragment *iface,
454     VARIANT* typename)
455 {
456     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
457     TRACE("(%p)->(%p)\n", This, typename);
458     return return_null_var( typename );
459 }
460
461 static HRESULT WINAPI domfrag_put_dataType(
462     IXMLDOMDocumentFragment *iface,
463     BSTR p)
464 {
465     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
466
467     FIXME("(%p)->(%s)\n", This, debugstr_w(p));
468
469     if(!p)
470         return E_INVALIDARG;
471
472     return E_FAIL;
473 }
474
475 static HRESULT WINAPI domfrag_get_xml(
476     IXMLDOMDocumentFragment *iface,
477     BSTR* p)
478 {
479     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
480
481     TRACE("(%p)->(%p)\n", This, p);
482
483     return node_get_xml(&This->node, FALSE, FALSE, p);
484 }
485
486 static HRESULT WINAPI domfrag_transformNode(
487     IXMLDOMDocumentFragment *iface,
488     IXMLDOMNode* domNode, BSTR* p)
489 {
490     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
491     return IXMLDOMNode_transformNode( &This->node.IXMLDOMNode_iface, domNode, p );
492 }
493
494 static HRESULT WINAPI domfrag_selectNodes(
495     IXMLDOMDocumentFragment *iface,
496     BSTR p, IXMLDOMNodeList** outList)
497 {
498     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
499     return IXMLDOMNode_selectNodes( &This->node.IXMLDOMNode_iface, p, outList );
500 }
501
502 static HRESULT WINAPI domfrag_selectSingleNode(
503     IXMLDOMDocumentFragment *iface,
504     BSTR p, IXMLDOMNode** outNode)
505 {
506     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
507     return IXMLDOMNode_selectSingleNode( &This->node.IXMLDOMNode_iface, p, outNode );
508 }
509
510 static HRESULT WINAPI domfrag_get_parsed(
511     IXMLDOMDocumentFragment *iface,
512     VARIANT_BOOL* isParsed)
513 {
514     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
515     FIXME("(%p)->(%p) stub!\n", This, isParsed);
516     *isParsed = VARIANT_TRUE;
517     return S_OK;
518 }
519
520 static HRESULT WINAPI domfrag_get_namespaceURI(
521     IXMLDOMDocumentFragment *iface,
522     BSTR* p)
523 {
524     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
525     TRACE("(%p)->(%p)\n", This, p);
526     return node_get_namespaceURI(&This->node, p);
527 }
528
529 static HRESULT WINAPI domfrag_get_prefix(
530     IXMLDOMDocumentFragment *iface,
531     BSTR* prefix)
532 {
533     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
534     TRACE("(%p)->(%p)\n", This, prefix);
535     return return_null_bstr( prefix );
536 }
537
538 static HRESULT WINAPI domfrag_get_baseName(
539     IXMLDOMDocumentFragment *iface,
540     BSTR* name)
541 {
542     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
543     FIXME("(%p)->(%p): needs test\n", This, name);
544     return return_null_bstr( name );
545 }
546
547 static HRESULT WINAPI domfrag_transformNodeToObject(
548     IXMLDOMDocumentFragment *iface,
549     IXMLDOMNode* domNode, VARIANT var1)
550 {
551     domfrag *This = impl_from_IXMLDOMDocumentFragment( iface );
552     FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1));
553     return E_NOTIMPL;
554 }
555
556 static const struct IXMLDOMDocumentFragmentVtbl domfrag_vtbl =
557 {
558     domfrag_QueryInterface,
559     domfrag_AddRef,
560     domfrag_Release,
561     domfrag_GetTypeInfoCount,
562     domfrag_GetTypeInfo,
563     domfrag_GetIDsOfNames,
564     domfrag_Invoke,
565     domfrag_get_nodeName,
566     domfrag_get_nodeValue,
567     domfrag_put_nodeValue,
568     domfrag_get_nodeType,
569     domfrag_get_parentNode,
570     domfrag_get_childNodes,
571     domfrag_get_firstChild,
572     domfrag_get_lastChild,
573     domfrag_get_previousSibling,
574     domfrag_get_nextSibling,
575     domfrag_get_attributes,
576     domfrag_insertBefore,
577     domfrag_replaceChild,
578     domfrag_removeChild,
579     domfrag_appendChild,
580     domfrag_hasChildNodes,
581     domfrag_get_ownerDocument,
582     domfrag_cloneNode,
583     domfrag_get_nodeTypeString,
584     domfrag_get_text,
585     domfrag_put_text,
586     domfrag_get_specified,
587     domfrag_get_definition,
588     domfrag_get_nodeTypedValue,
589     domfrag_put_nodeTypedValue,
590     domfrag_get_dataType,
591     domfrag_put_dataType,
592     domfrag_get_xml,
593     domfrag_transformNode,
594     domfrag_selectNodes,
595     domfrag_selectSingleNode,
596     domfrag_get_parsed,
597     domfrag_get_namespaceURI,
598     domfrag_get_prefix,
599     domfrag_get_baseName,
600     domfrag_transformNodeToObject
601 };
602
603 IUnknown* create_doc_fragment( xmlNodePtr fragment )
604 {
605     domfrag *This;
606
607     This = heap_alloc( sizeof *This );
608     if ( !This )
609         return NULL;
610
611     This->IXMLDOMDocumentFragment_iface.lpVtbl = &domfrag_vtbl;
612     This->ref = 1;
613
614     init_xmlnode(&This->node, fragment, (IXMLDOMNode*)&This->IXMLDOMDocumentFragment_iface, NULL);
615
616     return (IUnknown*)&This->IXMLDOMDocumentFragment_iface;
617 }
618
619 #endif