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