msvcrt: _Gettnames() should respect user overrides.
[wine.git] / dlls / msxml3 / stylesheet.c
blob9863ed7aa4b93b902e2b12c142088d0850d2b730
1 /*
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
21 #define COBJMACROS
23 #include "config.h"
25 #include <stdarg.h>
26 #ifdef HAVE_LIBXML2
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
29 #endif
31 #include "windef.h"
32 #include "winbase.h"
33 #include "winuser.h"
34 #include "ole2.h"
35 #include "msxml6.h"
37 #include "msxml_private.h"
39 #include "initguid.h"
40 #include "asptlb.h"
42 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
46 typedef struct
48 DispatchEx dispex;
49 IXSLTemplate IXSLTemplate_iface;
50 LONG ref;
52 IXMLDOMNode *node;
53 } xsltemplate;
55 enum output_type
57 PROCESSOR_OUTPUT_NOT_SET,
58 PROCESSOR_OUTPUT_STREAM, /* IStream or ISequentialStream */
59 PROCESSOR_OUTPUT_PERSISTSTREAM, /* IPersistStream or IPersistStreamInit */
60 PROCESSOR_OUTPUT_RESPONSE, /* IResponse */
63 typedef struct
65 DispatchEx dispex;
66 IXSLProcessor IXSLProcessor_iface;
67 LONG ref;
69 xsltemplate *stylesheet;
70 IXMLDOMNode *input;
72 union
74 IUnknown *unk;
75 ISequentialStream *stream;
76 IPersistStream *persiststream;
77 IResponse *response;
78 } output;
79 enum output_type output_type;
80 BSTR outstr;
82 struct xslprocessor_params params;
83 } xslprocessor;
85 static HRESULT XSLProcessor_create(xsltemplate*, IXSLProcessor**);
87 static inline xsltemplate *impl_from_IXSLTemplate( IXSLTemplate *iface )
89 return CONTAINING_RECORD(iface, xsltemplate, IXSLTemplate_iface);
92 static inline xslprocessor *impl_from_IXSLProcessor( IXSLProcessor *iface )
94 return CONTAINING_RECORD(iface, xslprocessor, IXSLProcessor_iface);
97 static void xslprocessor_par_free(struct xslprocessor_params *params, struct xslprocessor_par *par)
99 params->count--;
100 list_remove(&par->entry);
101 SysFreeString(par->name);
102 SysFreeString(par->value);
103 heap_free(par);
106 static void xsltemplate_set_node( xsltemplate *This, IXMLDOMNode *node )
108 if (This->node) IXMLDOMNode_Release(This->node);
109 This->node = node;
110 if (node) IXMLDOMNode_AddRef(node);
113 static HRESULT WINAPI xsltemplate_QueryInterface(
114 IXSLTemplate *iface,
115 REFIID riid,
116 void** ppvObject )
118 xsltemplate *This = impl_from_IXSLTemplate( iface );
119 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
121 if ( IsEqualGUID( riid, &IID_IXSLTemplate ) ||
122 IsEqualGUID( riid, &IID_IDispatch ) ||
123 IsEqualGUID( riid, &IID_IUnknown ) )
125 *ppvObject = iface;
127 else if (dispex_query_interface(&This->dispex, riid, ppvObject))
129 return *ppvObject ? S_OK : E_NOINTERFACE;
131 else
133 FIXME("Unsupported interface %s\n", debugstr_guid(riid));
134 *ppvObject = NULL;
135 return E_NOINTERFACE;
138 IUnknown_AddRef((IUnknown*)*ppvObject);
139 return S_OK;
142 static ULONG WINAPI xsltemplate_AddRef( IXSLTemplate *iface )
144 xsltemplate *This = impl_from_IXSLTemplate( iface );
145 ULONG ref = InterlockedIncrement( &This->ref );
146 TRACE("(%p)->(%d)\n", This, ref);
147 return ref;
150 static ULONG WINAPI xsltemplate_Release( IXSLTemplate *iface )
152 xsltemplate *This = impl_from_IXSLTemplate( iface );
153 ULONG ref = InterlockedDecrement( &This->ref );
155 TRACE("(%p)->(%d)\n", This, ref);
156 if ( ref == 0 )
158 if (This->node) IXMLDOMNode_Release( This->node );
159 heap_free( This );
162 return ref;
165 static HRESULT WINAPI xsltemplate_GetTypeInfoCount( IXSLTemplate *iface, UINT* pctinfo )
167 xsltemplate *This = impl_from_IXSLTemplate( iface );
168 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
171 static HRESULT WINAPI xsltemplate_GetTypeInfo(
172 IXSLTemplate *iface,
173 UINT iTInfo, LCID lcid,
174 ITypeInfo** ppTInfo )
176 xsltemplate *This = impl_from_IXSLTemplate( iface );
177 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
178 iTInfo, lcid, ppTInfo);
181 static HRESULT WINAPI xsltemplate_GetIDsOfNames(
182 IXSLTemplate *iface,
183 REFIID riid, LPOLESTR* rgszNames,
184 UINT cNames, LCID lcid, DISPID* rgDispId )
186 xsltemplate *This = impl_from_IXSLTemplate( iface );
187 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
188 riid, rgszNames, cNames, lcid, rgDispId);
191 static HRESULT WINAPI xsltemplate_Invoke(
192 IXSLTemplate *iface,
193 DISPID dispIdMember, REFIID riid, LCID lcid,
194 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
195 EXCEPINFO* pExcepInfo, UINT* puArgErr )
197 xsltemplate *This = impl_from_IXSLTemplate( iface );
198 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
199 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
202 static HRESULT WINAPI xsltemplate_putref_stylesheet( IXSLTemplate *iface,
203 IXMLDOMNode *node)
205 xsltemplate *This = impl_from_IXSLTemplate( iface );
207 TRACE("(%p)->(%p)\n", This, node);
209 if (!node)
211 xsltemplate_set_node(This, NULL);
212 return S_OK;
215 /* FIXME: test for document type */
216 xsltemplate_set_node(This, node);
218 return S_OK;
221 static HRESULT WINAPI xsltemplate_get_stylesheet( IXSLTemplate *iface,
222 IXMLDOMNode **node)
224 xsltemplate *This = impl_from_IXSLTemplate( iface );
226 FIXME("(%p)->(%p): stub\n", This, node);
227 return E_NOTIMPL;
230 static HRESULT WINAPI xsltemplate_createProcessor( IXSLTemplate *iface,
231 IXSLProcessor **processor)
233 xsltemplate *This = impl_from_IXSLTemplate( iface );
235 TRACE("(%p)->(%p)\n", This, processor);
237 if (!processor) return E_INVALIDARG;
239 return XSLProcessor_create(This, processor);
242 static const struct IXSLTemplateVtbl XSLTemplateVtbl =
244 xsltemplate_QueryInterface,
245 xsltemplate_AddRef,
246 xsltemplate_Release,
247 xsltemplate_GetTypeInfoCount,
248 xsltemplate_GetTypeInfo,
249 xsltemplate_GetIDsOfNames,
250 xsltemplate_Invoke,
251 xsltemplate_putref_stylesheet,
252 xsltemplate_get_stylesheet,
253 xsltemplate_createProcessor
256 static const tid_t xsltemplate_iface_tids[] = {
257 IXSLTemplate_tid,
261 static dispex_static_data_t xsltemplate_dispex = {
262 NULL,
263 IXSLTemplate_tid,
264 NULL,
265 xsltemplate_iface_tids
268 HRESULT XSLTemplate_create(void **ppObj)
270 xsltemplate *This;
272 TRACE("(%p)\n", ppObj);
274 This = heap_alloc( sizeof (*This) );
275 if(!This)
276 return E_OUTOFMEMORY;
278 This->IXSLTemplate_iface.lpVtbl = &XSLTemplateVtbl;
279 This->ref = 1;
280 This->node = NULL;
281 init_dispex(&This->dispex, (IUnknown*)&This->IXSLTemplate_iface, &xsltemplate_dispex);
283 *ppObj = &This->IXSLTemplate_iface;
285 TRACE("returning iface %p\n", *ppObj);
287 return S_OK;
290 /*** IXSLProcessor ***/
291 static HRESULT WINAPI xslprocessor_QueryInterface(
292 IXSLProcessor *iface,
293 REFIID riid,
294 void** ppvObject )
296 xslprocessor *This = impl_from_IXSLProcessor( iface );
297 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
299 if ( IsEqualGUID( riid, &IID_IXSLProcessor ) ||
300 IsEqualGUID( riid, &IID_IDispatch ) ||
301 IsEqualGUID( riid, &IID_IUnknown ) )
303 *ppvObject = iface;
305 else if (dispex_query_interface(&This->dispex, riid, ppvObject))
307 return *ppvObject ? S_OK : E_NOINTERFACE;
309 else
311 FIXME("Unsupported interface %s\n", debugstr_guid(riid));
312 *ppvObject = NULL;
313 return E_NOINTERFACE;
316 IUnknown_AddRef((IUnknown*)*ppvObject);
317 return S_OK;
320 static ULONG WINAPI xslprocessor_AddRef( IXSLProcessor *iface )
322 xslprocessor *This = impl_from_IXSLProcessor( iface );
323 ULONG ref = InterlockedIncrement( &This->ref );
324 TRACE("(%p)->(%d)\n", This, ref);
325 return ref;
328 static ULONG WINAPI xslprocessor_Release( IXSLProcessor *iface )
330 xslprocessor *This = impl_from_IXSLProcessor( iface );
331 ULONG ref = InterlockedDecrement( &This->ref );
333 TRACE("(%p)->(%d)\n", This, ref);
334 if ( ref == 0 )
336 struct xslprocessor_par *par, *par2;
338 if (This->input) IXMLDOMNode_Release(This->input);
339 if (This->output.unk)
340 IUnknown_Release(This->output.unk);
341 SysFreeString(This->outstr);
343 LIST_FOR_EACH_ENTRY_SAFE(par, par2, &This->params.list, struct xslprocessor_par, entry)
344 xslprocessor_par_free(&This->params, par);
346 IXSLTemplate_Release(&This->stylesheet->IXSLTemplate_iface);
347 heap_free( This );
350 return ref;
353 static HRESULT WINAPI xslprocessor_GetTypeInfoCount( IXSLProcessor *iface, UINT* pctinfo )
355 xslprocessor *This = impl_from_IXSLProcessor( iface );
356 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
359 static HRESULT WINAPI xslprocessor_GetTypeInfo(
360 IXSLProcessor *iface,
361 UINT iTInfo, LCID lcid,
362 ITypeInfo** ppTInfo )
364 xslprocessor *This = impl_from_IXSLProcessor( iface );
365 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
366 iTInfo, lcid, ppTInfo);
369 static HRESULT WINAPI xslprocessor_GetIDsOfNames(
370 IXSLProcessor *iface,
371 REFIID riid, LPOLESTR* rgszNames,
372 UINT cNames, LCID lcid, DISPID* rgDispId )
374 xslprocessor *This = impl_from_IXSLProcessor( iface );
375 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
376 riid, rgszNames, cNames, lcid, rgDispId);
379 static HRESULT WINAPI xslprocessor_Invoke(
380 IXSLProcessor *iface,
381 DISPID dispIdMember, REFIID riid, LCID lcid,
382 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,
383 EXCEPINFO* pExcepInfo, UINT* puArgErr )
385 xslprocessor *This = impl_from_IXSLProcessor( iface );
386 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
387 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
390 static HRESULT WINAPI xslprocessor_put_input( IXSLProcessor *iface, VARIANT input )
392 xslprocessor *This = impl_from_IXSLProcessor( iface );
393 IXMLDOMNode *input_node;
394 HRESULT hr;
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);
403 else
405 IXMLDOMDocument *doc;
407 hr = DOMDocument_create(MSXML_DEFAULT, (void**)&doc);
408 if (hr == S_OK)
410 VARIANT_BOOL b;
412 hr = IXMLDOMDocument_load(doc, input, &b);
413 if (hr == S_OK)
414 hr = IXMLDOMDocument_QueryInterface(doc, &IID_IXMLDOMNode, (void**)&input_node);
415 IXMLDOMDocument_Release(doc);
419 if (hr == S_OK)
421 if (This->input) IXMLDOMNode_Release(This->input);
422 This->input = input_node;
425 return hr;
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);
433 return E_NOTIMPL;
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);
443 return E_NOTIMPL;
446 static HRESULT WINAPI xslprocessor_setStartMode(
447 IXSLProcessor *iface,
448 BSTR p,
449 BSTR uri)
451 xslprocessor *This = impl_from_IXSLProcessor( iface );
453 FIXME("(%p)->(%s %s): stub\n", This, debugstr_w(p), debugstr_w(uri));
454 return E_NOTIMPL;
457 static HRESULT WINAPI xslprocessor_get_startMode(
458 IXSLProcessor *iface,
459 BSTR *p)
461 xslprocessor *This = impl_from_IXSLProcessor( iface );
463 FIXME("(%p)->(%p): stub\n", This, p);
464 return E_NOTIMPL;
467 static HRESULT WINAPI xslprocessor_get_startModeURI(
468 IXSLProcessor *iface,
469 BSTR *uri)
471 xslprocessor *This = impl_from_IXSLProcessor( iface );
473 FIXME("(%p)->(%p): stub\n", This, uri);
474 return E_NOTIMPL;
477 static HRESULT WINAPI xslprocessor_put_output(
478 IXSLProcessor *iface,
479 VARIANT var)
481 xslprocessor *This = impl_from_IXSLProcessor( iface );
482 enum output_type output_type = PROCESSOR_OUTPUT_NOT_SET;
483 IUnknown *output = NULL;
484 HRESULT hr = S_OK;
486 TRACE("(%p)->(%s)\n", This, debugstr_variant(&var));
488 switch (V_VT(&var))
490 case VT_EMPTY:
491 break;
492 case VT_UNKNOWN:
493 case VT_DISPATCH:
494 if (!V_UNKNOWN(&var))
495 break;
497 output_type = PROCESSOR_OUTPUT_STREAM;
498 hr = IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_IStream, (void **)&output);
499 if (FAILED(hr))
500 hr = IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_ISequentialStream, (void **)&output);
501 if (FAILED(hr))
503 output_type = PROCESSOR_OUTPUT_RESPONSE;
504 hr = IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_IResponse, (void **)&output);
506 if (FAILED(hr))
508 output_type = PROCESSOR_OUTPUT_PERSISTSTREAM;
509 hr = IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_IPersistStream, (void **)&output);
511 if (FAILED(hr))
512 hr = IUnknown_QueryInterface(V_UNKNOWN(&var), &IID_IPersistStreamInit, (void **)&output);
513 if (FAILED(hr))
515 output_type = PROCESSOR_OUTPUT_NOT_SET;
516 WARN("failed to get output interface, 0x%08x\n", hr);
518 break;
519 default:
520 FIXME("output type %d not handled\n", V_VT(&var));
521 hr = E_FAIL;
524 if (hr == S_OK)
526 if (This->output.unk)
527 IUnknown_Release(This->output.unk);
528 This->output.unk = output;
529 This->output_type = output_type;
532 return hr;
535 static HRESULT WINAPI xslprocessor_get_output(
536 IXSLProcessor *iface,
537 VARIANT *output)
539 xslprocessor *This = impl_from_IXSLProcessor( iface );
541 TRACE("(%p)->(%p)\n", This, output);
543 if (!output) return E_INVALIDARG;
545 if (This->output.unk)
547 V_VT(output) = VT_UNKNOWN;
548 V_UNKNOWN(output) = This->output.unk;
549 IUnknown_AddRef(This->output.unk);
551 else if (This->outstr)
553 V_VT(output) = VT_BSTR;
554 V_BSTR(output) = SysAllocString(This->outstr);
556 else
557 V_VT(output) = VT_EMPTY;
559 return S_OK;
562 static HRESULT WINAPI xslprocessor_transform(
563 IXSLProcessor *iface,
564 VARIANT_BOOL *ret)
566 #ifdef HAVE_LIBXML2
567 xslprocessor *This = impl_from_IXSLProcessor( iface );
568 ISequentialStream *stream = NULL;
569 HRESULT hr;
571 TRACE("(%p)->(%p)\n", This, ret);
573 if (!ret)
574 return E_INVALIDARG;
576 if (This->output_type == PROCESSOR_OUTPUT_STREAM)
578 stream = This->output.stream;
579 ISequentialStream_AddRef(stream);
581 else if (This->output_type == PROCESSOR_OUTPUT_PERSISTSTREAM ||
582 This->output_type == PROCESSOR_OUTPUT_RESPONSE)
584 if (FAILED(hr = CreateStreamOnHGlobal(NULL, TRUE, (IStream **)&stream)))
585 return hr;
588 SysFreeString(This->outstr);
590 hr = node_transform_node_params(get_node_obj(This->input), This->stylesheet->node,
591 &This->outstr, stream, &This->params);
592 if (SUCCEEDED(hr))
594 IStream *src = (IStream *)stream;
596 switch (This->output_type)
598 case PROCESSOR_OUTPUT_PERSISTSTREAM:
600 LARGE_INTEGER zero;
602 /* for IPersistStream* output seekable stream is used */
603 zero.QuadPart = 0;
604 IStream_Seek(src, zero, STREAM_SEEK_SET, NULL);
605 hr = IPersistStream_Load(This->output.persiststream, src);
606 break;
608 case PROCESSOR_OUTPUT_RESPONSE:
610 SAFEARRAYBOUND bound;
611 SAFEARRAY *array;
612 HGLOBAL hglobal;
613 VARIANT bin;
614 DWORD size;
615 void *dest;
617 if (FAILED(hr = GetHGlobalFromStream(src, &hglobal)))
618 break;
619 size = GlobalSize(hglobal);
621 bound.lLbound = 0;
622 bound.cElements = size;
623 if (!(array = SafeArrayCreate(VT_UI1, 1, &bound)))
624 break;
626 V_VT(&bin) = VT_ARRAY | VT_UI1;
627 V_ARRAY(&bin) = array;
629 hr = SafeArrayAccessData(array, &dest);
630 if (hr == S_OK)
632 void *data = GlobalLock(hglobal);
633 memcpy(dest, data, size);
634 GlobalUnlock(hglobal);
635 SafeArrayUnaccessData(array);
637 IResponse_BinaryWrite(This->output.response, bin);
640 VariantClear(&bin);
641 break;
643 default:
648 if (stream)
649 ISequentialStream_Release(stream);
651 *ret = hr == S_OK ? VARIANT_TRUE : VARIANT_FALSE;
652 return hr;
653 #else
654 FIXME("libxml2 is required but wasn't present at compile time\n");
655 return E_NOTIMPL;
656 #endif
659 static HRESULT WINAPI xslprocessor_reset( IXSLProcessor *iface )
661 xslprocessor *This = impl_from_IXSLProcessor( iface );
663 FIXME("(%p): stub\n", This);
664 return E_NOTIMPL;
667 static HRESULT WINAPI xslprocessor_get_readyState(
668 IXSLProcessor *iface,
669 LONG *state)
671 xslprocessor *This = impl_from_IXSLProcessor( iface );
673 FIXME("(%p)->(%p): stub\n", This, state);
674 return E_NOTIMPL;
677 static HRESULT xslprocessor_set_parvalue(const VARIANT *var, struct xslprocessor_par *par)
679 HRESULT hr = S_OK;
681 switch (V_VT(var))
683 case VT_BSTR:
685 par->value = SysAllocString(V_BSTR(var));
686 if (!par->value) hr = E_OUTOFMEMORY;
687 break;
689 default:
690 FIXME("value type %d not handled\n", V_VT(var));
691 hr = E_NOTIMPL;
694 return hr;
697 static HRESULT WINAPI xslprocessor_addParameter(
698 IXSLProcessor *iface,
699 BSTR p,
700 VARIANT var,
701 BSTR uri)
703 xslprocessor *This = impl_from_IXSLProcessor( iface );
704 struct xslprocessor_par *cur, *par = NULL;
705 HRESULT hr;
707 TRACE("(%p)->(%s %s %s)\n", This, debugstr_w(p), debugstr_variant(&var),
708 debugstr_w(uri));
710 if (uri && *uri)
711 FIXME("namespace uri is not supported\n");
713 /* search for existing parameter first */
714 LIST_FOR_EACH_ENTRY(cur, &This->params.list, struct xslprocessor_par, entry)
716 if (!strcmpW(cur->name, p))
718 par = cur;
719 break;
723 /* override with new value or add new parameter */
724 if (par)
726 if (V_VT(&var) == VT_NULL || V_VT(&var) == VT_EMPTY)
728 /* remove parameter */
729 xslprocessor_par_free(&This->params, par);
730 return S_OK;
732 SysFreeString(par->value);
733 par->value = NULL;
735 else
737 /* new parameter */
738 par = heap_alloc(sizeof(struct xslprocessor_par));
739 if (!par) return E_OUTOFMEMORY;
741 par->name = SysAllocString(p);
742 if (!par->name)
744 heap_free(par);
745 return E_OUTOFMEMORY;
747 list_add_tail(&This->params.list, &par->entry);
748 This->params.count++;
751 hr = xslprocessor_set_parvalue(&var, par);
752 if (FAILED(hr))
753 xslprocessor_par_free(&This->params, par);
755 return hr;
758 static HRESULT WINAPI xslprocessor_addObject(
759 IXSLProcessor *iface,
760 IDispatch *obj,
761 BSTR uri)
763 xslprocessor *This = impl_from_IXSLProcessor( iface );
765 FIXME("(%p)->(%p %s): stub\n", This, obj, debugstr_w(uri));
766 return E_NOTIMPL;
769 static HRESULT WINAPI xslprocessor_get_stylesheet(
770 IXSLProcessor *iface,
771 IXMLDOMNode **node)
773 xslprocessor *This = impl_from_IXSLProcessor( iface );
775 FIXME("(%p)->(%p): stub\n", This, node);
776 return E_NOTIMPL;
779 static const struct IXSLProcessorVtbl XSLProcessorVtbl =
781 xslprocessor_QueryInterface,
782 xslprocessor_AddRef,
783 xslprocessor_Release,
784 xslprocessor_GetTypeInfoCount,
785 xslprocessor_GetTypeInfo,
786 xslprocessor_GetIDsOfNames,
787 xslprocessor_Invoke,
788 xslprocessor_put_input,
789 xslprocessor_get_input,
790 xslprocessor_get_ownerTemplate,
791 xslprocessor_setStartMode,
792 xslprocessor_get_startMode,
793 xslprocessor_get_startModeURI,
794 xslprocessor_put_output,
795 xslprocessor_get_output,
796 xslprocessor_transform,
797 xslprocessor_reset,
798 xslprocessor_get_readyState,
799 xslprocessor_addParameter,
800 xslprocessor_addObject,
801 xslprocessor_get_stylesheet
804 static const tid_t xslprocessor_iface_tids[] = {
805 IXSLProcessor_tid,
809 static dispex_static_data_t xslprocessor_dispex = {
810 NULL,
811 IXSLProcessor_tid,
812 NULL,
813 xslprocessor_iface_tids
816 HRESULT XSLProcessor_create(xsltemplate *template, IXSLProcessor **ppObj)
818 xslprocessor *This;
820 TRACE("(%p)\n", ppObj);
822 This = heap_alloc( sizeof (*This) );
823 if(!This)
824 return E_OUTOFMEMORY;
826 This->IXSLProcessor_iface.lpVtbl = &XSLProcessorVtbl;
827 This->ref = 1;
828 This->input = NULL;
829 This->output.unk = NULL;
830 This->output_type = PROCESSOR_OUTPUT_NOT_SET;
831 This->outstr = NULL;
832 list_init(&This->params.list);
833 This->params.count = 0;
834 This->stylesheet = template;
835 IXSLTemplate_AddRef(&template->IXSLTemplate_iface);
836 init_dispex(&This->dispex, (IUnknown*)&This->IXSLProcessor_iface, &xslprocessor_dispex);
838 *ppObj = &This->IXSLProcessor_iface;
840 TRACE("returning iface %p\n", *ppObj);
842 return S_OK;