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
);
45 typedef struct _xsltemplate
47 IXSLTemplate IXSLTemplate_iface
;
53 typedef struct _xslprocessor
55 IXSLProcessor IXSLProcessor_iface
;
58 xsltemplate
*stylesheet
;
65 static HRESULT
XSLProcessor_create(xsltemplate
*, IXSLProcessor
**);
67 static inline xsltemplate
*impl_from_IXSLTemplate( IXSLTemplate
*iface
)
69 return CONTAINING_RECORD(iface
, xsltemplate
, IXSLTemplate_iface
);
72 static inline xslprocessor
*impl_from_IXSLProcessor( IXSLProcessor
*iface
)
74 return CONTAINING_RECORD(iface
, xslprocessor
, IXSLProcessor_iface
);
77 static void xsltemplate_set_node( xsltemplate
*This
, IXMLDOMNode
*node
)
79 if (This
->node
) IXMLDOMNode_Release(This
->node
);
81 if (node
) IXMLDOMNode_AddRef(node
);
84 static HRESULT WINAPI
xsltemplate_QueryInterface(
89 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
90 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
92 if ( IsEqualGUID( riid
, &IID_IXSLTemplate
) ||
93 IsEqualGUID( riid
, &IID_IDispatch
) ||
94 IsEqualGUID( riid
, &IID_IUnknown
) )
100 FIXME("Unsupported interface %s\n", debugstr_guid(riid
));
102 return E_NOINTERFACE
;
105 IUnknown_AddRef((IUnknown
*)*ppvObject
);
109 static ULONG WINAPI
xsltemplate_AddRef( IXSLTemplate
*iface
)
111 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
112 return InterlockedIncrement( &This
->ref
);
115 static ULONG WINAPI
xsltemplate_Release( IXSLTemplate
*iface
)
117 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
120 ref
= InterlockedDecrement( &This
->ref
);
123 if (This
->node
) IXMLDOMNode_Release( This
->node
);
130 static HRESULT WINAPI
xsltemplate_GetTypeInfoCount( IXSLTemplate
*iface
, UINT
* pctinfo
)
132 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
134 TRACE("(%p)->(%p)\n", This
, pctinfo
);
140 static HRESULT WINAPI
xsltemplate_GetTypeInfo(
142 UINT iTInfo
, LCID lcid
,
143 ITypeInfo
** ppTInfo
)
145 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
147 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
149 return get_typeinfo(IXSLTemplate_tid
, ppTInfo
);
152 static HRESULT WINAPI
xsltemplate_GetIDsOfNames(
154 REFIID riid
, LPOLESTR
* rgszNames
,
155 UINT cNames
, LCID lcid
, DISPID
* rgDispId
)
157 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
161 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
164 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
167 hr
= get_typeinfo(IXSLTemplate_tid
, &typeinfo
);
170 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
171 ITypeInfo_Release(typeinfo
);
177 static HRESULT WINAPI
xsltemplate_Invoke(
179 DISPID dispIdMember
, REFIID riid
, LCID lcid
,
180 WORD wFlags
, DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
,
181 EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
183 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
187 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
188 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
190 hr
= get_typeinfo(IXSLTemplate_tid
, &typeinfo
);
193 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IXSLTemplate_iface
, dispIdMember
,
194 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
195 ITypeInfo_Release(typeinfo
);
201 static HRESULT WINAPI
xsltemplate_putref_stylesheet( IXSLTemplate
*iface
,
204 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
206 TRACE("(%p)->(%p)\n", This
, node
);
210 xsltemplate_set_node(This
, NULL
);
214 /* FIXME: test for document type */
215 xsltemplate_set_node(This
, node
);
220 static HRESULT WINAPI
xsltemplate_get_stylesheet( IXSLTemplate
*iface
,
223 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
225 FIXME("(%p)->(%p): stub\n", This
, node
);
229 static HRESULT WINAPI
xsltemplate_createProcessor( IXSLTemplate
*iface
,
230 IXSLProcessor
**processor
)
232 xsltemplate
*This
= impl_from_IXSLTemplate( iface
);
234 TRACE("(%p)->(%p)\n", This
, processor
);
236 if (!processor
) return E_INVALIDARG
;
238 return XSLProcessor_create(This
, processor
);
241 static const struct IXSLTemplateVtbl xsltemplate_vtbl
=
243 xsltemplate_QueryInterface
,
246 xsltemplate_GetTypeInfoCount
,
247 xsltemplate_GetTypeInfo
,
248 xsltemplate_GetIDsOfNames
,
251 xsltemplate_putref_stylesheet
,
252 xsltemplate_get_stylesheet
,
253 xsltemplate_createProcessor
256 HRESULT
XSLTemplate_create(IUnknown
*pUnkOuter
, void **ppObj
)
260 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
262 if(pUnkOuter
) FIXME("support aggregation, outer\n");
264 This
= heap_alloc( sizeof (*This
) );
266 return E_OUTOFMEMORY
;
268 This
->IXSLTemplate_iface
.lpVtbl
= &xsltemplate_vtbl
;
272 *ppObj
= &This
->IXSLTemplate_iface
;
274 TRACE("returning iface %p\n", *ppObj
);
279 /*** IXSLProcessor ***/
280 static HRESULT WINAPI
xslprocessor_QueryInterface(
281 IXSLProcessor
*iface
,
285 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
286 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppvObject
);
288 if ( IsEqualGUID( riid
, &IID_IXSLProcessor
) ||
289 IsEqualGUID( riid
, &IID_IDispatch
) ||
290 IsEqualGUID( riid
, &IID_IUnknown
) )
296 FIXME("Unsupported interface %s\n", debugstr_guid(riid
));
298 return E_NOINTERFACE
;
301 IUnknown_AddRef((IUnknown
*)*ppvObject
);
305 static ULONG WINAPI
xslprocessor_AddRef( IXSLProcessor
*iface
)
307 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
308 return InterlockedIncrement( &This
->ref
);
311 static ULONG WINAPI
xslprocessor_Release( IXSLProcessor
*iface
)
313 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
316 ref
= InterlockedDecrement( &This
->ref
);
319 if (This
->input
) IXMLDOMNode_Release(This
->input
);
320 if (This
->output
) IStream_Release(This
->output
);
321 SysFreeString(This
->outstr
);
322 IXSLTemplate_Release(&This
->stylesheet
->IXSLTemplate_iface
);
329 static HRESULT WINAPI
xslprocessor_GetTypeInfoCount( IXSLProcessor
*iface
, UINT
* pctinfo
)
331 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
333 TRACE("(%p)->(%p)\n", This
, pctinfo
);
339 static HRESULT WINAPI
xslprocessor_GetTypeInfo(
340 IXSLProcessor
*iface
,
341 UINT iTInfo
, LCID lcid
,
342 ITypeInfo
** ppTInfo
)
344 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
346 TRACE("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
348 return get_typeinfo(IXSLProcessor_tid
, ppTInfo
);
351 static HRESULT WINAPI
xslprocessor_GetIDsOfNames(
352 IXSLProcessor
*iface
,
353 REFIID riid
, LPOLESTR
* rgszNames
,
354 UINT cNames
, LCID lcid
, DISPID
* rgDispId
)
356 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
360 TRACE("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
363 if(!rgszNames
|| cNames
== 0 || !rgDispId
)
366 hr
= get_typeinfo(IXSLProcessor_tid
, &typeinfo
);
369 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
370 ITypeInfo_Release(typeinfo
);
376 static HRESULT WINAPI
xslprocessor_Invoke(
377 IXSLProcessor
*iface
,
378 DISPID dispIdMember
, REFIID riid
, LCID lcid
,
379 WORD wFlags
, DISPPARAMS
* pDispParams
, VARIANT
* pVarResult
,
380 EXCEPINFO
* pExcepInfo
, UINT
* puArgErr
)
382 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
386 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
387 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
389 hr
= get_typeinfo(IXSLProcessor_tid
, &typeinfo
);
392 hr
= ITypeInfo_Invoke(typeinfo
, &This
->IXSLProcessor_iface
, dispIdMember
,
393 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
394 ITypeInfo_Release(typeinfo
);
400 static HRESULT WINAPI
xslprocessor_put_input( IXSLProcessor
*iface
, VARIANT input
)
402 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
403 IXMLDOMNode
*input_node
;
406 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&input
));
408 /* try IXMLDOMNode directly first */
409 if (V_VT(&input
) == VT_UNKNOWN
)
410 hr
= IUnknown_QueryInterface(V_UNKNOWN(&input
), &IID_IXMLDOMNode
, (void**)&input_node
);
411 else if (V_VT(&input
) == VT_DISPATCH
)
412 hr
= IDispatch_QueryInterface(V_DISPATCH(&input
), &IID_IXMLDOMNode
, (void**)&input_node
);
415 IXMLDOMDocument
*doc
;
417 hr
= DOMDocument_create(MSXML_DEFAULT
, NULL
, (void**)&doc
);
422 hr
= IXMLDOMDocument_load(doc
, input
, &b
);
424 hr
= IXMLDOMDocument_QueryInterface(doc
, &IID_IXMLDOMNode
, (void**)&input_node
);
425 IXMLDOMDocument_Release(doc
);
431 if (This
->input
) IXMLDOMNode_Release(This
->input
);
432 This
->input
= input_node
;
438 static HRESULT WINAPI
xslprocessor_get_input( IXSLProcessor
*iface
, VARIANT
*input
)
440 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
442 FIXME("(%p)->(%p): stub\n", This
, input
);
446 static HRESULT WINAPI
xslprocessor_get_ownerTemplate(
447 IXSLProcessor
*iface
,
448 IXSLTemplate
**template)
450 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
452 FIXME("(%p)->(%p): stub\n", This
, template);
456 static HRESULT WINAPI
xslprocessor_setStartMode(
457 IXSLProcessor
*iface
,
461 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
463 FIXME("(%p)->(%s %s): stub\n", This
, wine_dbgstr_w(p
), wine_dbgstr_w(uri
));
467 static HRESULT WINAPI
xslprocessor_get_startMode(
468 IXSLProcessor
*iface
,
471 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
473 FIXME("(%p)->(%p): stub\n", This
, p
);
477 static HRESULT WINAPI
xslprocessor_get_startModeURI(
478 IXSLProcessor
*iface
,
481 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
483 FIXME("(%p)->(%p): stub\n", This
, uri
);
487 static HRESULT WINAPI
xslprocessor_put_output(
488 IXSLProcessor
*iface
,
491 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
495 FIXME("(%p)->(%s): semi-stub\n", This
, debugstr_variant(&output
));
497 switch (V_VT(&output
))
504 hr
= IUnknown_QueryInterface(V_UNKNOWN(&output
), &IID_IStream
, (void**)&stream
);
512 if (This
->output
) IStream_Release(This
->output
);
513 This
->output
= stream
;
519 static HRESULT WINAPI
xslprocessor_get_output(
520 IXSLProcessor
*iface
,
523 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
525 TRACE("(%p)->(%p)\n", This
, output
);
527 if (!output
) return E_INVALIDARG
;
531 V_VT(output
) = VT_UNKNOWN
;
532 V_UNKNOWN(output
) = (IUnknown
*)This
->output
;
533 IStream_AddRef(This
->output
);
535 else if (This
->outstr
)
537 V_VT(output
) = VT_BSTR
;
538 V_BSTR(output
) = SysAllocString(This
->outstr
);
541 V_VT(output
) = VT_EMPTY
;
546 static HRESULT WINAPI
xslprocessor_transform(
547 IXSLProcessor
*iface
,
550 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
553 TRACE("(%p)->(%p)\n", This
, ret
);
555 if (!ret
) return E_INVALIDARG
;
557 SysFreeString(This
->outstr
);
558 hr
= IXMLDOMNode_transformNode(This
->input
, This
->stylesheet
->node
, &This
->outstr
);
565 /* output to stream */
566 hr
= IStream_Write(This
->output
, This
->outstr
, SysStringByteLen(This
->outstr
), &len
);
567 *ret
= len
== SysStringByteLen(This
->outstr
) ? VARIANT_TRUE
: VARIANT_FALSE
;
571 *ret
= VARIANT_FALSE
;
576 static HRESULT WINAPI
xslprocessor_reset( IXSLProcessor
*iface
)
578 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
580 FIXME("(%p): stub\n", This
);
584 static HRESULT WINAPI
xslprocessor_get_readyState(
585 IXSLProcessor
*iface
,
588 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
590 FIXME("(%p)->(%p): stub\n", This
, state
);
594 static HRESULT WINAPI
xslprocessor_addParameter(
595 IXSLProcessor
*iface
,
600 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
602 FIXME("(%p)->(%s %s %s): stub\n", This
, wine_dbgstr_w(p
), debugstr_variant(&var
),
607 static HRESULT WINAPI
xslprocessor_addObject(
608 IXSLProcessor
*iface
,
612 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
614 FIXME("(%p)->(%p %s): stub\n", This
, obj
, wine_dbgstr_w(uri
));
618 static HRESULT WINAPI
xslprocessor_get_stylesheet(
619 IXSLProcessor
*iface
,
622 xslprocessor
*This
= impl_from_IXSLProcessor( iface
);
624 FIXME("(%p)->(%p): stub\n", This
, node
);
628 static const struct IXSLProcessorVtbl xslprocessor_vtbl
=
630 xslprocessor_QueryInterface
,
632 xslprocessor_Release
,
633 xslprocessor_GetTypeInfoCount
,
634 xslprocessor_GetTypeInfo
,
635 xslprocessor_GetIDsOfNames
,
638 xslprocessor_put_input
,
639 xslprocessor_get_input
,
640 xslprocessor_get_ownerTemplate
,
641 xslprocessor_setStartMode
,
642 xslprocessor_get_startMode
,
643 xslprocessor_get_startModeURI
,
644 xslprocessor_put_output
,
645 xslprocessor_get_output
,
646 xslprocessor_transform
,
648 xslprocessor_get_readyState
,
649 xslprocessor_addParameter
,
650 xslprocessor_addObject
,
651 xslprocessor_get_stylesheet
654 HRESULT
XSLProcessor_create(xsltemplate
*template, IXSLProcessor
**ppObj
)
658 TRACE("(%p)\n", ppObj
);
660 This
= heap_alloc( sizeof (*This
) );
662 return E_OUTOFMEMORY
;
664 This
->IXSLProcessor_iface
.lpVtbl
= &xslprocessor_vtbl
;
669 This
->stylesheet
= template;
670 IXSLTemplate_AddRef(&template->IXSLTemplate_iface
);
672 *ppObj
= &This
->IXSLProcessor_iface
;
674 TRACE("returning iface %p\n", *ppObj
);
681 HRESULT
XSLTemplate_create(IUnknown
*pUnkOuter
, void **ppObj
)
683 MESSAGE("This program tried to use a XSLTemplate object, but\n"
684 "libxml2 support was not present at compile time.\n");