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
32 #include "msxml_private.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
40 typedef struct _xsltemplate
42 IXSLTemplate IXSLTemplate_iface;
48 typedef struct _xslprocessor
50 IXSLProcessor IXSLProcessor_iface;
53 xsltemplate *stylesheet;
58 static HRESULT XSLProcessor_create(xsltemplate*, IXSLProcessor**);
60 static inline xsltemplate *impl_from_IXSLTemplate( IXSLTemplate *iface )
62 return CONTAINING_RECORD(iface, xsltemplate, IXSLTemplate_iface);
65 static inline xslprocessor *impl_from_IXSLProcessor( IXSLProcessor *iface )
67 return CONTAINING_RECORD(iface, xslprocessor, IXSLProcessor_iface);
70 static void xsltemplate_set_node( xsltemplate *This, IXMLDOMNode *node )
72 if (This->node) IXMLDOMNode_Release(This->node);
74 if (node) IXMLDOMNode_AddRef(node);
77 static HRESULT WINAPI xsltemplate_QueryInterface(
82 xsltemplate *This = impl_from_IXSLTemplate( iface );
83 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
85 if ( IsEqualGUID( riid, &IID_IXSLTemplate ) ||
86 IsEqualGUID( riid, &IID_IDispatch ) ||
87 IsEqualGUID( riid, &IID_IUnknown ) )
93 FIXME("Unsupported interface %s\n", debugstr_guid(riid));
97 IUnknown_AddRef((IUnknown*)*ppvObject);
101 static ULONG WINAPI xsltemplate_AddRef( IXSLTemplate *iface )
103 xsltemplate *This = impl_from_IXSLTemplate( iface );
104 return InterlockedIncrement( &This->ref );
107 static ULONG WINAPI xsltemplate_Release( IXSLTemplate *iface )
109 xsltemplate *This = impl_from_IXSLTemplate( iface );
112 ref = InterlockedDecrement( &This->ref );
115 if (This->node) IXMLDOMNode_Release( This->node );
122 static HRESULT WINAPI xsltemplate_GetTypeInfoCount( IXSLTemplate *iface, UINT* pctinfo )
124 xsltemplate *This = impl_from_IXSLTemplate( iface );
126 TRACE("(%p)->(%p)\n", This, pctinfo);
132 static HRESULT WINAPI xsltemplate_GetTypeInfo(
134 UINT iTInfo, LCID lcid,
135 ITypeInfo** ppTInfo )
137 xsltemplate *This = impl_from_IXSLTemplate( iface );
139 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
141 return get_typeinfo(IXSLTemplate_tid, ppTInfo);
144 static HRESULT WINAPI xsltemplate_GetIDsOfNames(
146 REFIID riid, LPOLESTR* rgszNames,
147 UINT cNames, LCID lcid, DISPID* rgDispId )
149 xsltemplate *This = impl_from_IXSLTemplate( iface );
153 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
156 if(!rgszNames || cNames == 0 || !rgDispId)
159 hr = get_typeinfo(IXSLTemplate_tid, &typeinfo);
162 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
163 ITypeInfo_Release(typeinfo);
169 static HRESULT WINAPI xsltemplate_Invoke(
171 DISPID dispIdMember, REFIID riid, LCID lcid,
172 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
173 EXCEPINFO* pExcepInfo, UINT* puArgErr )
175 xsltemplate *This = impl_from_IXSLTemplate( iface );
179 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
180 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
182 hr = get_typeinfo(IXSLTemplate_tid, &typeinfo);
185 hr = ITypeInfo_Invoke(typeinfo, &This->IXSLTemplate_iface, dispIdMember,
186 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
187 ITypeInfo_Release(typeinfo);
193 static HRESULT WINAPI xsltemplate_putref_stylesheet( IXSLTemplate *iface,
196 xsltemplate *This = impl_from_IXSLTemplate( iface );
198 TRACE("(%p)->(%p)\n", This, node);
202 xsltemplate_set_node(This, NULL);
206 /* FIXME: test for document type */
207 xsltemplate_set_node(This, node);
212 static HRESULT WINAPI xsltemplate_get_stylesheet( IXSLTemplate *iface,
215 xsltemplate *This = impl_from_IXSLTemplate( iface );
217 FIXME("(%p)->(%p): stub\n", This, node);
221 static HRESULT WINAPI xsltemplate_createProcessor( IXSLTemplate *iface,
222 IXSLProcessor **processor)
224 xsltemplate *This = impl_from_IXSLTemplate( iface );
226 TRACE("(%p)->(%p)\n", This, processor);
228 if (!processor) return E_INVALIDARG;
230 return XSLProcessor_create(This, processor);
233 static const struct IXSLTemplateVtbl xsltemplate_vtbl =
235 xsltemplate_QueryInterface,
238 xsltemplate_GetTypeInfoCount,
239 xsltemplate_GetTypeInfo,
240 xsltemplate_GetIDsOfNames,
243 xsltemplate_putref_stylesheet,
244 xsltemplate_get_stylesheet,
245 xsltemplate_createProcessor
248 HRESULT XSLTemplate_create(IUnknown *pUnkOuter, void **ppObj)
252 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
254 if(pUnkOuter) FIXME("support aggregation, outer\n");
256 This = heap_alloc( sizeof (*This) );
258 return E_OUTOFMEMORY;
260 This->IXSLTemplate_iface.lpVtbl = &xsltemplate_vtbl;
264 *ppObj = &This->IXSLTemplate_iface;
266 TRACE("returning iface %p\n", *ppObj);
271 /*** IXSLProcessor ***/
272 static HRESULT WINAPI xslprocessor_QueryInterface(
273 IXSLProcessor *iface,
277 xslprocessor *This = impl_from_IXSLProcessor( iface );
278 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
280 if ( IsEqualGUID( riid, &IID_IXSLProcessor ) ||
281 IsEqualGUID( riid, &IID_IDispatch ) ||
282 IsEqualGUID( riid, &IID_IUnknown ) )
288 FIXME("Unsupported interface %s\n", debugstr_guid(riid));
289 return E_NOINTERFACE;
292 IUnknown_AddRef((IUnknown*)*ppvObject);
296 static ULONG WINAPI xslprocessor_AddRef( IXSLProcessor *iface )
298 xslprocessor *This = impl_from_IXSLProcessor( iface );
299 return InterlockedIncrement( &This->ref );
302 static ULONG WINAPI xslprocessor_Release( IXSLProcessor *iface )
304 xslprocessor *This = impl_from_IXSLProcessor( iface );
307 ref = InterlockedDecrement( &This->ref );
310 if (This->input) IXMLDOMNode_Release(This->input);
311 if (This->output) IStream_Release(This->output);
312 IXSLTemplate_Release(&This->stylesheet->IXSLTemplate_iface);
319 static HRESULT WINAPI xslprocessor_GetTypeInfoCount( IXSLProcessor *iface, UINT* pctinfo )
321 xslprocessor *This = impl_from_IXSLProcessor( iface );
323 TRACE("(%p)->(%p)\n", This, pctinfo);
329 static HRESULT WINAPI xslprocessor_GetTypeInfo(
330 IXSLProcessor *iface,
331 UINT iTInfo, LCID lcid,
332 ITypeInfo** ppTInfo )
334 xslprocessor *This = impl_from_IXSLProcessor( iface );
336 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
338 return get_typeinfo(IXSLProcessor_tid, ppTInfo);
341 static HRESULT WINAPI xslprocessor_GetIDsOfNames(
342 IXSLProcessor *iface,
343 REFIID riid, LPOLESTR* rgszNames,
344 UINT cNames, LCID lcid, DISPID* rgDispId )
346 xslprocessor *This = impl_from_IXSLProcessor( iface );
350 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
353 if(!rgszNames || cNames == 0 || !rgDispId)
356 hr = get_typeinfo(IXSLProcessor_tid, &typeinfo);
359 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
360 ITypeInfo_Release(typeinfo);
366 static HRESULT WINAPI xslprocessor_Invoke(
367 IXSLProcessor *iface,
368 DISPID dispIdMember, REFIID riid, LCID lcid,
369 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
370 EXCEPINFO* pExcepInfo, UINT* puArgErr )
372 xslprocessor *This = impl_from_IXSLProcessor( iface );
376 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
377 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
379 hr = get_typeinfo(IXSLProcessor_tid, &typeinfo);
382 hr = ITypeInfo_Invoke(typeinfo, &This->IXSLProcessor_iface, dispIdMember,
383 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
384 ITypeInfo_Release(typeinfo);
390 static HRESULT WINAPI xslprocessor_put_input( IXSLProcessor *iface, VARIANT input )
392 xslprocessor *This = impl_from_IXSLProcessor( iface );
393 IXMLDOMNode *input_node;
396 TRACE("(%p)->(%s)\n", This, debugstr_variant(&input));
398 /* try IXMLDOMNode directly first */
399 if (V_VT(&input) == VT_UNKNOWN)
400 hr = IUnknown_QueryInterface(V_UNKNOWN(&input), &IID_IXMLDOMNode, (void**)&input_node);
401 else if (V_VT(&input) == VT_DISPATCH)
402 hr = IDispatch_QueryInterface(V_DISPATCH(&input), &IID_IXMLDOMNode, (void**)&input_node);
405 IXMLDOMDocument *doc;
407 hr = DOMDocument_create(&CLSID_DOMDocument, NULL, (void**)&doc);
412 hr = IXMLDOMDocument_load(doc, input, &b);
414 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&input_node);
415 IXMLDOMDocument_Release(doc);
421 if (This->input) IXMLDOMNode_Release(This->input);
422 This->input = input_node;
428 static HRESULT WINAPI xslprocessor_get_input( IXSLProcessor *iface, VARIANT *input )
430 xslprocessor *This = impl_from_IXSLProcessor( iface );
432 FIXME("(%p)->(%p): stub\n", This, input);
436 static HRESULT WINAPI xslprocessor_get_ownerTemplate(
437 IXSLProcessor *iface,
438 IXSLTemplate **template)
440 xslprocessor *This = impl_from_IXSLProcessor( iface );
442 FIXME("(%p)->(%p): stub\n", This, template);
446 static HRESULT WINAPI xslprocessor_setStartMode(
447 IXSLProcessor *iface,
451 xslprocessor *This = impl_from_IXSLProcessor( iface );
453 FIXME("(%p)->(%s %s): stub\n", This, wine_dbgstr_w(p), wine_dbgstr_w(uri));
457 static HRESULT WINAPI xslprocessor_get_startMode(
458 IXSLProcessor *iface,
461 xslprocessor *This = impl_from_IXSLProcessor( iface );
463 FIXME("(%p)->(%p): stub\n", This, p);
467 static HRESULT WINAPI xslprocessor_get_startModeURI(
468 IXSLProcessor *iface,
471 xslprocessor *This = impl_from_IXSLProcessor( iface );
473 FIXME("(%p)->(%p): stub\n", This, uri);
477 static HRESULT WINAPI xslprocessor_put_output(
478 IXSLProcessor *iface,
481 xslprocessor *This = impl_from_IXSLProcessor( iface );
485 FIXME("(%p)->(%s): semi-stub\n", This, debugstr_variant(&output));
487 switch (V_VT(&output))
494 hr = IUnknown_QueryInterface(V_UNKNOWN(&output), &IID_IStream, (void**)&stream);
502 if (This->output) IStream_Release(This->output);
503 This->output = stream;
509 static HRESULT WINAPI xslprocessor_get_output(
510 IXSLProcessor *iface,
513 xslprocessor *This = impl_from_IXSLProcessor( iface );
515 FIXME("(%p)->(%p): stub\n", This, output);
519 static HRESULT WINAPI xslprocessor_transform(
520 IXSLProcessor *iface,
523 xslprocessor *This = impl_from_IXSLProcessor( iface );
527 TRACE("(%p)->(%p)\n", This, ret);
529 if (!ret) return E_INVALIDARG;
531 hr = IXMLDOMNode_transformNode(This->input, This->stylesheet->node, &p);
536 /* output to stream */
537 hr = IStream_Write(This->output, p, SysStringByteLen(p), &len);
538 *ret = len == SysStringByteLen(p) ? VARIANT_TRUE : VARIANT_FALSE;
542 *ret = VARIANT_FALSE;
547 static HRESULT WINAPI xslprocessor_reset( IXSLProcessor *iface )
549 xslprocessor *This = impl_from_IXSLProcessor( iface );
551 FIXME("(%p): stub\n", This);
555 static HRESULT WINAPI xslprocessor_get_readyState(
556 IXSLProcessor *iface,
559 xslprocessor *This = impl_from_IXSLProcessor( iface );
561 FIXME("(%p)->(%p): stub\n", This, state);
565 static HRESULT WINAPI xslprocessor_addParameter(
566 IXSLProcessor *iface,
571 xslprocessor *This = impl_from_IXSLProcessor( iface );
573 FIXME("(%p)->(%s %s): stub\n", This, wine_dbgstr_w(p), wine_dbgstr_w(uri));
577 static HRESULT WINAPI xslprocessor_addObject(
578 IXSLProcessor *iface,
582 xslprocessor *This = impl_from_IXSLProcessor( iface );
584 FIXME("(%p)->(%p %s): stub\n", This, obj, wine_dbgstr_w(uri));
588 static HRESULT WINAPI xslprocessor_get_stylesheet(
589 IXSLProcessor *iface,
592 xslprocessor *This = impl_from_IXSLProcessor( iface );
594 FIXME("(%p)->(%p): stub\n", This, node);
598 static const struct IXSLProcessorVtbl xslprocessor_vtbl =
600 xslprocessor_QueryInterface,
602 xslprocessor_Release,
603 xslprocessor_GetTypeInfoCount,
604 xslprocessor_GetTypeInfo,
605 xslprocessor_GetIDsOfNames,
608 xslprocessor_put_input,
609 xslprocessor_get_input,
610 xslprocessor_get_ownerTemplate,
611 xslprocessor_setStartMode,
612 xslprocessor_get_startMode,
613 xslprocessor_get_startModeURI,
614 xslprocessor_put_output,
615 xslprocessor_get_output,
616 xslprocessor_transform,
618 xslprocessor_get_readyState,
619 xslprocessor_addParameter,
620 xslprocessor_addObject,
621 xslprocessor_get_stylesheet
624 HRESULT XSLProcessor_create(xsltemplate *template, IXSLProcessor **ppObj)
628 TRACE("(%p)\n", ppObj);
630 This = heap_alloc( sizeof (*This) );
632 return E_OUTOFMEMORY;
634 This->IXSLProcessor_iface.lpVtbl = &xslprocessor_vtbl;
638 This->stylesheet = template;
639 IXSLTemplate_AddRef(&template->IXSLTemplate_iface);
641 *ppObj = &This->IXSLProcessor_iface;
643 TRACE("returning iface %p\n", *ppObj);
650 HRESULT XSLTemplate_create(IUnknown *pUnkOuter, void **ppObj)
652 MESSAGE("This program tried to use a XSLTemplate object, but\n"
653 "libxml2 support was not present at compile time.\n");