2 * XSLTemplate/XSLProcessor support
4 * Copyright 2011 Nikolay Sivov for CodeWeavers
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
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
37 #include "msxml_private.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
46 IXSLTemplate IXSLTemplate_iface
;
55 IXSLProcessor IXSLProcessor_iface
;
58 xsltemplate
*stylesheet
;
64 struct xslprocessor_params params
;
67 static HRESULT
XSLProcessor_create(xsltemplate
*, IXSLProcessor
**);
69 static inline xsltemplate
*impl_from_IXSLTemplate( IXSLTemplate
*iface
)
71 return CONTAINING_RECORD(iface
, xsltemplate
, IXSLTemplate_iface
);
74 static inline xslprocessor
*impl_from_IXSLProcessor( IXSLProcessor
*iface
)
76 return CONTAINING_RECORD(iface
, xslprocessor
, IXSLProcessor_iface
);
79 static void xslprocessor_par_free(struct xslprocessor_params
*params
, struct xslprocessor_par
*par
)
82 list_remove(&par
->entry
);
83 SysFreeString(par
->name
);
84 SysFreeString(par
->value
);
88 static void xsltemplate_set_node( xsltemplate
*This
, IXMLDOMNode
*node
)
90 if (This
->node
) IXMLDOMNode_Release(This
->node
);
92 if (node
) IXMLDOMNode_AddRef(node
);
95 static HRESULT WINAPI
xsltemplate_QueryInterface(
100 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
101 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
103 if ( IsEqualGUID( riid
, &IID_IXSLTemplate
) ||
104 IsEqualGUID( riid
, &IID_IDispatch
) ||
105 IsEqualGUID( riid
, &IID_IUnknown
) )
109 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
111 return *ppvObject
? S_OK
: E_NOINTERFACE
;
115 FIXME("Unsupported interface %s\n", debugstr_guid(riid
));
117 return E_NOINTERFACE
;
120 IUnknown_AddRef((IUnknown
*)*ppvObject
);
124 static ULONG WINAPI
xsltemplate_AddRef( IXSLTemplate
*iface
)
126 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
127 ULONG ref
= InterlockedIncrement( &This
->ref
);
128 TRACE("(%p)->(%d)\n", This
, ref
);
132 static ULONG WINAPI
xsltemplate_Release( IXSLTemplate
*iface
)
134 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
135 ULONG ref
= InterlockedDecrement( &This
->ref
);
137 TRACE("(%p)->(%d)\n", This
, ref
);
140 if (This
->node
) IXMLDOMNode_Release( This
->node
);
147 static HRESULT WINAPI
xsltemplate_GetTypeInfoCount( IXSLTemplate
*iface
, UINT
* pctinfo
)
149 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
150 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
153 static HRESULT WINAPI
xsltemplate_GetTypeInfo(
155 UINT iTInfo
, LCID lcid
,
156 ITypeInfo
** ppTInfo
)
158 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
159 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
160 iTInfo
, lcid
, ppTInfo
);
163 static HRESULT WINAPI
xsltemplate_GetIDsOfNames(
165 REFIID riid
, LPOLESTR
* rgszNames
,
166 UINT cNames
, LCID lcid
, DISPID
* rgDispId
)
168 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
169 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
170 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
173 static HRESULT WINAPI
xsltemplate_Invoke(
175 DISPID dispIdMember
, REFIID riid
, LCID lcid
,
176 WORD wFlags
, DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
,
177 EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
179 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
180 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
181 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
184 static HRESULT WINAPI
xsltemplate_putref_stylesheet( IXSLTemplate
*iface
,
187 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
189 TRACE("(%p)->(%p)\n", This
, node
);
193 xsltemplate_set_node(This
, NULL
);
197 /* FIXME: test for document type */
198 xsltemplate_set_node(This
, node
);
203 static HRESULT WINAPI
xsltemplate_get_stylesheet( IXSLTemplate
*iface
,
206 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
208 FIXME("(%p)->(%p): stub\n", This
, node
);
212 static HRESULT WINAPI
xsltemplate_createProcessor( IXSLTemplate
*iface
,
213 IXSLProcessor
**processor
)
215 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
217 TRACE("(%p)->(%p)\n", This
, processor
);
219 if (!processor
) return E_INVALIDARG
;
221 return XSLProcessor_create(This
, processor
);
224 static const struct IXSLTemplateVtbl XSLTemplateVtbl
=
226 xsltemplate_QueryInterface
,
229 xsltemplate_GetTypeInfoCount
,
230 xsltemplate_GetTypeInfo
,
231 xsltemplate_GetIDsOfNames
,
233 xsltemplate_putref_stylesheet
,
234 xsltemplate_get_stylesheet
,
235 xsltemplate_createProcessor
238 static const tid_t xsltemplate_iface_tids
[] = {
243 static dispex_static_data_t xsltemplate_dispex
= {
247 xsltemplate_iface_tids
250 HRESULT
XSLTemplate_create(void **ppObj
)
254 TRACE("(%p)\n", ppObj
);
256 This
= heap_alloc( sizeof (*This
) );
258 return E_OUTOFMEMORY
;
260 This
->IXSLTemplate_iface
.lpVtbl
= &XSLTemplateVtbl
;
263 init_dispex(&This
->dispex
, (IUnknown
*)&This
->IXSLTemplate_iface
, &xsltemplate_dispex
);
265 *ppObj
= &This
->IXSLTemplate_iface
;
267 TRACE("returning iface %p\n", *ppObj
);
272 /*** IXSLProcessor ***/
273 static HRESULT WINAPI
xslprocessor_QueryInterface(
274 IXSLProcessor
*iface
,
278 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
279 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
281 if ( IsEqualGUID( riid
, &IID_IXSLProcessor
) ||
282 IsEqualGUID( riid
, &IID_IDispatch
) ||
283 IsEqualGUID( riid
, &IID_IUnknown
) )
287 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
289 return *ppvObject
? S_OK
: E_NOINTERFACE
;
293 FIXME("Unsupported interface %s\n", debugstr_guid(riid
));
295 return E_NOINTERFACE
;
298 IUnknown_AddRef((IUnknown
*)*ppvObject
);
302 static ULONG WINAPI
xslprocessor_AddRef( IXSLProcessor
*iface
)
304 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
305 ULONG ref
= InterlockedIncrement( &This
->ref
);
306 TRACE("(%p)->(%d)\n", This
, ref
);
310 static ULONG WINAPI
xslprocessor_Release( IXSLProcessor
*iface
)
312 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
313 ULONG ref
= InterlockedDecrement( &This
->ref
);
315 TRACE("(%p)->(%d)\n", This
, ref
);
318 struct xslprocessor_par
*par
, *par2
;
320 if (This
->input
) IXMLDOMNode_Release(This
->input
);
321 if (This
->output
) IStream_Release(This
->output
);
322 SysFreeString(This
->outstr
);
324 LIST_FOR_EACH_ENTRY_SAFE(par
, par2
, &This
->params
.list
, struct xslprocessor_par
, entry
)
325 xslprocessor_par_free(&This
->params
, par
);
327 IXSLTemplate_Release(&This
->stylesheet
->IXSLTemplate_iface
);
334 static HRESULT WINAPI
xslprocessor_GetTypeInfoCount( IXSLProcessor
*iface
, UINT
* pctinfo
)
336 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
337 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
340 static HRESULT WINAPI
xslprocessor_GetTypeInfo(
341 IXSLProcessor
*iface
,
342 UINT iTInfo
, LCID lcid
,
343 ITypeInfo
** ppTInfo
)
345 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
346 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
347 iTInfo
, lcid
, ppTInfo
);
350 static HRESULT WINAPI
xslprocessor_GetIDsOfNames(
351 IXSLProcessor
*iface
,
352 REFIID riid
, LPOLESTR
* rgszNames
,
353 UINT cNames
, LCID lcid
, DISPID
* rgDispId
)
355 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
356 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
357 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
360 static HRESULT WINAPI
xslprocessor_Invoke(
361 IXSLProcessor
*iface
,
362 DISPID dispIdMember
, REFIID riid
, LCID lcid
,
363 WORD wFlags
, DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
,
364 EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
366 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
367 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
368 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
371 static HRESULT WINAPI
xslprocessor_put_input( IXSLProcessor
*iface
, VARIANT input
)
373 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
374 IXMLDOMNode
*input_node
;
377 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&input
));
379 /* try IXMLDOMNode directly first */
380 if (V_VT(&input
) == VT_UNKNOWN
)
381 hr
= IUnknown_QueryInterface(V_UNKNOWN(&input
), &IID_IXMLDOMNode
, (void**)&input_node
);
382 else if (V_VT(&input
) == VT_DISPATCH
)
383 hr
= IDispatch_QueryInterface(V_DISPATCH(&input
), &IID_IXMLDOMNode
, (void**)&input_node
);
386 IXMLDOMDocument
*doc
;
388 hr
= DOMDocument_create(MSXML_DEFAULT
, (void**)&doc
);
393 hr
= IXMLDOMDocument_load(doc
, input
, &b
);
395 hr
= IXMLDOMDocument_QueryInterface(doc
, &IID_IXMLDOMNode
, (void**)&input_node
);
396 IXMLDOMDocument_Release(doc
);
402 if (This
->input
) IXMLDOMNode_Release(This
->input
);
403 This
->input
= input_node
;
409 static HRESULT WINAPI
xslprocessor_get_input( IXSLProcessor
*iface
, VARIANT
*input
)
411 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
413 FIXME("(%p)->(%p): stub\n", This
, input
);
417 static HRESULT WINAPI
xslprocessor_get_ownerTemplate(
418 IXSLProcessor
*iface
,
419 IXSLTemplate
**template)
421 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
423 FIXME("(%p)->(%p): stub\n", This
, template);
427 static HRESULT WINAPI
xslprocessor_setStartMode(
428 IXSLProcessor
*iface
,
432 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
434 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(p
), debugstr_w(uri
));
438 static HRESULT WINAPI
xslprocessor_get_startMode(
439 IXSLProcessor
*iface
,
442 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
444 FIXME("(%p)->(%p): stub\n", This
, p
);
448 static HRESULT WINAPI
xslprocessor_get_startModeURI(
449 IXSLProcessor
*iface
,
452 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
454 FIXME("(%p)->(%p): stub\n", This
, uri
);
458 static HRESULT WINAPI
xslprocessor_put_output(
459 IXSLProcessor
*iface
,
462 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
466 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&output
));
468 switch (V_VT(&output
))
475 hr
= IUnknown_QueryInterface(V_UNKNOWN(&output
), &IID_IStream
, (void**)&stream
);
477 WARN("failed to get IStream from output, 0x%08x\n", hr
);
480 FIXME("output type %d not handled\n", V_VT(&output
));
486 if (This
->output
) IStream_Release(This
->output
);
487 This
->output
= stream
;
493 static HRESULT WINAPI
xslprocessor_get_output(
494 IXSLProcessor
*iface
,
497 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
499 TRACE("(%p)->(%p)\n", This
, output
);
501 if (!output
) return E_INVALIDARG
;
505 V_VT(output
) = VT_UNKNOWN
;
506 V_UNKNOWN(output
) = (IUnknown
*)This
->output
;
507 IStream_AddRef(This
->output
);
509 else if (This
->outstr
)
511 V_VT(output
) = VT_BSTR
;
512 V_BSTR(output
) = SysAllocString(This
->outstr
);
515 V_VT(output
) = VT_EMPTY
;
520 static HRESULT WINAPI
xslprocessor_transform(
521 IXSLProcessor
*iface
,
525 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
528 TRACE("(%p)->(%p)\n", This
, ret
);
530 if (!ret
) return E_INVALIDARG
;
532 SysFreeString(This
->outstr
);
533 hr
= node_transform_node_params(get_node_obj(This
->input
), This
->stylesheet
->node
, &This
->outstr
, This
->output
, &This
->params
);
534 *ret
= hr
== S_OK
? VARIANT_TRUE
: VARIANT_FALSE
;
537 FIXME("libxml2 is required but wasn't present at compile time\n");
542 static HRESULT WINAPI
xslprocessor_reset( IXSLProcessor
*iface
)
544 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
546 FIXME("(%p): stub\n", This
);
550 static HRESULT WINAPI
xslprocessor_get_readyState(
551 IXSLProcessor
*iface
,
554 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
556 FIXME("(%p)->(%p): stub\n", This
, state
);
560 static HRESULT
xslprocessor_set_parvalue(const VARIANT
*var
, struct xslprocessor_par
*par
)
568 par
->value
= SysAllocString(V_BSTR(var
));
569 if (!par
->value
) hr
= E_OUTOFMEMORY
;
573 FIXME("value type %d not handled\n", V_VT(var
));
580 static HRESULT WINAPI
xslprocessor_addParameter(
581 IXSLProcessor
*iface
,
586 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
587 struct xslprocessor_par
*cur
, *par
= NULL
;
590 TRACE("(%p)->(%s %s %s)\n", This
, debugstr_w(p
), debugstr_variant(&var
),
594 FIXME("namespace uri is not supported\n");
596 /* search for existing parameter first */
597 LIST_FOR_EACH_ENTRY(cur
, &This
->params
.list
, struct xslprocessor_par
, entry
)
599 if (!strcmpW(cur
->name
, p
))
606 /* override with new value or add new parameter */
609 if (V_VT(&var
) == VT_NULL
|| V_VT(&var
) == VT_EMPTY
)
611 /* remove parameter */
612 xslprocessor_par_free(&This
->params
, par
);
615 SysFreeString(par
->value
);
621 par
= heap_alloc(sizeof(struct xslprocessor_par
));
622 if (!par
) return E_OUTOFMEMORY
;
624 par
->name
= SysAllocString(p
);
628 return E_OUTOFMEMORY
;
630 list_add_tail(&This
->params
.list
, &par
->entry
);
631 This
->params
.count
++;
634 hr
= xslprocessor_set_parvalue(&var
, par
);
636 xslprocessor_par_free(&This
->params
, par
);
641 static HRESULT WINAPI
xslprocessor_addObject(
642 IXSLProcessor
*iface
,
646 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
648 FIXME("(%p)->(%p %s): stub\n", This
, obj
, debugstr_w(uri
));
652 static HRESULT WINAPI
xslprocessor_get_stylesheet(
653 IXSLProcessor
*iface
,
656 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
658 FIXME("(%p)->(%p): stub\n", This
, node
);
662 static const struct IXSLProcessorVtbl XSLProcessorVtbl
=
664 xslprocessor_QueryInterface
,
666 xslprocessor_Release
,
667 xslprocessor_GetTypeInfoCount
,
668 xslprocessor_GetTypeInfo
,
669 xslprocessor_GetIDsOfNames
,
671 xslprocessor_put_input
,
672 xslprocessor_get_input
,
673 xslprocessor_get_ownerTemplate
,
674 xslprocessor_setStartMode
,
675 xslprocessor_get_startMode
,
676 xslprocessor_get_startModeURI
,
677 xslprocessor_put_output
,
678 xslprocessor_get_output
,
679 xslprocessor_transform
,
681 xslprocessor_get_readyState
,
682 xslprocessor_addParameter
,
683 xslprocessor_addObject
,
684 xslprocessor_get_stylesheet
687 static const tid_t xslprocessor_iface_tids
[] = {
692 static dispex_static_data_t xslprocessor_dispex
= {
696 xslprocessor_iface_tids
699 HRESULT
XSLProcessor_create(xsltemplate
*template, IXSLProcessor
**ppObj
)
703 TRACE("(%p)\n", ppObj
);
705 This
= heap_alloc( sizeof (*This
) );
707 return E_OUTOFMEMORY
;
709 This
->IXSLProcessor_iface
.lpVtbl
= &XSLProcessorVtbl
;
714 list_init(&This
->params
.list
);
715 This
->params
.count
= 0;
716 This
->stylesheet
= template;
717 IXSLTemplate_AddRef(&template->IXSLTemplate_iface
);
718 init_dispex(&This
->dispex
, (IUnknown
*)&This
->IXSLProcessor_iface
, &xslprocessor_dispex
);
720 *ppObj
= &This
->IXSLProcessor_iface
;
722 TRACE("returning iface %p\n", *ppObj
);