msxml3: Added ISAXContentHandler_startElement event.
[wine] / dlls / msxml3 / saxreader.c
1 /*
2  *    SAX Reader implementation
3  *
4  * Copyright 2008 Alistair Leslie-Hughes
5  * Copyright 2008 Piotr Caban
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 #define COBJMACROS
22
23 #include "config.h"
24
25 #include <stdarg.h>
26 #include <assert.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "winnls.h"
31 #include "ole2.h"
32 #include "msxml2.h"
33 #include "wininet.h"
34 #include "urlmon.h"
35 #include "winreg.h"
36 #include "shlwapi.h"
37
38 #include "wine/debug.h"
39
40 #include "msxml_private.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
43
44 #ifdef HAVE_LIBXML2
45
46 #include <libxml/SAX2.h>
47
48 typedef struct _saxreader
49 {
50     const struct IVBSAXXMLReaderVtbl *lpVtbl;
51     const struct ISAXXMLReaderVtbl *lpSAXXMLReaderVtbl;
52     LONG ref;
53     struct ISAXContentHandler *contentHandler;
54     struct ISAXErrorHandler *errorHandler;
55     xmlSAXHandler sax;
56 } saxreader;
57
58 typedef struct _saxlocator
59 {
60     const struct ISAXLocatorVtbl *lpSAXLocatorVtbl;
61     LONG ref;
62     saxreader *saxreader;
63     HRESULT ret;
64     xmlParserCtxtPtr pParserCtxt;
65     int lastLine;
66     int lastColumn;
67 } saxlocator;
68
69 static inline saxreader *impl_from_IVBSAXXMLReader( IVBSAXXMLReader *iface )
70 {
71     return (saxreader *)((char*)iface - FIELD_OFFSET(saxreader, lpVtbl));
72 }
73
74 static inline saxreader *impl_from_ISAXXMLReader( ISAXXMLReader *iface )
75 {
76     return (saxreader *)((char*)iface - FIELD_OFFSET(saxreader, lpSAXXMLReaderVtbl));
77 }
78
79 static inline saxlocator *impl_from_ISAXLocator( ISAXLocator *iface )
80 {
81     return (saxlocator *)((char*)iface - FIELD_OFFSET(saxlocator, lpSAXLocatorVtbl));
82 }
83
84 /*** LibXML callbacks ***/
85 static void libxmlStartDocument(void *ctx)
86 {
87     saxlocator *This = ctx;
88     HRESULT hr;
89
90     if(This->saxreader->contentHandler)
91     {
92         hr = ISAXContentHandler_startDocument(This->saxreader->contentHandler);
93         if(FAILED(hr))
94         {
95             xmlStopParser(This->pParserCtxt);
96             This->ret = hr;
97         }
98     }
99
100     This->lastColumn = xmlSAX2GetColumnNumber(This->pParserCtxt);
101     This->lastLine = xmlSAX2GetLineNumber(This->pParserCtxt);
102 }
103
104 static void libxmlEndDocument(void *ctx)
105 {
106     saxlocator *This = ctx;
107     HRESULT hr;
108
109     This->lastColumn = 0;
110     This->lastLine = 0;
111
112     if(This->saxreader->contentHandler)
113     {
114         hr = ISAXContentHandler_endDocument(This->saxreader->contentHandler);
115         if(FAILED(hr))
116         {
117             xmlStopParser(This->pParserCtxt);
118             This->ret = hr;
119         }
120     }
121 }
122
123 static void libxmlStartElementNS(
124         void *ctx,
125         const xmlChar *localname,
126         const xmlChar *prefix,
127         const xmlChar *URI,
128         int nb_namespaces,
129         const xmlChar **namespaces,
130         int nb_attributes,
131         int nb_defaulted,
132         const xmlChar **attributes)
133 {
134     BSTR NamespaceUri, LocalName, QName;
135     saxlocator *This = ctx;
136     HRESULT hr;
137
138     FIXME("Arguments processing not yet implemented.\n");
139
140     This->lastColumn = xmlSAX2GetColumnNumber(This->pParserCtxt)+1;
141     This->lastLine = xmlSAX2GetLineNumber(This->pParserCtxt);
142
143     if(This->saxreader->contentHandler)
144     {
145         NamespaceUri = bstr_from_xmlChar(URI);
146         LocalName = bstr_from_xmlChar(localname);
147         QName = bstr_from_xmlChar(localname);
148
149         hr = ISAXContentHandler_startElement(
150                 This->saxreader->contentHandler,
151                 NamespaceUri, SysStringLen(NamespaceUri),
152                 LocalName, SysStringLen(LocalName),
153                 QName, SysStringLen(QName),
154                 NULL);
155
156         SysFreeString(NamespaceUri);
157         SysFreeString(LocalName);
158         SysFreeString(QName);
159
160         if(FAILED(hr))
161         {
162             xmlStopParser(This->pParserCtxt);
163             This->ret = hr;
164         }
165     }
166 }
167
168 /*** ISAXLocator interface ***/
169 /*** IUnknown methods ***/
170 static HRESULT WINAPI isaxlocator_QueryInterface(ISAXLocator* iface, REFIID riid, void **ppvObject)
171 {
172     saxlocator *This = impl_from_ISAXLocator( iface );
173
174     TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
175
176     *ppvObject = NULL;
177
178     if ( IsEqualGUID( riid, &IID_IUnknown ) ||
179             IsEqualGUID( riid, &IID_ISAXLocator ))
180     {
181         *ppvObject = iface;
182     }
183     else
184     {
185         FIXME("interface %s not implemented\n", debugstr_guid(riid));
186         return E_NOINTERFACE;
187     }
188
189     ISAXLocator_AddRef( iface );
190
191     return S_OK;
192 }
193
194 static ULONG WINAPI isaxlocator_AddRef(ISAXLocator* iface)
195 {
196     saxlocator *This = impl_from_ISAXLocator( iface );
197     TRACE("%p\n", This );
198     return InterlockedIncrement( &This->ref );
199 }
200
201 static ULONG WINAPI isaxlocator_Release(
202         ISAXLocator* iface)
203 {
204     saxlocator *This = impl_from_ISAXLocator( iface );
205     LONG ref;
206
207     TRACE("%p\n", This );
208
209     ref = InterlockedDecrement( &This->ref );
210     if ( ref == 0 )
211     {
212         ISAXXMLReader_Release((ISAXXMLReader*)&This->saxreader->lpSAXXMLReaderVtbl);
213         HeapFree( GetProcessHeap(), 0, This );
214     }
215
216     return ref;
217 }
218
219 /*** ISAXLocator methods ***/
220 static HRESULT WINAPI isaxlocator_getColumnNumber(
221         ISAXLocator* iface,
222         int *pnColumn)
223 {
224     saxlocator *This = impl_from_ISAXLocator( iface );
225
226     *pnColumn = This->lastColumn;
227     return S_OK;
228 }
229
230 static HRESULT WINAPI isaxlocator_getLineNumber(
231         ISAXLocator* iface,
232         int *pnLine)
233 {
234     saxlocator *This = impl_from_ISAXLocator( iface );
235
236     *pnLine = This->lastLine;
237     return S_OK;
238 }
239
240 static HRESULT WINAPI isaxlocator_getPublicId(
241         ISAXLocator* iface,
242         const WCHAR ** ppwchPublicId)
243 {
244     saxlocator *This = impl_from_ISAXLocator( iface );
245
246     FIXME("(%p)->(%p) stub\n", This, ppwchPublicId);
247     return E_NOTIMPL;
248 }
249
250 static HRESULT WINAPI isaxlocator_getSystemId(
251         ISAXLocator* iface,
252         const WCHAR ** ppwchSystemId)
253 {
254     saxlocator *This = impl_from_ISAXLocator( iface );
255
256     FIXME("(%p)->(%p) stub\n", This, ppwchSystemId);
257     return E_NOTIMPL;
258 }
259
260 static const struct ISAXLocatorVtbl isaxlocator_vtbl =
261 {
262     isaxlocator_QueryInterface,
263     isaxlocator_AddRef,
264     isaxlocator_Release,
265     isaxlocator_getColumnNumber,
266     isaxlocator_getLineNumber,
267     isaxlocator_getPublicId,
268     isaxlocator_getSystemId
269 };
270
271 static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator)
272 {
273     saxlocator *locator;
274
275     locator = HeapAlloc( GetProcessHeap(), 0, sizeof (*locator) );
276     if( !locator )
277         return E_OUTOFMEMORY;
278
279     locator->lpSAXLocatorVtbl = &isaxlocator_vtbl;
280     locator->ref = 1;
281
282     locator->saxreader = reader;
283     ISAXXMLReader_AddRef((ISAXXMLReader*)&reader->lpSAXXMLReaderVtbl);
284
285     locator->pParserCtxt = NULL;
286     locator->lastLine = 0;
287     locator->lastColumn = 0;
288     locator->ret = S_OK;
289
290     *ppsaxlocator = locator;
291
292     TRACE("returning %p\n", *ppsaxlocator);
293
294     return S_OK;
295 }
296
297 /*** IVBSAXXMLReader interface ***/
298 /*** IUnknown methods ***/
299 static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject)
300 {
301     saxreader *This = impl_from_IVBSAXXMLReader( iface );
302
303     TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
304
305     *ppvObject = NULL;
306
307     if ( IsEqualGUID( riid, &IID_IUnknown ) ||
308          IsEqualGUID( riid, &IID_IDispatch ) ||
309          IsEqualGUID( riid, &IID_IVBSAXXMLReader ))
310     {
311         *ppvObject = iface;
312     }
313     else if( IsEqualGUID( riid, &IID_ISAXXMLReader ))
314     {
315         *ppvObject = (ISAXXMLReader*)&This->lpSAXXMLReaderVtbl;
316     }
317     else
318     {
319         FIXME("interface %s not implemented\n", debugstr_guid(riid));
320         return E_NOINTERFACE;
321     }
322
323     IVBSAXXMLReader_AddRef( iface );
324
325     return S_OK;
326 }
327
328 static ULONG WINAPI saxxmlreader_AddRef(IVBSAXXMLReader* iface)
329 {
330     saxreader *This = impl_from_IVBSAXXMLReader( iface );
331     TRACE("%p\n", This );
332     return InterlockedIncrement( &This->ref );
333 }
334
335 static ULONG WINAPI saxxmlreader_Release(
336     IVBSAXXMLReader* iface)
337 {
338     saxreader *This = impl_from_IVBSAXXMLReader( iface );
339     LONG ref;
340
341     TRACE("%p\n", This );
342
343     ref = InterlockedDecrement( &This->ref );
344     if ( ref == 0 )
345     {
346         if(This->contentHandler)
347             ISAXContentHandler_Release(This->contentHandler);
348
349         if(This->errorHandler)
350             ISAXErrorHandler_Release(This->errorHandler);
351
352         HeapFree( GetProcessHeap(), 0, This );
353     }
354
355     return ref;
356 }
357 /*** IDispatch ***/
358 static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo )
359 {
360     saxreader *This = impl_from_IVBSAXXMLReader( iface );
361
362     TRACE("(%p)->(%p)\n", This, pctinfo);
363
364     *pctinfo = 1;
365
366     return S_OK;
367 }
368
369 static HRESULT WINAPI saxxmlreader_GetTypeInfo(
370     IVBSAXXMLReader *iface,
371     UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
372 {
373     saxreader *This = impl_from_IVBSAXXMLReader( iface );
374     HRESULT hr;
375
376     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
377
378     hr = get_typeinfo(IVBSAXXMLReader_tid, ppTInfo);
379
380     return hr;
381 }
382
383 static HRESULT WINAPI saxxmlreader_GetIDsOfNames(
384     IVBSAXXMLReader *iface,
385     REFIID riid,
386     LPOLESTR* rgszNames,
387     UINT cNames,
388     LCID lcid,
389     DISPID* rgDispId)
390 {
391     saxreader *This = impl_from_IVBSAXXMLReader( iface );
392     ITypeInfo *typeinfo;
393     HRESULT hr;
394
395     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
396           lcid, rgDispId);
397
398     if(!rgszNames || cNames == 0 || !rgDispId)
399         return E_INVALIDARG;
400
401     hr = get_typeinfo(IVBSAXXMLReader_tid, &typeinfo);
402     if(SUCCEEDED(hr))
403     {
404         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
405         ITypeInfo_Release(typeinfo);
406     }
407
408     return hr;
409 }
410
411 static HRESULT WINAPI saxxmlreader_Invoke(
412     IVBSAXXMLReader *iface,
413     DISPID dispIdMember,
414     REFIID riid,
415     LCID lcid,
416     WORD wFlags,
417     DISPPARAMS* pDispParams,
418     VARIANT* pVarResult,
419     EXCEPINFO* pExcepInfo,
420     UINT* puArgErr)
421 {
422     saxreader *This = impl_from_IVBSAXXMLReader( iface );
423     ITypeInfo *typeinfo;
424     HRESULT hr;
425
426     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
427           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
428
429     hr = get_typeinfo(IVBSAXXMLReader_tid, &typeinfo);
430     if(SUCCEEDED(hr))
431     {
432         hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
433                 pVarResult, pExcepInfo, puArgErr);
434         ITypeInfo_Release(typeinfo);
435     }
436
437     return hr;
438 }
439
440 /*** IVBSAXXMLReader methods ***/
441 static HRESULT WINAPI saxxmlreader_getFeature(
442     IVBSAXXMLReader* iface,
443     const WCHAR *pFeature,
444     VARIANT_BOOL *pValue)
445 {
446     saxreader *This = impl_from_IVBSAXXMLReader( iface );
447
448     FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pFeature), pValue);
449     return E_NOTIMPL;
450 }
451
452 static HRESULT WINAPI saxxmlreader_putFeature(
453     IVBSAXXMLReader* iface,
454     const WCHAR *pFeature,
455     VARIANT_BOOL vfValue)
456 {
457     saxreader *This = impl_from_IVBSAXXMLReader( iface );
458
459     FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(pFeature), vfValue);
460     return E_NOTIMPL;
461 }
462
463 static HRESULT WINAPI saxxmlreader_getProperty(
464     IVBSAXXMLReader* iface,
465     const WCHAR *pProp,
466     VARIANT *pValue)
467 {
468     saxreader *This = impl_from_IVBSAXXMLReader( iface );
469
470     FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pProp), pValue);
471     return E_NOTIMPL;
472 }
473
474 static HRESULT WINAPI saxxmlreader_putProperty(
475     IVBSAXXMLReader* iface,
476     const WCHAR *pProp,
477     VARIANT value)
478 {
479     saxreader *This = impl_from_IVBSAXXMLReader( iface );
480
481     FIXME("(%p)->(%s) stub\n", This, debugstr_w(pProp));
482     return E_NOTIMPL;
483 }
484
485 static HRESULT WINAPI saxxmlreader_getEntityResolver(
486     IVBSAXXMLReader* iface,
487     IVBSAXEntityResolver **pEntityResolver)
488 {
489     saxreader *This = impl_from_IVBSAXXMLReader( iface );
490
491     FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
492     return E_NOTIMPL;
493 }
494
495 static HRESULT WINAPI saxxmlreader_putEntityResolver(
496     IVBSAXXMLReader* iface,
497     IVBSAXEntityResolver *pEntityResolver)
498 {
499     saxreader *This = impl_from_IVBSAXXMLReader( iface );
500
501     FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
502     return E_NOTIMPL;
503 }
504
505 static HRESULT WINAPI saxxmlreader_getContentHandler(
506     IVBSAXXMLReader* iface,
507     IVBSAXContentHandler **ppContentHandler)
508 {
509     saxreader *This = impl_from_IVBSAXXMLReader( iface );
510
511     FIXME("(%p)->(%p) stub\n", This, ppContentHandler);
512     return E_NOTIMPL;
513 }
514
515 static HRESULT WINAPI saxxmlreader_putContentHandler(
516     IVBSAXXMLReader* iface,
517     IVBSAXContentHandler *contentHandler)
518 {
519     saxreader *This = impl_from_IVBSAXXMLReader( iface );
520
521     FIXME("(%p)->(%p) stub\n", This, contentHandler);
522     return E_NOTIMPL;
523 }
524
525 static HRESULT WINAPI saxxmlreader_getDTDHandler(
526     IVBSAXXMLReader* iface,
527     IVBSAXDTDHandler **pDTDHandler)
528 {
529     saxreader *This = impl_from_IVBSAXXMLReader( iface );
530
531     FIXME("(%p)->(%p) stub\n", This, pDTDHandler);
532     return E_NOTIMPL;
533 }
534
535 static HRESULT WINAPI saxxmlreader_putDTDHandler(
536     IVBSAXXMLReader* iface,
537     IVBSAXDTDHandler *pDTDHandler)
538 {
539     saxreader *This = impl_from_IVBSAXXMLReader( iface );
540
541     FIXME("(%p)->(%p) stub\n", This, pDTDHandler);
542     return E_NOTIMPL;
543 }
544
545 static HRESULT WINAPI saxxmlreader_getErrorHandler(
546     IVBSAXXMLReader* iface,
547     IVBSAXErrorHandler **pErrorHandler)
548 {
549     saxreader *This = impl_from_IVBSAXXMLReader( iface );
550
551     FIXME("(%p)->(%p) stub\n", This, pErrorHandler);
552     return E_NOTIMPL;
553 }
554
555 static HRESULT WINAPI saxxmlreader_putErrorHandler(
556     IVBSAXXMLReader* iface,
557     IVBSAXErrorHandler *errorHandler)
558 {
559     saxreader *This = impl_from_IVBSAXXMLReader( iface );
560
561     FIXME("(%p)->(%p) stub\n", This, errorHandler);
562     return E_NOTIMPL;
563 }
564
565 static HRESULT WINAPI saxxmlreader_getBaseURL(
566     IVBSAXXMLReader* iface,
567     const WCHAR **pBaseUrl)
568 {
569     saxreader *This = impl_from_IVBSAXXMLReader( iface );
570
571     FIXME("(%p)->(%p) stub\n", This, pBaseUrl);
572     return E_NOTIMPL;
573 }
574
575 static HRESULT WINAPI saxxmlreader_putBaseURL(
576     IVBSAXXMLReader* iface,
577     const WCHAR *pBaseUrl)
578 {
579     saxreader *This = impl_from_IVBSAXXMLReader( iface );
580
581     FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl));
582     return E_NOTIMPL;
583 }
584
585 static HRESULT WINAPI saxxmlreader_getSecureBaseURL(
586     IVBSAXXMLReader* iface,
587     const WCHAR **pSecureBaseUrl)
588 {
589     saxreader *This = impl_from_IVBSAXXMLReader( iface );
590
591     FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
592     return E_NOTIMPL;
593 }
594
595
596 static HRESULT WINAPI saxxmlreader_putSecureBaseURL(
597     IVBSAXXMLReader* iface,
598     const WCHAR *secureBaseUrl)
599 {
600     saxreader *This = impl_from_IVBSAXXMLReader( iface );
601
602     FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl));
603     return E_NOTIMPL;
604 }
605
606 static HRESULT WINAPI saxxmlreader_parse(
607     IVBSAXXMLReader* iface,
608     VARIANT varInput)
609 {
610     saxreader *This = impl_from_IVBSAXXMLReader( iface );
611
612     FIXME("(%p) stub\n", This);
613     return E_NOTIMPL;
614 }
615
616 static HRESULT WINAPI saxxmlreader_parseURL(
617     IVBSAXXMLReader* iface,
618     const WCHAR *url)
619 {
620     saxreader *This = impl_from_IVBSAXXMLReader( iface );
621
622     FIXME("(%p)->(%s) stub\n", This, debugstr_w(url));
623     return E_NOTIMPL;
624 }
625
626 static const struct IVBSAXXMLReaderVtbl saxreader_vtbl =
627 {
628     saxxmlreader_QueryInterface,
629     saxxmlreader_AddRef,
630     saxxmlreader_Release,
631     saxxmlreader_GetTypeInfoCount,
632     saxxmlreader_GetTypeInfo,
633     saxxmlreader_GetIDsOfNames,
634     saxxmlreader_Invoke,
635     saxxmlreader_getFeature,
636     saxxmlreader_putFeature,
637     saxxmlreader_getProperty,
638     saxxmlreader_putProperty,
639     saxxmlreader_getEntityResolver,
640     saxxmlreader_putEntityResolver,
641     saxxmlreader_getContentHandler,
642     saxxmlreader_putContentHandler,
643     saxxmlreader_getDTDHandler,
644     saxxmlreader_putDTDHandler,
645     saxxmlreader_getErrorHandler,
646     saxxmlreader_putErrorHandler,
647     saxxmlreader_getBaseURL,
648     saxxmlreader_putBaseURL,
649     saxxmlreader_getSecureBaseURL,
650     saxxmlreader_putSecureBaseURL,
651     saxxmlreader_parse,
652     saxxmlreader_parseURL
653 };
654
655 /*** ISAXXMLReader interface ***/
656 /*** IUnknown methods ***/
657 static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject)
658 {
659     saxreader *This = impl_from_ISAXXMLReader( iface );
660     return saxxmlreader_QueryInterface((IVBSAXXMLReader*)&This->lpVtbl, riid, ppvObject);
661 }
662
663 static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface)
664 {
665     saxreader *This = impl_from_ISAXXMLReader( iface );
666     return saxxmlreader_AddRef((IVBSAXXMLReader*)&This->lpVtbl);
667 }
668
669 static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface)
670 {
671     saxreader *This = impl_from_ISAXXMLReader( iface );
672     return saxxmlreader_Release((IVBSAXXMLReader*)&This->lpVtbl);
673 }
674
675 /*** ISAXXMLReader methods ***/
676 static HRESULT WINAPI isaxxmlreader_getFeature(
677         ISAXXMLReader* iface,
678         const WCHAR *pFeature,
679         VARIANT_BOOL *pValue)
680 {
681     saxreader *This = impl_from_ISAXXMLReader( iface );
682
683     FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pFeature), pValue);
684     return E_NOTIMPL;
685 }
686
687 static HRESULT WINAPI isaxxmlreader_putFeature(
688         ISAXXMLReader* iface,
689         const WCHAR *pFeature,
690         VARIANT_BOOL vfValue)
691 {
692     saxreader *This = impl_from_ISAXXMLReader( iface );
693
694     FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(pFeature), vfValue);
695     return E_NOTIMPL;
696 }
697
698 static HRESULT WINAPI isaxxmlreader_getProperty(
699         ISAXXMLReader* iface,
700         const WCHAR *pProp,
701         VARIANT *pValue)
702 {
703     saxreader *This = impl_from_ISAXXMLReader( iface );
704
705     FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pProp), pValue);
706     return E_NOTIMPL;
707 }
708
709 static HRESULT WINAPI isaxxmlreader_putProperty(
710         ISAXXMLReader* iface,
711         const WCHAR *pProp,
712         VARIANT value)
713 {
714     saxreader *This = impl_from_ISAXXMLReader( iface );
715
716     FIXME("(%p)->(%s) stub\n", This, debugstr_w(pProp));
717     return E_NOTIMPL;
718 }
719
720 static HRESULT WINAPI isaxxmlreader_getEntityResolver(
721         ISAXXMLReader* iface,
722         ISAXEntityResolver **ppEntityResolver)
723 {
724     saxreader *This = impl_from_ISAXXMLReader( iface );
725
726     FIXME("(%p)->(%p) stub\n", This, ppEntityResolver);
727     return E_NOTIMPL;
728 }
729
730 static HRESULT WINAPI isaxxmlreader_putEntityResolver(
731         ISAXXMLReader* iface,
732         ISAXEntityResolver *pEntityResolver)
733 {
734     saxreader *This = impl_from_ISAXXMLReader( iface );
735
736     FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
737     return E_NOTIMPL;
738 }
739
740 static HRESULT WINAPI isaxxmlreader_getContentHandler(
741         ISAXXMLReader* iface,
742         ISAXContentHandler **pContentHandler)
743 {
744     saxreader *This = impl_from_ISAXXMLReader( iface );
745
746     TRACE("(%p)->(%p)\n", This, pContentHandler);
747     if(pContentHandler == NULL)
748         return E_POINTER;
749     if(This->contentHandler)
750         ISAXContentHandler_AddRef(This->contentHandler);
751     *pContentHandler = This->contentHandler;
752
753     return S_OK;
754 }
755
756 static HRESULT WINAPI isaxxmlreader_putContentHandler(
757         ISAXXMLReader* iface,
758         ISAXContentHandler *contentHandler)
759 {
760     saxreader *This = impl_from_ISAXXMLReader( iface );
761
762     TRACE("(%p)->(%p)\n", This, contentHandler);
763     if(contentHandler)
764         ISAXContentHandler_AddRef(contentHandler);
765     if(This->contentHandler)
766         ISAXContentHandler_Release(This->contentHandler);
767     This->contentHandler = contentHandler;
768
769     return S_OK;
770 }
771
772 static HRESULT WINAPI isaxxmlreader_getDTDHandler(
773         ISAXXMLReader* iface,
774         ISAXDTDHandler **pDTDHandler)
775 {
776     saxreader *This = impl_from_ISAXXMLReader( iface );
777
778     FIXME("(%p)->(%p) stub\n", This, pDTDHandler);
779     return E_NOTIMPL;
780 }
781
782 static HRESULT WINAPI isaxxmlreader_putDTDHandler(
783         ISAXXMLReader* iface,
784         ISAXDTDHandler *pDTDHandler)
785 {
786     saxreader *This = impl_from_ISAXXMLReader( iface );
787
788     FIXME("(%p)->(%p) stub\n", This, pDTDHandler);
789     return E_NOTIMPL;
790 }
791
792 static HRESULT WINAPI isaxxmlreader_getErrorHandler(
793         ISAXXMLReader* iface,
794         ISAXErrorHandler **pErrorHandler)
795 {
796     saxreader *This = impl_from_ISAXXMLReader( iface );
797
798     TRACE("(%p)->(%p)\n", This, pErrorHandler);
799     if(pErrorHandler == NULL)
800         return E_POINTER;
801     if(This->errorHandler)
802         ISAXErrorHandler_AddRef(This->errorHandler);
803     *pErrorHandler = This->errorHandler;
804
805     return S_OK;
806 }
807
808 static HRESULT WINAPI isaxxmlreader_putErrorHandler(
809         ISAXXMLReader* iface,
810         ISAXErrorHandler *errorHandler)
811 {
812     saxreader *This = impl_from_ISAXXMLReader( iface );
813
814     TRACE("(%p)->(%p)\n", This, errorHandler);
815     if(errorHandler)
816         ISAXErrorHandler_AddRef(errorHandler);
817     if(This->errorHandler)
818         ISAXErrorHandler_Release(This->errorHandler);
819     This->errorHandler = errorHandler;
820
821     return S_OK;
822 }
823
824 static HRESULT WINAPI isaxxmlreader_getBaseURL(
825         ISAXXMLReader* iface,
826         const WCHAR **pBaseUrl)
827 {
828     saxreader *This = impl_from_ISAXXMLReader( iface );
829
830     FIXME("(%p)->(%p) stub\n", This, pBaseUrl);
831     return E_NOTIMPL;
832 }
833
834 static HRESULT WINAPI isaxxmlreader_putBaseURL(
835         ISAXXMLReader* iface,
836         const WCHAR *pBaseUrl)
837 {
838     saxreader *This = impl_from_ISAXXMLReader( iface );
839
840     FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl));
841     return E_NOTIMPL;
842 }
843
844 static HRESULT WINAPI isaxxmlreader_getSecureBaseURL(
845         ISAXXMLReader* iface,
846         const WCHAR **pSecureBaseUrl)
847 {
848     saxreader *This = impl_from_ISAXXMLReader( iface );
849
850     FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
851     return E_NOTIMPL;
852 }
853
854 static HRESULT WINAPI isaxxmlreader_putSecureBaseURL(
855         ISAXXMLReader* iface,
856         const WCHAR *secureBaseUrl)
857 {
858     saxreader *This = impl_from_ISAXXMLReader( iface );
859
860     FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl));
861     return E_NOTIMPL;
862 }
863
864 static HRESULT WINAPI isaxxmlreader_parse(
865         ISAXXMLReader* iface,
866         VARIANT varInput)
867 {
868     saxreader *This = impl_from_ISAXXMLReader( iface );
869     saxlocator *locator;
870     xmlChar *data = NULL;
871     HRESULT hr;
872
873     FIXME("(%p) semi-stub\n", This);
874
875     hr = SAXLocator_create(This, &locator);
876     if(FAILED(hr))
877         return E_FAIL;
878
879     hr = S_OK;
880     switch(V_VT(&varInput))
881     {
882         case VT_BSTR:
883             locator->pParserCtxt = xmlNewParserCtxt();
884             if(!locator->pParserCtxt)
885             {
886                 hr = E_FAIL;
887                 break;
888             }
889             data = xmlChar_from_wchar(V_BSTR(&varInput));
890             xmlSetupParserForBuffer(locator->pParserCtxt, data, NULL);
891
892             locator->pParserCtxt->sax = &locator->saxreader->sax;
893             locator->pParserCtxt->userData = locator;
894
895             if(xmlParseDocument(locator->pParserCtxt)) hr = E_FAIL;
896             else hr = locator->ret;
897             break;
898         default:
899             hr = E_NOTIMPL;
900     }
901
902     if(locator->pParserCtxt)
903     {
904         locator->pParserCtxt->sax = NULL;
905         xmlFreeParserCtxt(locator->pParserCtxt);
906         locator->pParserCtxt = NULL;
907     }
908     if(data) HeapFree(GetProcessHeap(), 0, data);
909     ISAXLocator_Release((ISAXLocator*)&locator->lpSAXLocatorVtbl);
910     return hr;
911 }
912
913 static HRESULT WINAPI isaxxmlreader_parseURL(
914         ISAXXMLReader* iface,
915         const WCHAR *url)
916 {
917     saxreader *This = impl_from_ISAXXMLReader( iface );
918
919     FIXME("(%p)->(%s) stub\n", This, debugstr_w(url));
920     return E_NOTIMPL;
921 }
922
923 static const struct ISAXXMLReaderVtbl isaxreader_vtbl =
924 {
925     isaxxmlreader_QueryInterface,
926     isaxxmlreader_AddRef,
927     isaxxmlreader_Release,
928     isaxxmlreader_getFeature,
929     isaxxmlreader_putFeature,
930     isaxxmlreader_getProperty,
931     isaxxmlreader_putProperty,
932     isaxxmlreader_getEntityResolver,
933     isaxxmlreader_putEntityResolver,
934     isaxxmlreader_getContentHandler,
935     isaxxmlreader_putContentHandler,
936     isaxxmlreader_getDTDHandler,
937     isaxxmlreader_putDTDHandler,
938     isaxxmlreader_getErrorHandler,
939     isaxxmlreader_putErrorHandler,
940     isaxxmlreader_getBaseURL,
941     isaxxmlreader_putBaseURL,
942     isaxxmlreader_getSecureBaseURL,
943     isaxxmlreader_putSecureBaseURL,
944     isaxxmlreader_parse,
945     isaxxmlreader_parseURL
946 };
947
948 HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj)
949 {
950     saxreader *reader;
951
952     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
953
954     reader = HeapAlloc( GetProcessHeap(), 0, sizeof (*reader) );
955     if( !reader )
956         return E_OUTOFMEMORY;
957
958     reader->lpVtbl = &saxreader_vtbl;
959     reader->lpSAXXMLReaderVtbl = &isaxreader_vtbl;
960     reader->ref = 1;
961     reader->contentHandler = NULL;
962     reader->errorHandler = NULL;
963
964     memset(&reader->sax, 0, sizeof(xmlSAXHandler));
965     reader->sax.initialized = XML_SAX2_MAGIC;
966     reader->sax.startDocument = libxmlStartDocument;
967     reader->sax.endDocument = libxmlEndDocument;
968     reader->sax.startElementNs = libxmlStartElementNS;
969
970     *ppObj = &reader->lpVtbl;
971
972     TRACE("returning iface %p\n", *ppObj);
973
974     return S_OK;
975 }
976
977 #else
978
979 HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj)
980 {
981     MESSAGE("This program tried to use a SAX XML Reader object, but\n"
982             "libxml2 support was not present at compile time.\n");
983     return E_NOTIMPL;
984 }
985
986 #endif