msxml3: Added ISAXLocator_getLineNumber and ISAXLocator_getColumnNumber partial imple...
[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 /*** ISAXLocator interface ***/
105 /*** IUnknown methods ***/
106 static HRESULT WINAPI isaxlocator_QueryInterface(ISAXLocator* iface, REFIID riid, void **ppvObject)
107 {
108     saxlocator *This = impl_from_ISAXLocator( iface );
109
110     TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
111
112     *ppvObject = NULL;
113
114     if ( IsEqualGUID( riid, &IID_IUnknown ) ||
115             IsEqualGUID( riid, &IID_ISAXLocator ))
116     {
117         *ppvObject = iface;
118     }
119     else
120     {
121         FIXME("interface %s not implemented\n", debugstr_guid(riid));
122         return E_NOINTERFACE;
123     }
124
125     ISAXLocator_AddRef( iface );
126
127     return S_OK;
128 }
129
130 static ULONG WINAPI isaxlocator_AddRef(ISAXLocator* iface)
131 {
132     saxlocator *This = impl_from_ISAXLocator( iface );
133     TRACE("%p\n", This );
134     return InterlockedIncrement( &This->ref );
135 }
136
137 static ULONG WINAPI isaxlocator_Release(
138         ISAXLocator* iface)
139 {
140     saxlocator *This = impl_from_ISAXLocator( iface );
141     LONG ref;
142
143     TRACE("%p\n", This );
144
145     ref = InterlockedDecrement( &This->ref );
146     if ( ref == 0 )
147     {
148         ISAXXMLReader_Release((ISAXXMLReader*)&This->saxreader->lpSAXXMLReaderVtbl);
149         HeapFree( GetProcessHeap(), 0, This );
150     }
151
152     return ref;
153 }
154
155 /*** ISAXLocator methods ***/
156 static HRESULT WINAPI isaxlocator_getColumnNumber(
157         ISAXLocator* iface,
158         int *pnColumn)
159 {
160     saxlocator *This = impl_from_ISAXLocator( iface );
161
162     *pnColumn = This->lastColumn;
163     return S_OK;
164 }
165
166 static HRESULT WINAPI isaxlocator_getLineNumber(
167         ISAXLocator* iface,
168         int *pnLine)
169 {
170     saxlocator *This = impl_from_ISAXLocator( iface );
171
172     *pnLine = This->lastLine;
173     return S_OK;
174 }
175
176 static HRESULT WINAPI isaxlocator_getPublicId(
177         ISAXLocator* iface,
178         const WCHAR ** ppwchPublicId)
179 {
180     saxlocator *This = impl_from_ISAXLocator( iface );
181
182     FIXME("(%p)->(%p) stub\n", This, ppwchPublicId);
183     return E_NOTIMPL;
184 }
185
186 static HRESULT WINAPI isaxlocator_getSystemId(
187         ISAXLocator* iface,
188         const WCHAR ** ppwchSystemId)
189 {
190     saxlocator *This = impl_from_ISAXLocator( iface );
191
192     FIXME("(%p)->(%p) stub\n", This, ppwchSystemId);
193     return E_NOTIMPL;
194 }
195
196 static const struct ISAXLocatorVtbl isaxlocator_vtbl =
197 {
198     isaxlocator_QueryInterface,
199     isaxlocator_AddRef,
200     isaxlocator_Release,
201     isaxlocator_getColumnNumber,
202     isaxlocator_getLineNumber,
203     isaxlocator_getPublicId,
204     isaxlocator_getSystemId
205 };
206
207 static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator)
208 {
209     saxlocator *locator;
210
211     locator = HeapAlloc( GetProcessHeap(), 0, sizeof (*locator) );
212     if( !locator )
213         return E_OUTOFMEMORY;
214
215     locator->lpSAXLocatorVtbl = &isaxlocator_vtbl;
216     locator->ref = 1;
217
218     locator->saxreader = reader;
219     ISAXXMLReader_AddRef((ISAXXMLReader*)&reader->lpSAXXMLReaderVtbl);
220
221     locator->pParserCtxt = NULL;
222     locator->lastLine = 0;
223     locator->lastColumn = 0;
224     locator->ret = S_OK;
225
226     *ppsaxlocator = locator;
227
228     TRACE("returning %p\n", *ppsaxlocator);
229
230     return S_OK;
231 }
232
233 /*** IVBSAXXMLReader interface ***/
234 /*** IUnknown methods ***/
235 static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject)
236 {
237     saxreader *This = impl_from_IVBSAXXMLReader( iface );
238
239     TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
240
241     *ppvObject = NULL;
242
243     if ( IsEqualGUID( riid, &IID_IUnknown ) ||
244          IsEqualGUID( riid, &IID_IDispatch ) ||
245          IsEqualGUID( riid, &IID_IVBSAXXMLReader ))
246     {
247         *ppvObject = iface;
248     }
249     else if( IsEqualGUID( riid, &IID_ISAXXMLReader ))
250     {
251         *ppvObject = (ISAXXMLReader*)&This->lpSAXXMLReaderVtbl;
252     }
253     else
254     {
255         FIXME("interface %s not implemented\n", debugstr_guid(riid));
256         return E_NOINTERFACE;
257     }
258
259     IVBSAXXMLReader_AddRef( iface );
260
261     return S_OK;
262 }
263
264 static ULONG WINAPI saxxmlreader_AddRef(IVBSAXXMLReader* iface)
265 {
266     saxreader *This = impl_from_IVBSAXXMLReader( iface );
267     TRACE("%p\n", This );
268     return InterlockedIncrement( &This->ref );
269 }
270
271 static ULONG WINAPI saxxmlreader_Release(
272     IVBSAXXMLReader* iface)
273 {
274     saxreader *This = impl_from_IVBSAXXMLReader( iface );
275     LONG ref;
276
277     TRACE("%p\n", This );
278
279     ref = InterlockedDecrement( &This->ref );
280     if ( ref == 0 )
281     {
282         if(This->contentHandler)
283             ISAXContentHandler_Release(This->contentHandler);
284
285         if(This->errorHandler)
286             ISAXErrorHandler_Release(This->errorHandler);
287
288         HeapFree( GetProcessHeap(), 0, This );
289     }
290
291     return ref;
292 }
293 /*** IDispatch ***/
294 static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo )
295 {
296     saxreader *This = impl_from_IVBSAXXMLReader( iface );
297
298     TRACE("(%p)->(%p)\n", This, pctinfo);
299
300     *pctinfo = 1;
301
302     return S_OK;
303 }
304
305 static HRESULT WINAPI saxxmlreader_GetTypeInfo(
306     IVBSAXXMLReader *iface,
307     UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
308 {
309     saxreader *This = impl_from_IVBSAXXMLReader( iface );
310     HRESULT hr;
311
312     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
313
314     hr = get_typeinfo(IVBSAXXMLReader_tid, ppTInfo);
315
316     return hr;
317 }
318
319 static HRESULT WINAPI saxxmlreader_GetIDsOfNames(
320     IVBSAXXMLReader *iface,
321     REFIID riid,
322     LPOLESTR* rgszNames,
323     UINT cNames,
324     LCID lcid,
325     DISPID* rgDispId)
326 {
327     saxreader *This = impl_from_IVBSAXXMLReader( iface );
328     ITypeInfo *typeinfo;
329     HRESULT hr;
330
331     TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
332           lcid, rgDispId);
333
334     if(!rgszNames || cNames == 0 || !rgDispId)
335         return E_INVALIDARG;
336
337     hr = get_typeinfo(IVBSAXXMLReader_tid, &typeinfo);
338     if(SUCCEEDED(hr))
339     {
340         hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
341         ITypeInfo_Release(typeinfo);
342     }
343
344     return hr;
345 }
346
347 static HRESULT WINAPI saxxmlreader_Invoke(
348     IVBSAXXMLReader *iface,
349     DISPID dispIdMember,
350     REFIID riid,
351     LCID lcid,
352     WORD wFlags,
353     DISPPARAMS* pDispParams,
354     VARIANT* pVarResult,
355     EXCEPINFO* pExcepInfo,
356     UINT* puArgErr)
357 {
358     saxreader *This = impl_from_IVBSAXXMLReader( iface );
359     ITypeInfo *typeinfo;
360     HRESULT hr;
361
362     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
363           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
364
365     hr = get_typeinfo(IVBSAXXMLReader_tid, &typeinfo);
366     if(SUCCEEDED(hr))
367     {
368         hr = ITypeInfo_Invoke(typeinfo, &(This->lpVtbl), dispIdMember, wFlags, pDispParams,
369                 pVarResult, pExcepInfo, puArgErr);
370         ITypeInfo_Release(typeinfo);
371     }
372
373     return hr;
374 }
375
376 /*** IVBSAXXMLReader methods ***/
377 static HRESULT WINAPI saxxmlreader_getFeature(
378     IVBSAXXMLReader* iface,
379     const WCHAR *pFeature,
380     VARIANT_BOOL *pValue)
381 {
382     saxreader *This = impl_from_IVBSAXXMLReader( iface );
383
384     FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pFeature), pValue);
385     return E_NOTIMPL;
386 }
387
388 static HRESULT WINAPI saxxmlreader_putFeature(
389     IVBSAXXMLReader* iface,
390     const WCHAR *pFeature,
391     VARIANT_BOOL vfValue)
392 {
393     saxreader *This = impl_from_IVBSAXXMLReader( iface );
394
395     FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(pFeature), vfValue);
396     return E_NOTIMPL;
397 }
398
399 static HRESULT WINAPI saxxmlreader_getProperty(
400     IVBSAXXMLReader* iface,
401     const WCHAR *pProp,
402     VARIANT *pValue)
403 {
404     saxreader *This = impl_from_IVBSAXXMLReader( iface );
405
406     FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pProp), pValue);
407     return E_NOTIMPL;
408 }
409
410 static HRESULT WINAPI saxxmlreader_putProperty(
411     IVBSAXXMLReader* iface,
412     const WCHAR *pProp,
413     VARIANT value)
414 {
415     saxreader *This = impl_from_IVBSAXXMLReader( iface );
416
417     FIXME("(%p)->(%s) stub\n", This, debugstr_w(pProp));
418     return E_NOTIMPL;
419 }
420
421 static HRESULT WINAPI saxxmlreader_getEntityResolver(
422     IVBSAXXMLReader* iface,
423     IVBSAXEntityResolver **pEntityResolver)
424 {
425     saxreader *This = impl_from_IVBSAXXMLReader( iface );
426
427     FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
428     return E_NOTIMPL;
429 }
430
431 static HRESULT WINAPI saxxmlreader_putEntityResolver(
432     IVBSAXXMLReader* iface,
433     IVBSAXEntityResolver *pEntityResolver)
434 {
435     saxreader *This = impl_from_IVBSAXXMLReader( iface );
436
437     FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
438     return E_NOTIMPL;
439 }
440
441 static HRESULT WINAPI saxxmlreader_getContentHandler(
442     IVBSAXXMLReader* iface,
443     IVBSAXContentHandler **ppContentHandler)
444 {
445     saxreader *This = impl_from_IVBSAXXMLReader( iface );
446
447     FIXME("(%p)->(%p) stub\n", This, ppContentHandler);
448     return E_NOTIMPL;
449 }
450
451 static HRESULT WINAPI saxxmlreader_putContentHandler(
452     IVBSAXXMLReader* iface,
453     IVBSAXContentHandler *contentHandler)
454 {
455     saxreader *This = impl_from_IVBSAXXMLReader( iface );
456
457     FIXME("(%p)->(%p) stub\n", This, contentHandler);
458     return E_NOTIMPL;
459 }
460
461 static HRESULT WINAPI saxxmlreader_getDTDHandler(
462     IVBSAXXMLReader* iface,
463     IVBSAXDTDHandler **pDTDHandler)
464 {
465     saxreader *This = impl_from_IVBSAXXMLReader( iface );
466
467     FIXME("(%p)->(%p) stub\n", This, pDTDHandler);
468     return E_NOTIMPL;
469 }
470
471 static HRESULT WINAPI saxxmlreader_putDTDHandler(
472     IVBSAXXMLReader* iface,
473     IVBSAXDTDHandler *pDTDHandler)
474 {
475     saxreader *This = impl_from_IVBSAXXMLReader( iface );
476
477     FIXME("(%p)->(%p) stub\n", This, pDTDHandler);
478     return E_NOTIMPL;
479 }
480
481 static HRESULT WINAPI saxxmlreader_getErrorHandler(
482     IVBSAXXMLReader* iface,
483     IVBSAXErrorHandler **pErrorHandler)
484 {
485     saxreader *This = impl_from_IVBSAXXMLReader( iface );
486
487     FIXME("(%p)->(%p) stub\n", This, pErrorHandler);
488     return E_NOTIMPL;
489 }
490
491 static HRESULT WINAPI saxxmlreader_putErrorHandler(
492     IVBSAXXMLReader* iface,
493     IVBSAXErrorHandler *errorHandler)
494 {
495     saxreader *This = impl_from_IVBSAXXMLReader( iface );
496
497     FIXME("(%p)->(%p) stub\n", This, errorHandler);
498     return E_NOTIMPL;
499 }
500
501 static HRESULT WINAPI saxxmlreader_getBaseURL(
502     IVBSAXXMLReader* iface,
503     const WCHAR **pBaseUrl)
504 {
505     saxreader *This = impl_from_IVBSAXXMLReader( iface );
506
507     FIXME("(%p)->(%p) stub\n", This, pBaseUrl);
508     return E_NOTIMPL;
509 }
510
511 static HRESULT WINAPI saxxmlreader_putBaseURL(
512     IVBSAXXMLReader* iface,
513     const WCHAR *pBaseUrl)
514 {
515     saxreader *This = impl_from_IVBSAXXMLReader( iface );
516
517     FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl));
518     return E_NOTIMPL;
519 }
520
521 static HRESULT WINAPI saxxmlreader_getSecureBaseURL(
522     IVBSAXXMLReader* iface,
523     const WCHAR **pSecureBaseUrl)
524 {
525     saxreader *This = impl_from_IVBSAXXMLReader( iface );
526
527     FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
528     return E_NOTIMPL;
529 }
530
531
532 static HRESULT WINAPI saxxmlreader_putSecureBaseURL(
533     IVBSAXXMLReader* iface,
534     const WCHAR *secureBaseUrl)
535 {
536     saxreader *This = impl_from_IVBSAXXMLReader( iface );
537
538     FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl));
539     return E_NOTIMPL;
540 }
541
542 static HRESULT WINAPI saxxmlreader_parse(
543     IVBSAXXMLReader* iface,
544     VARIANT varInput)
545 {
546     saxreader *This = impl_from_IVBSAXXMLReader( iface );
547
548     FIXME("(%p) stub\n", This);
549     return E_NOTIMPL;
550 }
551
552 static HRESULT WINAPI saxxmlreader_parseURL(
553     IVBSAXXMLReader* iface,
554     const WCHAR *url)
555 {
556     saxreader *This = impl_from_IVBSAXXMLReader( iface );
557
558     FIXME("(%p)->(%s) stub\n", This, debugstr_w(url));
559     return E_NOTIMPL;
560 }
561
562 static const struct IVBSAXXMLReaderVtbl saxreader_vtbl =
563 {
564     saxxmlreader_QueryInterface,
565     saxxmlreader_AddRef,
566     saxxmlreader_Release,
567     saxxmlreader_GetTypeInfoCount,
568     saxxmlreader_GetTypeInfo,
569     saxxmlreader_GetIDsOfNames,
570     saxxmlreader_Invoke,
571     saxxmlreader_getFeature,
572     saxxmlreader_putFeature,
573     saxxmlreader_getProperty,
574     saxxmlreader_putProperty,
575     saxxmlreader_getEntityResolver,
576     saxxmlreader_putEntityResolver,
577     saxxmlreader_getContentHandler,
578     saxxmlreader_putContentHandler,
579     saxxmlreader_getDTDHandler,
580     saxxmlreader_putDTDHandler,
581     saxxmlreader_getErrorHandler,
582     saxxmlreader_putErrorHandler,
583     saxxmlreader_getBaseURL,
584     saxxmlreader_putBaseURL,
585     saxxmlreader_getSecureBaseURL,
586     saxxmlreader_putSecureBaseURL,
587     saxxmlreader_parse,
588     saxxmlreader_parseURL
589 };
590
591 /*** ISAXXMLReader interface ***/
592 /*** IUnknown methods ***/
593 static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject)
594 {
595     saxreader *This = impl_from_ISAXXMLReader( iface );
596     return saxxmlreader_QueryInterface((IVBSAXXMLReader*)&This->lpVtbl, riid, ppvObject);
597 }
598
599 static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface)
600 {
601     saxreader *This = impl_from_ISAXXMLReader( iface );
602     return saxxmlreader_AddRef((IVBSAXXMLReader*)&This->lpVtbl);
603 }
604
605 static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface)
606 {
607     saxreader *This = impl_from_ISAXXMLReader( iface );
608     return saxxmlreader_Release((IVBSAXXMLReader*)&This->lpVtbl);
609 }
610
611 /*** ISAXXMLReader methods ***/
612 static HRESULT WINAPI isaxxmlreader_getFeature(
613         ISAXXMLReader* iface,
614         const WCHAR *pFeature,
615         VARIANT_BOOL *pValue)
616 {
617     saxreader *This = impl_from_ISAXXMLReader( iface );
618
619     FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pFeature), pValue);
620     return E_NOTIMPL;
621 }
622
623 static HRESULT WINAPI isaxxmlreader_putFeature(
624         ISAXXMLReader* iface,
625         const WCHAR *pFeature,
626         VARIANT_BOOL vfValue)
627 {
628     saxreader *This = impl_from_ISAXXMLReader( iface );
629
630     FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(pFeature), vfValue);
631     return E_NOTIMPL;
632 }
633
634 static HRESULT WINAPI isaxxmlreader_getProperty(
635         ISAXXMLReader* iface,
636         const WCHAR *pProp,
637         VARIANT *pValue)
638 {
639     saxreader *This = impl_from_ISAXXMLReader( iface );
640
641     FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pProp), pValue);
642     return E_NOTIMPL;
643 }
644
645 static HRESULT WINAPI isaxxmlreader_putProperty(
646         ISAXXMLReader* iface,
647         const WCHAR *pProp,
648         VARIANT value)
649 {
650     saxreader *This = impl_from_ISAXXMLReader( iface );
651
652     FIXME("(%p)->(%s) stub\n", This, debugstr_w(pProp));
653     return E_NOTIMPL;
654 }
655
656 static HRESULT WINAPI isaxxmlreader_getEntityResolver(
657         ISAXXMLReader* iface,
658         ISAXEntityResolver **ppEntityResolver)
659 {
660     saxreader *This = impl_from_ISAXXMLReader( iface );
661
662     FIXME("(%p)->(%p) stub\n", This, ppEntityResolver);
663     return E_NOTIMPL;
664 }
665
666 static HRESULT WINAPI isaxxmlreader_putEntityResolver(
667         ISAXXMLReader* iface,
668         ISAXEntityResolver *pEntityResolver)
669 {
670     saxreader *This = impl_from_ISAXXMLReader( iface );
671
672     FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
673     return E_NOTIMPL;
674 }
675
676 static HRESULT WINAPI isaxxmlreader_getContentHandler(
677         ISAXXMLReader* iface,
678         ISAXContentHandler **pContentHandler)
679 {
680     saxreader *This = impl_from_ISAXXMLReader( iface );
681
682     TRACE("(%p)->(%p)\n", This, pContentHandler);
683     if(pContentHandler == NULL)
684         return E_POINTER;
685     if(This->contentHandler)
686         ISAXContentHandler_AddRef(This->contentHandler);
687     *pContentHandler = This->contentHandler;
688
689     return S_OK;
690 }
691
692 static HRESULT WINAPI isaxxmlreader_putContentHandler(
693         ISAXXMLReader* iface,
694         ISAXContentHandler *contentHandler)
695 {
696     saxreader *This = impl_from_ISAXXMLReader( iface );
697
698     TRACE("(%p)->(%p)\n", This, contentHandler);
699     if(contentHandler)
700         ISAXContentHandler_AddRef(contentHandler);
701     if(This->contentHandler)
702         ISAXContentHandler_Release(This->contentHandler);
703     This->contentHandler = contentHandler;
704
705     return S_OK;
706 }
707
708 static HRESULT WINAPI isaxxmlreader_getDTDHandler(
709         ISAXXMLReader* iface,
710         ISAXDTDHandler **pDTDHandler)
711 {
712     saxreader *This = impl_from_ISAXXMLReader( iface );
713
714     FIXME("(%p)->(%p) stub\n", This, pDTDHandler);
715     return E_NOTIMPL;
716 }
717
718 static HRESULT WINAPI isaxxmlreader_putDTDHandler(
719         ISAXXMLReader* iface,
720         ISAXDTDHandler *pDTDHandler)
721 {
722     saxreader *This = impl_from_ISAXXMLReader( iface );
723
724     FIXME("(%p)->(%p) stub\n", This, pDTDHandler);
725     return E_NOTIMPL;
726 }
727
728 static HRESULT WINAPI isaxxmlreader_getErrorHandler(
729         ISAXXMLReader* iface,
730         ISAXErrorHandler **pErrorHandler)
731 {
732     saxreader *This = impl_from_ISAXXMLReader( iface );
733
734     TRACE("(%p)->(%p)\n", This, pErrorHandler);
735     if(pErrorHandler == NULL)
736         return E_POINTER;
737     if(This->errorHandler)
738         ISAXErrorHandler_AddRef(This->errorHandler);
739     *pErrorHandler = This->errorHandler;
740
741     return S_OK;
742 }
743
744 static HRESULT WINAPI isaxxmlreader_putErrorHandler(
745         ISAXXMLReader* iface,
746         ISAXErrorHandler *errorHandler)
747 {
748     saxreader *This = impl_from_ISAXXMLReader( iface );
749
750     TRACE("(%p)->(%p)\n", This, errorHandler);
751     if(errorHandler)
752         ISAXErrorHandler_AddRef(errorHandler);
753     if(This->errorHandler)
754         ISAXErrorHandler_Release(This->errorHandler);
755     This->errorHandler = errorHandler;
756
757     return S_OK;
758 }
759
760 static HRESULT WINAPI isaxxmlreader_getBaseURL(
761         ISAXXMLReader* iface,
762         const WCHAR **pBaseUrl)
763 {
764     saxreader *This = impl_from_ISAXXMLReader( iface );
765
766     FIXME("(%p)->(%p) stub\n", This, pBaseUrl);
767     return E_NOTIMPL;
768 }
769
770 static HRESULT WINAPI isaxxmlreader_putBaseURL(
771         ISAXXMLReader* iface,
772         const WCHAR *pBaseUrl)
773 {
774     saxreader *This = impl_from_ISAXXMLReader( iface );
775
776     FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl));
777     return E_NOTIMPL;
778 }
779
780 static HRESULT WINAPI isaxxmlreader_getSecureBaseURL(
781         ISAXXMLReader* iface,
782         const WCHAR **pSecureBaseUrl)
783 {
784     saxreader *This = impl_from_ISAXXMLReader( iface );
785
786     FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
787     return E_NOTIMPL;
788 }
789
790 static HRESULT WINAPI isaxxmlreader_putSecureBaseURL(
791         ISAXXMLReader* iface,
792         const WCHAR *secureBaseUrl)
793 {
794     saxreader *This = impl_from_ISAXXMLReader( iface );
795
796     FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl));
797     return E_NOTIMPL;
798 }
799
800 static HRESULT WINAPI isaxxmlreader_parse(
801         ISAXXMLReader* iface,
802         VARIANT varInput)
803 {
804     saxreader *This = impl_from_ISAXXMLReader( iface );
805     saxlocator *locator;
806     xmlChar *data = NULL;
807     HRESULT hr;
808
809     FIXME("(%p) semi-stub\n", This);
810
811     hr = SAXLocator_create(This, &locator);
812     if(FAILED(hr))
813         return E_FAIL;
814
815     hr = S_OK;
816     switch(V_VT(&varInput))
817     {
818         case VT_BSTR:
819             locator->pParserCtxt = xmlNewParserCtxt();
820             if(!locator->pParserCtxt)
821             {
822                 hr = E_FAIL;
823                 break;
824             }
825             data = xmlChar_from_wchar(V_BSTR(&varInput));
826             xmlSetupParserForBuffer(locator->pParserCtxt, data, NULL);
827
828             locator->pParserCtxt->sax = &locator->saxreader->sax;
829             locator->pParserCtxt->userData = locator;
830
831             if(xmlParseDocument(locator->pParserCtxt)) hr = E_FAIL;
832             else hr = locator->ret;
833             break;
834         default:
835             hr = E_NOTIMPL;
836     }
837
838     if(locator->pParserCtxt)
839     {
840         locator->pParserCtxt->sax = NULL;
841         xmlFreeParserCtxt(locator->pParserCtxt);
842         locator->pParserCtxt = NULL;
843     }
844     if(data) HeapFree(GetProcessHeap(), 0, data);
845     ISAXLocator_Release((ISAXLocator*)&locator->lpSAXLocatorVtbl);
846     return hr;
847 }
848
849 static HRESULT WINAPI isaxxmlreader_parseURL(
850         ISAXXMLReader* iface,
851         const WCHAR *url)
852 {
853     saxreader *This = impl_from_ISAXXMLReader( iface );
854
855     FIXME("(%p)->(%s) stub\n", This, debugstr_w(url));
856     return E_NOTIMPL;
857 }
858
859 static const struct ISAXXMLReaderVtbl isaxreader_vtbl =
860 {
861     isaxxmlreader_QueryInterface,
862     isaxxmlreader_AddRef,
863     isaxxmlreader_Release,
864     isaxxmlreader_getFeature,
865     isaxxmlreader_putFeature,
866     isaxxmlreader_getProperty,
867     isaxxmlreader_putProperty,
868     isaxxmlreader_getEntityResolver,
869     isaxxmlreader_putEntityResolver,
870     isaxxmlreader_getContentHandler,
871     isaxxmlreader_putContentHandler,
872     isaxxmlreader_getDTDHandler,
873     isaxxmlreader_putDTDHandler,
874     isaxxmlreader_getErrorHandler,
875     isaxxmlreader_putErrorHandler,
876     isaxxmlreader_getBaseURL,
877     isaxxmlreader_putBaseURL,
878     isaxxmlreader_getSecureBaseURL,
879     isaxxmlreader_putSecureBaseURL,
880     isaxxmlreader_parse,
881     isaxxmlreader_parseURL
882 };
883
884 HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj)
885 {
886     saxreader *reader;
887
888     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
889
890     reader = HeapAlloc( GetProcessHeap(), 0, sizeof (*reader) );
891     if( !reader )
892         return E_OUTOFMEMORY;
893
894     reader->lpVtbl = &saxreader_vtbl;
895     reader->lpSAXXMLReaderVtbl = &isaxreader_vtbl;
896     reader->ref = 1;
897     reader->contentHandler = NULL;
898     reader->errorHandler = NULL;
899
900     memset(&reader->sax, 0, sizeof(xmlSAXHandler));
901     reader->sax.initialized = XML_SAX2_MAGIC;
902     reader->sax.startDocument = libxmlStartDocument;
903
904     *ppObj = &reader->lpVtbl;
905
906     TRACE("returning iface %p\n", *ppObj);
907
908     return S_OK;
909 }
910
911 #else
912
913 HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj)
914 {
915     MESSAGE("This program tried to use a SAX XML Reader object, but\n"
916             "libxml2 support was not present at compile time.\n");
917     return E_NOTIMPL;
918 }
919
920 #endif