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
26 IXSLTemplate IXSLTemplate_iface
;
35 IXSLProcessor IXSLProcessor_iface
;
38 xsltemplate
*stylesheet
;
44 struct xslprocessor_params params
;
47 static HRESULT
XSLProcessor_create(xsltemplate
*, IXSLProcessor
**);
49 static inline xsltemplate
*impl_from_IXSLTemplate( IXSLTemplate
*iface
)
51 return CONTAINING_RECORD(iface
, xsltemplate
, IXSLTemplate_iface
);
54 static inline xslprocessor
*impl_from_IXSLProcessor( IXSLProcessor
*iface
)
56 return CONTAINING_RECORD(iface
, xslprocessor
, IXSLProcessor_iface
);
59 static void xslprocessor_par_free(struct xslprocessor_params
*params
, struct xslprocessor_par
*par
)
62 list_remove(&par
->entry
);
63 SysFreeString(par
->name
);
64 SysFreeString(par
->value
);
68 static void xsltemplate_set_node( xsltemplate
*This
, IXMLDOMNode
*node
)
70 if (This
->node
) IXMLDOMNode_Release(This
->node
);
72 if (node
) IXMLDOMNode_AddRef(node
);
75 static HRESULT WINAPI
xsltemplate_QueryInterface(
80 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
81 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
83 if ( IsEqualGUID( riid
, &IID_IXSLTemplate
) ||
84 IsEqualGUID( riid
, &IID_IDispatch
) ||
85 IsEqualGUID( riid
, &IID_IUnknown
) )
89 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
91 return *ppvObject
? S_OK
: E_NOINTERFACE
;
95 FIXME("Unsupported interface %s\n", debugstr_guid(riid
));
100 IUnknown_AddRef((IUnknown
*)*ppvObject
);
104 static ULONG WINAPI
xsltemplate_AddRef( IXSLTemplate
*iface
)
106 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
107 ULONG ref
= InterlockedIncrement( &This
->ref
);
108 TRACE("(%p)->(%d)\n", This
, ref
);
112 static ULONG WINAPI
xsltemplate_Release( IXSLTemplate
*iface
)
114 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
115 ULONG ref
= InterlockedDecrement( &This
->ref
);
117 TRACE("(%p)->(%d)\n", This
, ref
);
120 if (This
->node
) IXMLDOMNode_Release( This
->node
);
127 static HRESULT WINAPI
xsltemplate_GetTypeInfoCount( IXSLTemplate
*iface
, UINT
* pctinfo
)
129 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
130 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
133 static HRESULT WINAPI
xsltemplate_GetTypeInfo(
135 UINT iTInfo
, LCID lcid
,
136 ITypeInfo
** ppTInfo
)
138 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
139 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
140 iTInfo
, lcid
, ppTInfo
);
143 static HRESULT WINAPI
xsltemplate_GetIDsOfNames(
145 REFIID riid
, LPOLESTR
* rgszNames
,
146 UINT cNames
, LCID lcid
, DISPID
* rgDispId
)
148 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
149 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
150 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
153 static HRESULT WINAPI
xsltemplate_Invoke(
155 DISPID dispIdMember
, REFIID riid
, LCID lcid
,
156 WORD wFlags
, DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
,
157 EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
159 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
160 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
161 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
164 static HRESULT WINAPI
xsltemplate_putref_stylesheet( IXSLTemplate
*iface
,
167 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
169 TRACE("(%p)->(%p)\n", This
, node
);
173 xsltemplate_set_node(This
, NULL
);
177 /* FIXME: test for document type */
178 xsltemplate_set_node(This
, node
);
183 static HRESULT WINAPI
xsltemplate_get_stylesheet( IXSLTemplate
*iface
,
186 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
188 FIXME("(%p)->(%p): stub\n", This
, node
);
192 static HRESULT WINAPI
xsltemplate_createProcessor( IXSLTemplate
*iface
,
193 IXSLProcessor
**processor
)
195 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
197 TRACE("(%p)->(%p)\n", This
, processor
);
199 if (!processor
) return E_INVALIDARG
;
201 return XSLProcessor_create(This
, processor
);
204 static const struct IXSLTemplateVtbl XSLTemplateVtbl
=
206 xsltemplate_QueryInterface
,
209 xsltemplate_GetTypeInfoCount
,
210 xsltemplate_GetTypeInfo
,
211 xsltemplate_GetIDsOfNames
,
213 xsltemplate_putref_stylesheet
,
214 xsltemplate_get_stylesheet
,
215 xsltemplate_createProcessor
218 static const tid_t xsltemplate_iface_tids
[] = {
223 static dispex_static_data_t xsltemplate_dispex
= {
227 xsltemplate_iface_tids
230 HRESULT
XSLTemplate_create(void **ppObj
)
234 TRACE("(%p)\n", ppObj
);
236 This
= heap_alloc( sizeof (*This
) );
238 return E_OUTOFMEMORY
;
240 This
->IXSLTemplate_iface
.lpVtbl
= &XSLTemplateVtbl
;
243 init_dispex(&This
->dispex
, (IUnknown
*)&This
->IXSLTemplate_iface
, &xsltemplate_dispex
);
245 *ppObj
= &This
->IXSLTemplate_iface
;
247 TRACE("returning iface %p\n", *ppObj
);
252 /*** IXSLProcessor ***/
253 static HRESULT WINAPI
xslprocessor_QueryInterface(
254 IXSLProcessor
*iface
,
258 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
259 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
261 if ( IsEqualGUID( riid
, &IID_IXSLProcessor
) ||
262 IsEqualGUID( riid
, &IID_IDispatch
) ||
263 IsEqualGUID( riid
, &IID_IUnknown
) )
267 else if (dispex_query_interface(&This
->dispex
, riid
, ppvObject
))
269 return *ppvObject
? S_OK
: E_NOINTERFACE
;
273 FIXME("Unsupported interface %s\n", debugstr_guid(riid
));
275 return E_NOINTERFACE
;
278 IUnknown_AddRef((IUnknown
*)*ppvObject
);
282 static ULONG WINAPI
xslprocessor_AddRef( IXSLProcessor
*iface
)
284 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
285 ULONG ref
= InterlockedIncrement( &This
->ref
);
286 TRACE("(%p)->(%d)\n", This
, ref
);
290 static ULONG WINAPI
xslprocessor_Release( IXSLProcessor
*iface
)
292 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
293 ULONG ref
= InterlockedDecrement( &This
->ref
);
295 TRACE("(%p)->(%d)\n", This
, ref
);
298 struct xslprocessor_par
*par
, *par2
;
300 if (This
->input
) IXMLDOMNode_Release(This
->input
);
301 if (This
->output
) IStream_Release(This
->output
);
302 SysFreeString(This
->outstr
);
304 LIST_FOR_EACH_ENTRY_SAFE(par
, par2
, &This
->params
.list
, struct xslprocessor_par
, entry
)
305 xslprocessor_par_free(&This
->params
, par
);
307 IXSLTemplate_Release(&This
->stylesheet
->IXSLTemplate_iface
);
314 static HRESULT WINAPI
xslprocessor_GetTypeInfoCount( IXSLProcessor
*iface
, UINT
* pctinfo
)
316 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
317 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
320 static HRESULT WINAPI
xslprocessor_GetTypeInfo(
321 IXSLProcessor
*iface
,
322 UINT iTInfo
, LCID lcid
,
323 ITypeInfo
** ppTInfo
)
325 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
326 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
,
327 iTInfo
, lcid
, ppTInfo
);
330 static HRESULT WINAPI
xslprocessor_GetIDsOfNames(
331 IXSLProcessor
*iface
,
332 REFIID riid
, LPOLESTR
* rgszNames
,
333 UINT cNames
, LCID lcid
, DISPID
* rgDispId
)
335 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
336 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
,
337 riid
, rgszNames
, cNames
, lcid
, rgDispId
);
340 static HRESULT WINAPI
xslprocessor_Invoke(
341 IXSLProcessor
*iface
,
342 DISPID dispIdMember
, REFIID riid
, LCID lcid
,
343 WORD wFlags
, DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
,
344 EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
346 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
347 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
,
348 dispIdMember
, riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
351 static HRESULT WINAPI
xslprocessor_put_input( IXSLProcessor
*iface
, VARIANT input
)
353 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
354 IXMLDOMNode
*input_node
;
357 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&input
));
359 /* try IXMLDOMNode directly first */
360 if (V_VT(&input
) == VT_UNKNOWN
)
361 hr
= IUnknown_QueryInterface(V_UNKNOWN(&input
), &IID_IXMLDOMNode
, (void**)&input_node
);
362 else if (V_VT(&input
) == VT_DISPATCH
)
363 hr
= IDispatch_QueryInterface(V_DISPATCH(&input
), &IID_IXMLDOMNode
, (void**)&input_node
);
366 IXMLDOMDocument
*doc
;
368 hr
= DOMDocument_create(MSXML_DEFAULT
, (void**)&doc
);
373 hr
= IXMLDOMDocument_load(doc
, input
, &b
);
375 hr
= IXMLDOMDocument_QueryInterface(doc
, &IID_IXMLDOMNode
, (void**)&input_node
);
376 IXMLDOMDocument_Release(doc
);
382 if (This
->input
) IXMLDOMNode_Release(This
->input
);
383 This
->input
= input_node
;
389 static HRESULT WINAPI
xslprocessor_get_input( IXSLProcessor
*iface
, VARIANT
*input
)
391 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
393 FIXME("(%p)->(%p): stub\n", This
, input
);
397 static HRESULT WINAPI
xslprocessor_get_ownerTemplate(
398 IXSLProcessor
*iface
,
399 IXSLTemplate
**template)
401 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
403 FIXME("(%p)->(%p): stub\n", This
, template);
407 static HRESULT WINAPI
xslprocessor_setStartMode(
408 IXSLProcessor
*iface
,
412 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
414 FIXME("(%p)->(%s %s): stub\n", This
, debugstr_w(p
), debugstr_w(uri
));
418 static HRESULT WINAPI
xslprocessor_get_startMode(
419 IXSLProcessor
*iface
,
422 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
424 FIXME("(%p)->(%p): stub\n", This
, p
);
428 static HRESULT WINAPI
xslprocessor_get_startModeURI(
429 IXSLProcessor
*iface
,
432 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
434 FIXME("(%p)->(%p): stub\n", This
, uri
);
438 static HRESULT WINAPI
xslprocessor_put_output(
439 IXSLProcessor
*iface
,
442 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
446 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&output
));
448 switch (V_VT(&output
))
455 hr
= IUnknown_QueryInterface(V_UNKNOWN(&output
), &IID_IStream
, (void**)&stream
);
457 WARN("failed to get IStream from output, 0x%08x\n", hr
);
460 FIXME("output type %d not handled\n", V_VT(&output
));
466 if (This
->output
) IStream_Release(This
->output
);
467 This
->output
= stream
;
473 static HRESULT WINAPI
xslprocessor_get_output(
474 IXSLProcessor
*iface
,
477 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
479 TRACE("(%p)->(%p)\n", This
, output
);
481 if (!output
) return E_INVALIDARG
;
485 V_VT(output
) = VT_UNKNOWN
;
486 V_UNKNOWN(output
) = (IUnknown
*)This
->output
;
487 IStream_AddRef(This
->output
);
489 else if (This
->outstr
)
491 V_VT(output
) = VT_BSTR
;
492 V_BSTR(output
) = SysAllocString(This
->outstr
);
495 V_VT(output
) = VT_EMPTY
;
500 static HRESULT WINAPI
xslprocessor_transform(
501 IXSLProcessor
*iface
,
505 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
508 TRACE("(%p)->(%p)\n", This
, ret
);
510 if (!ret
) return E_INVALIDARG
;
512 SysFreeString(This
->outstr
);
513 hr
= node_transform_node_params(get_node_obj(This
->input
), This
->stylesheet
->node
, &This
->outstr
, This
->output
, &This
->params
);
514 *ret
= hr
== S_OK
? VARIANT_TRUE
: VARIANT_FALSE
;
517 FIXME("libxml2 is required but wasn't present at compile time\n");
522 static HRESULT WINAPI
xslprocessor_reset( IXSLProcessor
*iface
)
524 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
526 FIXME("(%p): stub\n", This
);
530 static HRESULT WINAPI
xslprocessor_get_readyState(
531 IXSLProcessor
*iface
,
534 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
536 FIXME("(%p)->(%p): stub\n", This
, state
);
540 static HRESULT
xslprocessor_set_parvalue(const VARIANT
*var
, struct xslprocessor_par
*par
)
548 par
->value
= SysAllocString(V_BSTR(var
));
549 if (!par
->value
) hr
= E_OUTOFMEMORY
;
553 FIXME("value type %d not handled\n", V_VT(var
));
560 static HRESULT WINAPI
xslprocessor_addParameter(
561 IXSLProcessor
*iface
,
566 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
567 struct xslprocessor_par
*cur
, *par
= NULL
;
570 TRACE("(%p)->(%s %s %s)\n", This
, debugstr_w(p
), debugstr_variant(&var
),
574 FIXME("namespace uri is not supported\n");
576 /* search for existing parameter first */
577 LIST_FOR_EACH_ENTRY(cur
, &This
->params
.list
, struct xslprocessor_par
, entry
)
579 if (!strcmpW(cur
->name
, p
))
586 /* override with new value or add new parameter */
589 if (V_VT(&var
) == VT_NULL
|| V_VT(&var
) == VT_EMPTY
)
591 /* remove parameter */
592 xslprocessor_par_free(&This
->params
, par
);
595 SysFreeString(par
->value
);
601 par
= heap_alloc(sizeof(struct xslprocessor_par
));
602 if (!par
) return E_OUTOFMEMORY
;
604 par
->name
= SysAllocString(p
);
608 return E_OUTOFMEMORY
;
610 list_add_tail(&This
->params
.list
, &par
->entry
);
611 This
->params
.count
++;
614 hr
= xslprocessor_set_parvalue(&var
, par
);
616 xslprocessor_par_free(&This
->params
, par
);
621 static HRESULT WINAPI
xslprocessor_addObject(
622 IXSLProcessor
*iface
,
626 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
628 FIXME("(%p)->(%p %s): stub\n", This
, obj
, debugstr_w(uri
));
632 static HRESULT WINAPI
xslprocessor_get_stylesheet(
633 IXSLProcessor
*iface
,
636 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
638 FIXME("(%p)->(%p): stub\n", This
, node
);
642 static const struct IXSLProcessorVtbl XSLProcessorVtbl
=
644 xslprocessor_QueryInterface
,
646 xslprocessor_Release
,
647 xslprocessor_GetTypeInfoCount
,
648 xslprocessor_GetTypeInfo
,
649 xslprocessor_GetIDsOfNames
,
651 xslprocessor_put_input
,
652 xslprocessor_get_input
,
653 xslprocessor_get_ownerTemplate
,
654 xslprocessor_setStartMode
,
655 xslprocessor_get_startMode
,
656 xslprocessor_get_startModeURI
,
657 xslprocessor_put_output
,
658 xslprocessor_get_output
,
659 xslprocessor_transform
,
661 xslprocessor_get_readyState
,
662 xslprocessor_addParameter
,
663 xslprocessor_addObject
,
664 xslprocessor_get_stylesheet
667 static const tid_t xslprocessor_iface_tids
[] = {
672 static dispex_static_data_t xslprocessor_dispex
= {
676 xslprocessor_iface_tids
679 HRESULT
XSLProcessor_create(xsltemplate
*template, IXSLProcessor
**ppObj
)
683 TRACE("(%p)\n", ppObj
);
685 This
= heap_alloc( sizeof (*This
) );
687 return E_OUTOFMEMORY
;
689 This
->IXSLProcessor_iface
.lpVtbl
= &XSLProcessorVtbl
;
694 list_init(&This
->params
.list
);
695 This
->params
.count
= 0;
696 This
->stylesheet
= template;
697 IXSLTemplate_AddRef(&template->IXSLTemplate_iface
);
698 init_dispex(&This
->dispex
, (IUnknown
*)&This
->IXSLProcessor_iface
, &xslprocessor_dispex
);
700 *ppObj
= &This
->IXSLProcessor_iface
;
702 TRACE("returning iface %p\n", *ppObj
);