90600eb5a080a4185e8132dcf9c2ef32d0b3c2bd
[reactos.git] / reactos / dll / win32 / 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 #include <libxml/parserInternals.h>
48
49 typedef struct _saxreader
50 {
51 const struct IVBSAXXMLReaderVtbl *lpVBSAXXMLReaderVtbl;
52 const struct ISAXXMLReaderVtbl *lpSAXXMLReaderVtbl;
53 LONG ref;
54 struct ISAXContentHandler *contentHandler;
55 struct IVBSAXContentHandler *vbcontentHandler;
56 struct ISAXErrorHandler *errorHandler;
57 struct IVBSAXErrorHandler *vberrorHandler;
58 struct ISAXLexicalHandler *lexicalHandler;
59 struct IVBSAXLexicalHandler *vblexicalHandler;
60 struct ISAXDeclHandler *declHandler;
61 struct IVBSAXDeclHandler *vbdeclHandler;
62 xmlSAXHandler sax;
63 BOOL isParsing;
64 } saxreader;
65
66 typedef struct _saxlocator
67 {
68 const struct IVBSAXLocatorVtbl *lpVBSAXLocatorVtbl;
69 const struct ISAXLocatorVtbl *lpSAXLocatorVtbl;
70 LONG ref;
71 saxreader *saxreader;
72 HRESULT ret;
73 xmlParserCtxtPtr pParserCtxt;
74 WCHAR *publicId;
75 WCHAR *systemId;
76 xmlChar *lastCur;
77 int line;
78 int realLine;
79 int column;
80 int realColumn;
81 BOOL vbInterface;
82 int nsStackSize;
83 int nsStackLast;
84 int *nsStack;
85 } saxlocator;
86
87 typedef struct _saxattributes
88 {
89 const struct IVBSAXAttributesVtbl *lpVBSAXAttributesVtbl;
90 const struct ISAXAttributesVtbl *lpSAXAttributesVtbl;
91 LONG ref;
92 int nb_attributes;
93 BSTR *szLocalname;
94 BSTR *szURI;
95 BSTR *szValue;
96 BSTR *szQName;
97 } saxattributes;
98
99 static inline saxreader *impl_from_IVBSAXXMLReader( IVBSAXXMLReader *iface )
100 {
101 return (saxreader *)((char*)iface - FIELD_OFFSET(saxreader, lpVBSAXXMLReaderVtbl));
102 }
103
104 static inline saxreader *impl_from_ISAXXMLReader( ISAXXMLReader *iface )
105 {
106 return (saxreader *)((char*)iface - FIELD_OFFSET(saxreader, lpSAXXMLReaderVtbl));
107 }
108
109 static inline saxlocator *impl_from_IVBSAXLocator( IVBSAXLocator *iface )
110 {
111 return (saxlocator *)((char*)iface - FIELD_OFFSET(saxlocator, lpVBSAXLocatorVtbl));
112 }
113
114 static inline saxlocator *impl_from_ISAXLocator( ISAXLocator *iface )
115 {
116 return (saxlocator *)((char*)iface - FIELD_OFFSET(saxlocator, lpSAXLocatorVtbl));
117 }
118
119 static inline saxattributes *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
120 {
121 return (saxattributes *)((char*)iface - FIELD_OFFSET(saxattributes, lpVBSAXAttributesVtbl));
122 }
123
124 static inline saxattributes *impl_from_ISAXAttributes( ISAXAttributes *iface )
125 {
126 return (saxattributes *)((char*)iface - FIELD_OFFSET(saxattributes, lpSAXAttributesVtbl));
127 }
128
129
130 static HRESULT namespacePush(saxlocator *locator, int ns)
131 {
132 if(locator->nsStackLast>=locator->nsStackSize)
133 {
134 int *new_stack;
135
136 new_stack = HeapReAlloc(GetProcessHeap(), 0,
137 locator->nsStack, locator->nsStackSize*2);
138 if(!new_stack) return E_OUTOFMEMORY;
139 locator->nsStack = new_stack;
140 locator->nsStackSize *= 2;
141 }
142 locator->nsStack[locator->nsStackLast++] = ns;
143
144 return S_OK;
145 }
146
147 static int namespacePop(saxlocator *locator)
148 {
149 if(locator->nsStackLast == 0) return 0;
150 return locator->nsStack[--locator->nsStackLast];
151 }
152
153 static BSTR bstr_from_xmlCharN(const xmlChar *buf, int len)
154 {
155 DWORD dLen;
156 LPWSTR str;
157 BSTR bstr;
158
159 if (!buf)
160 return NULL;
161
162 dLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0);
163 if(len != -1) dLen++;
164 str = HeapAlloc(GetProcessHeap(), 0, dLen * sizeof (WCHAR));
165 if (!str)
166 return NULL;
167 MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, str, dLen);
168 if(len != -1) str[dLen-1] = '\0';
169 bstr = SysAllocString(str);
170 HeapFree(GetProcessHeap(), 0, str);
171
172 return bstr;
173 }
174
175 static BSTR QName_from_xmlChar(const xmlChar *prefix, const xmlChar *name)
176 {
177 DWORD dLen, dLast;
178 LPWSTR str;
179 BSTR bstr;
180
181 if(!name) return NULL;
182
183 if(!prefix || *prefix=='\0')
184 return bstr_from_xmlChar(name);
185
186 dLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)prefix, -1, NULL, 0)
187 + MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)name, -1, NULL, 0);
188 str = HeapAlloc(GetProcessHeap(), 0, dLen * sizeof(WCHAR));
189 if(!str)
190 return NULL;
191
192 dLast = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)prefix, -1, str, dLen);
193 str[dLast-1] = ':';
194 MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)name, -1, &str[dLast], dLen-dLast);
195 bstr = SysAllocString(str);
196
197 HeapFree(GetProcessHeap(), 0, str);
198
199 return bstr;
200 }
201
202 static void format_error_message_from_id(saxlocator *This, HRESULT hr)
203 {
204 xmlStopParser(This->pParserCtxt);
205 This->ret = hr;
206
207 if((This->vbInterface && This->saxreader->vberrorHandler)
208 || (!This->vbInterface && This->saxreader->errorHandler))
209 {
210 WCHAR msg[1024];
211 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
212 NULL, hr, 0, msg, sizeof(msg), NULL))
213 {
214 FIXME("MSXML errors not yet supported.\n");
215 msg[0] = '\0';
216 }
217
218 if(This->vbInterface)
219 {
220 BSTR bstrMsg = SysAllocString(msg);
221 IVBSAXErrorHandler_fatalError(This->saxreader->vberrorHandler,
222 (IVBSAXLocator*)&This->lpVBSAXLocatorVtbl, &bstrMsg, hr);
223 }
224 else
225 ISAXErrorHandler_fatalError(This->saxreader->errorHandler,
226 (ISAXLocator*)&This->lpSAXLocatorVtbl, msg, hr);
227 }
228 }
229
230 static void update_position(saxlocator *This, xmlChar *end)
231 {
232 if(This->lastCur == NULL)
233 {
234 This->lastCur = (xmlChar*)This->pParserCtxt->input->base;
235 This->realLine = 1;
236 This->realColumn = 1;
237 }
238 else if(This->lastCur < This->pParserCtxt->input->base)
239 {
240 This->lastCur = (xmlChar*)This->pParserCtxt->input->base;
241 This->realLine = 1;
242 This->realColumn = 1;
243 }
244
245 if(This->pParserCtxt->input->cur<This->lastCur)
246 {
247 This->lastCur = (xmlChar*)This->pParserCtxt->input->base;
248 This->realLine -= 1;
249 This->realColumn = 1;
250 }
251
252 if(!end) end = (xmlChar*)This->pParserCtxt->input->cur;
253
254 while(This->lastCur < end)
255 {
256 if(*(This->lastCur) == '\n')
257 {
258 This->realLine++;
259 This->realColumn = 1;
260 }
261 else if(*(This->lastCur) == '\r' &&
262 (This->lastCur==This->pParserCtxt->input->end ||
263 *(This->lastCur+1)!='\n'))
264 {
265 This->realLine++;
266 This->realColumn = 1;
267 }
268 else This->realColumn++;
269
270 This->lastCur++;
271
272 /* Count multibyte UTF8 encoded characters once */
273 while((*(This->lastCur)&0xC0) == 0x80) This->lastCur++;
274 }
275
276 This->line = This->realLine;
277 This->column = This->realColumn;
278 }
279
280 /*** IVBSAXAttributes interface ***/
281 /*** IUnknown methods ***/
282 static HRESULT WINAPI ivbsaxattributes_QueryInterface(
283 IVBSAXAttributes* iface,
284 REFIID riid,
285 void **ppvObject)
286 {
287 saxattributes *This = impl_from_IVBSAXAttributes(iface);
288
289 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
290
291 *ppvObject = NULL;
292
293 if (IsEqualGUID(riid, &IID_IUnknown) ||
294 IsEqualGUID(riid, &IID_IDispatch) ||
295 IsEqualGUID(riid, &IID_IVBSAXAttributes))
296 {
297 *ppvObject = iface;
298 }
299 else
300 {
301 FIXME("interface %s not implemented\n", debugstr_guid(riid));
302 return E_NOINTERFACE;
303 }
304
305 IVBSAXAttributes_AddRef(iface);
306
307 return S_OK;
308 }
309
310 static ULONG WINAPI ivbsaxattributes_AddRef(IVBSAXAttributes* iface)
311 {
312 saxattributes *This = impl_from_IVBSAXAttributes(iface);
313 return ISAXAttributes_AddRef((ISAXAttributes*)&This->lpSAXAttributesVtbl);
314 }
315
316 static ULONG WINAPI ivbsaxattributes_Release(IVBSAXAttributes* iface)
317 {
318 saxattributes *This = impl_from_IVBSAXAttributes(iface);
319 return ISAXAttributes_Release((ISAXAttributes*)&This->lpSAXAttributesVtbl);
320 }
321
322 /*** IDispatch methods ***/
323 static HRESULT WINAPI ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
324 {
325 saxattributes *This = impl_from_IVBSAXAttributes( iface );
326
327 TRACE("(%p)->(%p)\n", This, pctinfo);
328
329 *pctinfo = 1;
330
331 return S_OK;
332 }
333
334 static HRESULT WINAPI ivbsaxattributes_GetTypeInfo(
335 IVBSAXAttributes *iface,
336 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
337 {
338 saxattributes *This = impl_from_IVBSAXAttributes( iface );
339 HRESULT hr;
340
341 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
342
343 hr = get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
344
345 return hr;
346 }
347
348 static HRESULT WINAPI ivbsaxattributes_GetIDsOfNames(
349 IVBSAXAttributes *iface,
350 REFIID riid,
351 LPOLESTR* rgszNames,
352 UINT cNames,
353 LCID lcid,
354 DISPID* rgDispId)
355 {
356 saxattributes *This = impl_from_IVBSAXAttributes( iface );
357 ITypeInfo *typeinfo;
358 HRESULT hr;
359
360 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
361 lcid, rgDispId);
362
363 if(!rgszNames || cNames == 0 || !rgDispId)
364 return E_INVALIDARG;
365
366 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
367 if(SUCCEEDED(hr))
368 {
369 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
370 ITypeInfo_Release(typeinfo);
371 }
372
373 return hr;
374 }
375
376 static HRESULT WINAPI ivbsaxattributes_Invoke(
377 IVBSAXAttributes *iface,
378 DISPID dispIdMember,
379 REFIID riid,
380 LCID lcid,
381 WORD wFlags,
382 DISPPARAMS* pDispParams,
383 VARIANT* pVarResult,
384 EXCEPINFO* pExcepInfo,
385 UINT* puArgErr)
386 {
387 saxattributes *This = impl_from_IVBSAXAttributes( iface );
388 ITypeInfo *typeinfo;
389 HRESULT hr;
390
391 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
392 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
393
394 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
395 if(SUCCEEDED(hr))
396 {
397 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVBSAXAttributesVtbl), dispIdMember, wFlags, pDispParams,
398 pVarResult, pExcepInfo, puArgErr);
399 ITypeInfo_Release(typeinfo);
400 }
401
402 return hr;
403 }
404
405 /*** IVBSAXAttributes methods ***/
406 static HRESULT WINAPI ivbsaxattributes_get_length(
407 IVBSAXAttributes* iface,
408 int *nLength)
409 {
410 saxattributes *This = impl_from_IVBSAXAttributes( iface );
411 return ISAXAttributes_getLength(
412 (ISAXAttributes*)&This->lpSAXAttributesVtbl,
413 nLength);
414 }
415
416 static HRESULT WINAPI ivbsaxattributes_getURI(
417 IVBSAXAttributes* iface,
418 int nIndex,
419 BSTR *uri)
420 {
421 int len;
422 saxattributes *This = impl_from_IVBSAXAttributes( iface );
423 return ISAXAttributes_getURI(
424 (ISAXAttributes*)&This->lpSAXAttributesVtbl,
425 nIndex, (const WCHAR**)uri, &len);
426 }
427
428 static HRESULT WINAPI ivbsaxattributes_getLocalName(
429 IVBSAXAttributes* iface,
430 int nIndex,
431 BSTR *localName)
432 {
433 int len;
434 saxattributes *This = impl_from_IVBSAXAttributes( iface );
435 return ISAXAttributes_getLocalName(
436 (ISAXAttributes*)&This->lpSAXAttributesVtbl,
437 nIndex, (const WCHAR**)localName, &len);
438 }
439
440 static HRESULT WINAPI ivbsaxattributes_getQName(
441 IVBSAXAttributes* iface,
442 int nIndex,
443 BSTR *QName)
444 {
445 int len;
446 saxattributes *This = impl_from_IVBSAXAttributes( iface );
447 return ISAXAttributes_getQName(
448 (ISAXAttributes*)&This->lpSAXAttributesVtbl,
449 nIndex, (const WCHAR**)QName, &len);
450 }
451
452 static HRESULT WINAPI ivbsaxattributes_getIndexFromName(
453 IVBSAXAttributes* iface,
454 BSTR uri,
455 BSTR localName,
456 int *index)
457 {
458 saxattributes *This = impl_from_IVBSAXAttributes( iface );
459 return ISAXAttributes_getIndexFromName(
460 (ISAXAttributes*)&This->lpSAXAttributesVtbl, uri, SysStringLen(uri),
461 localName, SysStringLen(localName), index);
462 }
463
464 static HRESULT WINAPI ivbsaxattributes_getIndexFromQName(
465 IVBSAXAttributes* iface,
466 BSTR QName,
467 int *index)
468 {
469 saxattributes *This = impl_from_IVBSAXAttributes( iface );
470 return ISAXAttributes_getIndexFromQName(
471 (ISAXAttributes*)&This->lpSAXAttributesVtbl, QName,
472 SysStringLen(QName), index);
473 }
474
475 static HRESULT WINAPI ivbsaxattributes_getType(
476 IVBSAXAttributes* iface,
477 int nIndex,
478 BSTR *type)
479 {
480 int len;
481 saxattributes *This = impl_from_IVBSAXAttributes( iface );
482 return ISAXAttributes_getType(
483 (ISAXAttributes*)&This->lpSAXAttributesVtbl,
484 nIndex, (const WCHAR**)type, &len);
485 }
486
487 static HRESULT WINAPI ivbsaxattributes_getTypeFromName(
488 IVBSAXAttributes* iface,
489 BSTR uri,
490 BSTR localName,
491 BSTR *type)
492 {
493 int len;
494 saxattributes *This = impl_from_IVBSAXAttributes( iface );
495 return ISAXAttributes_getTypeFromName(
496 (ISAXAttributes*)&This->lpSAXAttributesVtbl, uri, SysStringLen(uri),
497 localName, SysStringLen(localName), (const WCHAR**)type, &len);
498 }
499
500 static HRESULT WINAPI ivbsaxattributes_getTypeFromQName(
501 IVBSAXAttributes* iface,
502 BSTR QName,
503 BSTR *type)
504 {
505 int len;
506 saxattributes *This = impl_from_IVBSAXAttributes( iface );
507 return ISAXAttributes_getTypeFromQName(
508 (ISAXAttributes*)&This->lpSAXAttributesVtbl, QName,
509 SysStringLen(QName), (const WCHAR**)type, &len);
510 }
511
512 static HRESULT WINAPI ivbsaxattributes_getValue(
513 IVBSAXAttributes* iface,
514 int nIndex,
515 BSTR *value)
516 {
517 int len;
518 saxattributes *This = impl_from_IVBSAXAttributes( iface );
519 return ISAXAttributes_getValue(
520 (ISAXAttributes*)&This->lpSAXAttributesVtbl,
521 nIndex, (const WCHAR**)value, &len);
522 }
523
524 static HRESULT WINAPI ivbsaxattributes_getValueFromName(
525 IVBSAXAttributes* iface,
526 BSTR uri,
527 BSTR localName,
528 BSTR *value)
529 {
530 int len;
531 saxattributes *This = impl_from_IVBSAXAttributes( iface );
532 return ISAXAttributes_getValueFromName(
533 (ISAXAttributes*)&This->lpSAXAttributesVtbl, uri, SysStringLen(uri),
534 localName, SysStringLen(localName), (const WCHAR**)value, &len);
535 }
536
537 static HRESULT WINAPI ivbsaxattributes_getValueFromQName(
538 IVBSAXAttributes* iface,
539 BSTR QName,
540 BSTR *value)
541 {
542 int len;
543 saxattributes *This = impl_from_IVBSAXAttributes( iface );
544 return ISAXAttributes_getValueFromQName(
545 (ISAXAttributes*)&This->lpSAXAttributesVtbl, QName,
546 SysStringLen(QName), (const WCHAR**)value, &len);
547 }
548
549 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl =
550 {
551 ivbsaxattributes_QueryInterface,
552 ivbsaxattributes_AddRef,
553 ivbsaxattributes_Release,
554 ivbsaxattributes_GetTypeInfoCount,
555 ivbsaxattributes_GetTypeInfo,
556 ivbsaxattributes_GetIDsOfNames,
557 ivbsaxattributes_Invoke,
558 ivbsaxattributes_get_length,
559 ivbsaxattributes_getURI,
560 ivbsaxattributes_getLocalName,
561 ivbsaxattributes_getQName,
562 ivbsaxattributes_getIndexFromName,
563 ivbsaxattributes_getIndexFromQName,
564 ivbsaxattributes_getType,
565 ivbsaxattributes_getTypeFromName,
566 ivbsaxattributes_getTypeFromQName,
567 ivbsaxattributes_getValue,
568 ivbsaxattributes_getValueFromName,
569 ivbsaxattributes_getValueFromQName
570 };
571
572 /*** ISAXAttributes interface ***/
573 /*** IUnknown methods ***/
574 static HRESULT WINAPI isaxattributes_QueryInterface(
575 ISAXAttributes* iface,
576 REFIID riid,
577 void **ppvObject)
578 {
579 saxattributes *This = impl_from_ISAXAttributes(iface);
580
581 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
582
583 *ppvObject = NULL;
584
585 if (IsEqualGUID(riid, &IID_IUnknown) ||
586 IsEqualGUID(riid, &IID_ISAXAttributes))
587 {
588 *ppvObject = iface;
589 }
590 else
591 {
592 FIXME("interface %s not implemented\n", debugstr_guid(riid));
593 return E_NOINTERFACE;
594 }
595
596 ISAXAttributes_AddRef(iface);
597
598 return S_OK;
599 }
600
601 static ULONG WINAPI isaxattributes_AddRef(ISAXAttributes* iface)
602 {
603 saxattributes *This = impl_from_ISAXAttributes(iface);
604 TRACE("%p\n", This);
605 return InterlockedIncrement(&This->ref);
606 }
607
608 static ULONG WINAPI isaxattributes_Release(ISAXAttributes* iface)
609 {
610 saxattributes *This = impl_from_ISAXAttributes(iface);
611 LONG ref;
612
613 TRACE("%p\n", This);
614
615 ref = InterlockedDecrement(&This->ref);
616 if (ref==0)
617 {
618 int index;
619 for(index=0; index<This->nb_attributes; index++)
620 {
621 SysFreeString(This->szLocalname[index]);
622 SysFreeString(This->szURI[index]);
623 SysFreeString(This->szValue[index]);
624 SysFreeString(This->szQName[index]);
625 }
626
627 HeapFree(GetProcessHeap(), 0, This->szLocalname);
628 HeapFree(GetProcessHeap(), 0, This->szURI);
629 HeapFree(GetProcessHeap(), 0, This->szValue);
630 HeapFree(GetProcessHeap(), 0, This->szQName);
631
632 HeapFree(GetProcessHeap(), 0, This);
633 }
634
635 return ref;
636 }
637
638 /*** ISAXAttributes methods ***/
639 static HRESULT WINAPI isaxattributes_getLength(
640 ISAXAttributes* iface,
641 int *length)
642 {
643 saxattributes *This = impl_from_ISAXAttributes( iface );
644
645 *length = This->nb_attributes;
646 TRACE("Length set to %d\n", *length);
647 return S_OK;
648 }
649
650 static HRESULT WINAPI isaxattributes_getURI(
651 ISAXAttributes* iface,
652 int nIndex,
653 const WCHAR **pUrl,
654 int *pUriSize)
655 {
656 saxattributes *This = impl_from_ISAXAttributes( iface );
657 TRACE("(%p)->(%d)\n", This, nIndex);
658
659 if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
660 if(!pUrl || !pUriSize) return E_POINTER;
661
662 *pUriSize = SysStringLen(This->szURI[nIndex]);
663 *pUrl = This->szURI[nIndex];
664
665 return S_OK;
666 }
667
668 static HRESULT WINAPI isaxattributes_getLocalName(
669 ISAXAttributes* iface,
670 int nIndex,
671 const WCHAR **pLocalName,
672 int *pLocalNameLength)
673 {
674 saxattributes *This = impl_from_ISAXAttributes( iface );
675 TRACE("(%p)->(%d)\n", This, nIndex);
676
677 if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
678 if(!pLocalName || !pLocalNameLength) return E_POINTER;
679
680 *pLocalNameLength = SysStringLen(This->szLocalname[nIndex]);
681 *pLocalName = This->szLocalname[nIndex];
682
683 return S_OK;
684 }
685
686 static HRESULT WINAPI isaxattributes_getQName(
687 ISAXAttributes* iface,
688 int nIndex,
689 const WCHAR **pQName,
690 int *pQNameLength)
691 {
692 saxattributes *This = impl_from_ISAXAttributes( iface );
693 TRACE("(%p)->(%d)\n", This, nIndex);
694
695 if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
696 if(!pQName || !pQNameLength) return E_POINTER;
697
698 *pQNameLength = SysStringLen(This->szQName[nIndex]);
699 *pQName = This->szQName[nIndex];
700
701 return S_OK;
702 }
703
704 static HRESULT WINAPI isaxattributes_getName(
705 ISAXAttributes* iface,
706 int nIndex,
707 const WCHAR **pUri,
708 int *pUriLength,
709 const WCHAR **pLocalName,
710 int *pLocalNameSize,
711 const WCHAR **pQName,
712 int *pQNameLength)
713 {
714 saxattributes *This = impl_from_ISAXAttributes( iface );
715 TRACE("(%p)->(%d)\n", This, nIndex);
716
717 if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
718 if(!pUri || !pUriLength || !pLocalName || !pLocalNameSize
719 || !pQName || !pQNameLength) return E_POINTER;
720
721 *pUriLength = SysStringLen(This->szURI[nIndex]);
722 *pUri = This->szURI[nIndex];
723 *pLocalNameSize = SysStringLen(This->szLocalname[nIndex]);
724 *pLocalName = This->szLocalname[nIndex];
725 *pQNameLength = SysStringLen(This->szQName[nIndex]);
726 *pQName = This->szQName[nIndex];
727
728 return S_OK;
729 }
730
731 static HRESULT WINAPI isaxattributes_getIndexFromName(
732 ISAXAttributes* iface,
733 const WCHAR *pUri,
734 int cUriLength,
735 const WCHAR *pLocalName,
736 int cocalNameLength,
737 int *index)
738 {
739 saxattributes *This = impl_from_ISAXAttributes( iface );
740 int i;
741 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), cUriLength,
742 debugstr_w(pLocalName), cocalNameLength);
743
744 if(!pUri || !pLocalName || !index) return E_POINTER;
745
746 for(i=0; i<This->nb_attributes; i++)
747 {
748 if(cUriLength!=SysStringLen(This->szURI[i])
749 || cocalNameLength!=SysStringLen(This->szLocalname[i]))
750 continue;
751 if(cUriLength && memcmp(pUri, This->szURI[i],
752 sizeof(WCHAR)*cUriLength))
753 continue;
754 if(cocalNameLength && memcmp(pLocalName, This->szLocalname[i],
755 sizeof(WCHAR)*cocalNameLength))
756 continue;
757
758 *index = i;
759 return S_OK;
760 }
761
762 return E_INVALIDARG;
763 }
764
765 static HRESULT WINAPI isaxattributes_getIndexFromQName(
766 ISAXAttributes* iface,
767 const WCHAR *pQName,
768 int nQNameLength,
769 int *index)
770 {
771 saxattributes *This = impl_from_ISAXAttributes( iface );
772 int i;
773 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQNameLength);
774
775 if(!pQName || !index) return E_POINTER;
776 if(!nQNameLength) return E_INVALIDARG;
777
778 for(i=0; i<This->nb_attributes; i++)
779 {
780 if(nQNameLength!=SysStringLen(This->szQName[i])) continue;
781 if(memcmp(pQName, This->szQName, sizeof(WCHAR)*nQNameLength)) continue;
782
783 *index = i;
784 return S_OK;
785 }
786
787 return E_INVALIDARG;
788 }
789
790 static HRESULT WINAPI isaxattributes_getType(
791 ISAXAttributes* iface,
792 int nIndex,
793 const WCHAR **pType,
794 int *pTypeLength)
795 {
796 saxattributes *This = impl_from_ISAXAttributes( iface );
797
798 FIXME("(%p)->(%d) stub\n", This, nIndex);
799 return E_NOTIMPL;
800 }
801
802 static HRESULT WINAPI isaxattributes_getTypeFromName(
803 ISAXAttributes* iface,
804 const WCHAR *pUri,
805 int nUri,
806 const WCHAR *pLocalName,
807 int nLocalName,
808 const WCHAR **pType,
809 int *nType)
810 {
811 saxattributes *This = impl_from_ISAXAttributes( iface );
812
813 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This, debugstr_w(pUri), nUri,
814 debugstr_w(pLocalName), nLocalName);
815 return E_NOTIMPL;
816 }
817
818 static HRESULT WINAPI isaxattributes_getTypeFromQName(
819 ISAXAttributes* iface,
820 const WCHAR *pQName,
821 int nQName,
822 const WCHAR **pType,
823 int *nType)
824 {
825 saxattributes *This = impl_from_ISAXAttributes( iface );
826
827 FIXME("(%p)->(%s, %d) stub\n", This, debugstr_w(pQName), nQName);
828 return E_NOTIMPL;
829 }
830
831 static HRESULT WINAPI isaxattributes_getValue(
832 ISAXAttributes* iface,
833 int nIndex,
834 const WCHAR **pValue,
835 int *nValue)
836 {
837 saxattributes *This = impl_from_ISAXAttributes( iface );
838 TRACE("(%p)->(%d)\n", This, nIndex);
839
840 if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
841 if(!pValue || !nValue) return E_POINTER;
842
843 *nValue = SysStringLen(This->szValue[nIndex]);
844 *pValue = This->szValue[nIndex];
845
846 return S_OK;
847 }
848
849 static HRESULT WINAPI isaxattributes_getValueFromName(
850 ISAXAttributes* iface,
851 const WCHAR *pUri,
852 int nUri,
853 const WCHAR *pLocalName,
854 int nLocalName,
855 const WCHAR **pValue,
856 int *nValue)
857 {
858 HRESULT hr;
859 int index;
860 saxattributes *This = impl_from_ISAXAttributes( iface );
861 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), nUri,
862 debugstr_w(pLocalName), nLocalName);
863
864 hr = ISAXAttributes_getIndexFromName(iface,
865 pUri, nUri, pLocalName, nLocalName, &index);
866 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
867
868 return hr;
869 }
870
871 static HRESULT WINAPI isaxattributes_getValueFromQName(
872 ISAXAttributes* iface,
873 const WCHAR *pQName,
874 int nQName,
875 const WCHAR **pValue,
876 int *nValue)
877 {
878 HRESULT hr;
879 int index;
880 saxattributes *This = impl_from_ISAXAttributes( iface );
881 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQName);
882
883 hr = ISAXAttributes_getIndexFromQName(iface, pQName, nQName, &index);
884 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
885
886 return hr;
887 }
888
889 static const struct ISAXAttributesVtbl isaxattributes_vtbl =
890 {
891 isaxattributes_QueryInterface,
892 isaxattributes_AddRef,
893 isaxattributes_Release,
894 isaxattributes_getLength,
895 isaxattributes_getURI,
896 isaxattributes_getLocalName,
897 isaxattributes_getQName,
898 isaxattributes_getName,
899 isaxattributes_getIndexFromName,
900 isaxattributes_getIndexFromQName,
901 isaxattributes_getType,
902 isaxattributes_getTypeFromName,
903 isaxattributes_getTypeFromQName,
904 isaxattributes_getValue,
905 isaxattributes_getValueFromName,
906 isaxattributes_getValueFromQName
907 };
908
909 static HRESULT SAXAttributes_create(saxattributes **attr,
910 int nb_namespaces, const xmlChar **xmlNamespaces,
911 int nb_attributes, const xmlChar **xmlAttributes)
912 {
913 saxattributes *attributes;
914 int index;
915 static const xmlChar xmlns[] = "xmlns";
916
917 attributes = HeapAlloc(GetProcessHeap(), 0, sizeof(*attributes));
918 if(!attributes)
919 return E_OUTOFMEMORY;
920
921 attributes->lpVBSAXAttributesVtbl = &ivbsaxattributes_vtbl;
922 attributes->lpSAXAttributesVtbl = &isaxattributes_vtbl;
923 attributes->ref = 1;
924
925 attributes->nb_attributes = nb_namespaces+nb_attributes;
926
927 attributes->szLocalname =
928 HeapAlloc(GetProcessHeap(), 0, sizeof(BSTR)*attributes->nb_attributes);
929 attributes->szURI =
930 HeapAlloc(GetProcessHeap(), 0, sizeof(BSTR)*attributes->nb_attributes);
931 attributes->szValue =
932 HeapAlloc(GetProcessHeap(), 0, sizeof(BSTR)*attributes->nb_attributes);
933 attributes->szQName =
934 HeapAlloc(GetProcessHeap(), 0, sizeof(BSTR)*attributes->nb_attributes);
935
936 if(!attributes->szLocalname || !attributes->szURI
937 || !attributes->szValue || !attributes->szQName)
938 {
939 HeapFree(GetProcessHeap(), 0, attributes->szLocalname);
940 HeapFree(GetProcessHeap(), 0, attributes->szURI);
941 HeapFree(GetProcessHeap(), 0, attributes->szValue);
942 HeapFree(GetProcessHeap(), 0, attributes->szQName);
943 HeapFree(GetProcessHeap(), 0, attributes);
944 return E_FAIL;
945 }
946
947 for(index=0; index<nb_namespaces; index++)
948 {
949 attributes->szLocalname[index] = SysAllocStringLen(NULL, 0);
950 attributes->szURI[index] = SysAllocStringLen(NULL, 0);
951 attributes->szValue[index] = bstr_from_xmlChar(xmlNamespaces[2*index+1]);
952 attributes->szQName[index] = QName_from_xmlChar(xmlns, xmlNamespaces[2*index]);
953 }
954
955 for(index=0; index<nb_attributes; index++)
956 {
957 attributes->szLocalname[nb_namespaces+index] =
958 bstr_from_xmlChar(xmlAttributes[index*5]);
959 attributes->szURI[nb_namespaces+index] =
960 bstr_from_xmlChar(xmlAttributes[index*5+2]);
961 attributes->szValue[nb_namespaces+index] =
962 bstr_from_xmlCharN(xmlAttributes[index*5+3],
963 xmlAttributes[index*5+4]-xmlAttributes[index*5+3]);
964 attributes->szQName[nb_namespaces+index] =
965 QName_from_xmlChar(xmlAttributes[index*5+1], xmlAttributes[index*5]);
966 }
967
968 *attr = attributes;
969
970 TRACE("returning %p\n", *attr);
971
972 return S_OK;
973 }
974
975 /*** LibXML callbacks ***/
976 static void libxmlStartDocument(void *ctx)
977 {
978 saxlocator *This = ctx;
979 HRESULT hr;
980
981 if((This->vbInterface && This->saxreader->vbcontentHandler)
982 || (!This->vbInterface && This->saxreader->contentHandler))
983 {
984 if(This->vbInterface)
985 hr = IVBSAXContentHandler_startDocument(This->saxreader->vbcontentHandler);
986 else
987 hr = ISAXContentHandler_startDocument(This->saxreader->contentHandler);
988
989 if(hr != S_OK)
990 format_error_message_from_id(This, hr);
991 }
992
993 update_position(This, NULL);
994 }
995
996 static void libxmlEndDocument(void *ctx)
997 {
998 saxlocator *This = ctx;
999 HRESULT hr;
1000
1001 This->column = 0;
1002 This->line = 0;
1003
1004 if(This->ret != S_OK) return;
1005
1006 if((This->vbInterface && This->saxreader->vbcontentHandler)
1007 || (!This->vbInterface && This->saxreader->contentHandler))
1008 {
1009 if(This->vbInterface)
1010 hr = IVBSAXContentHandler_endDocument(This->saxreader->vbcontentHandler);
1011 else
1012 hr = ISAXContentHandler_endDocument(This->saxreader->contentHandler);
1013
1014 if(hr != S_OK)
1015 format_error_message_from_id(This, hr);
1016 }
1017 }
1018
1019 static void libxmlStartElementNS(
1020 void *ctx,
1021 const xmlChar *localname,
1022 const xmlChar *prefix,
1023 const xmlChar *URI,
1024 int nb_namespaces,
1025 const xmlChar **namespaces,
1026 int nb_attributes,
1027 int nb_defaulted,
1028 const xmlChar **attributes)
1029 {
1030 BSTR NamespaceUri, LocalName, QName, Prefix, Uri;
1031 saxlocator *This = ctx;
1032 HRESULT hr;
1033 saxattributes *attr;
1034 int index;
1035
1036 if(*(This->pParserCtxt->input->cur) == '/')
1037 update_position(This, (xmlChar*)This->pParserCtxt->input->cur+2);
1038 else
1039 update_position(This, (xmlChar*)This->pParserCtxt->input->cur+1);
1040
1041 hr = namespacePush(This, nb_namespaces);
1042 if(hr==S_OK && ((This->vbInterface && This->saxreader->vbcontentHandler)
1043 || (!This->vbInterface && This->saxreader->contentHandler)))
1044 {
1045 for(index=0; index<nb_namespaces; index++)
1046 {
1047 Prefix = bstr_from_xmlChar(namespaces[2*index]);
1048 Uri = bstr_from_xmlChar(namespaces[2*index+1]);
1049
1050 if(This->vbInterface)
1051 hr = IVBSAXContentHandler_startPrefixMapping(
1052 This->saxreader->vbcontentHandler,
1053 &Prefix, &Uri);
1054 else
1055 hr = ISAXContentHandler_startPrefixMapping(
1056 This->saxreader->contentHandler,
1057 Prefix, SysStringLen(Prefix),
1058 Uri, SysStringLen(Uri));
1059
1060 SysFreeString(Prefix);
1061 SysFreeString(Uri);
1062
1063 if(hr != S_OK)
1064 {
1065 format_error_message_from_id(This, hr);
1066 return;
1067 }
1068 }
1069
1070 NamespaceUri = bstr_from_xmlChar(URI);
1071 LocalName = bstr_from_xmlChar(localname);
1072 QName = QName_from_xmlChar(prefix, localname);
1073
1074 hr = SAXAttributes_create(&attr, nb_namespaces, namespaces, nb_attributes, attributes);
1075 if(hr == S_OK)
1076 {
1077 if(This->vbInterface)
1078 hr = IVBSAXContentHandler_startElement(
1079 This->saxreader->vbcontentHandler,
1080 &NamespaceUri, &LocalName, &QName,
1081 (IVBSAXAttributes*)&attr->lpVBSAXAttributesVtbl);
1082 else
1083 hr = ISAXContentHandler_startElement(
1084 This->saxreader->contentHandler,
1085 NamespaceUri, SysStringLen(NamespaceUri),
1086 LocalName, SysStringLen(LocalName),
1087 QName, SysStringLen(QName),
1088 (ISAXAttributes*)&attr->lpSAXAttributesVtbl);
1089
1090 ISAXAttributes_Release((ISAXAttributes*)&attr->lpSAXAttributesVtbl);
1091 }
1092
1093 SysFreeString(NamespaceUri);
1094 SysFreeString(LocalName);
1095 SysFreeString(QName);
1096 }
1097
1098 if(hr != S_OK)
1099 format_error_message_from_id(This, hr);
1100 }
1101
1102 static void libxmlEndElementNS(
1103 void *ctx,
1104 const xmlChar *localname,
1105 const xmlChar *prefix,
1106 const xmlChar *URI)
1107 {
1108 BSTR NamespaceUri, LocalName, QName, Prefix;
1109 saxlocator *This = ctx;
1110 HRESULT hr;
1111 xmlChar *end;
1112 int nsNr, index;
1113
1114 end = (xmlChar*)This->pParserCtxt->input->cur;
1115 if(*(end-1) != '>' || *(end-2) != '/')
1116 while(*(end-2)!='<' && *(end-1)!='/') end--;
1117
1118 update_position(This, end);
1119
1120 nsNr = namespacePop(This);
1121
1122 if((This->vbInterface && This->saxreader->vbcontentHandler)
1123 || (!This->vbInterface && This->saxreader->contentHandler))
1124 {
1125 NamespaceUri = bstr_from_xmlChar(URI);
1126 LocalName = bstr_from_xmlChar(localname);
1127 QName = QName_from_xmlChar(prefix, localname);
1128
1129 if(This->vbInterface)
1130 hr = IVBSAXContentHandler_endElement(
1131 This->saxreader->vbcontentHandler,
1132 &NamespaceUri, &LocalName, &QName);
1133 else
1134 hr = ISAXContentHandler_endElement(
1135 This->saxreader->contentHandler,
1136 NamespaceUri, SysStringLen(NamespaceUri),
1137 LocalName, SysStringLen(LocalName),
1138 QName, SysStringLen(QName));
1139
1140 SysFreeString(NamespaceUri);
1141 SysFreeString(LocalName);
1142 SysFreeString(QName);
1143
1144 if(hr != S_OK)
1145 {
1146 format_error_message_from_id(This, hr);
1147 return;
1148 }
1149
1150 for(index=This->pParserCtxt->nsNr-2;
1151 index>=This->pParserCtxt->nsNr-nsNr*2; index-=2)
1152 {
1153 Prefix = bstr_from_xmlChar(This->pParserCtxt->nsTab[index]);
1154
1155 if(This->vbInterface)
1156 hr = IVBSAXContentHandler_endPrefixMapping(
1157 This->saxreader->vbcontentHandler, &Prefix);
1158 else
1159 hr = ISAXContentHandler_endPrefixMapping(
1160 This->saxreader->contentHandler,
1161 Prefix, SysStringLen(Prefix));
1162
1163 SysFreeString(Prefix);
1164
1165 if(hr != S_OK)
1166 {
1167 format_error_message_from_id(This, hr);
1168 return;
1169 }
1170
1171 }
1172 }
1173
1174 update_position(This, NULL);
1175 }
1176
1177 static void libxmlCharacters(
1178 void *ctx,
1179 const xmlChar *ch,
1180 int len)
1181 {
1182 saxlocator *This = ctx;
1183 BSTR Chars;
1184 HRESULT hr;
1185 xmlChar *cur;
1186 xmlChar *end;
1187 BOOL lastEvent = FALSE;
1188
1189 if((This->vbInterface && !This->saxreader->vbcontentHandler)
1190 || (!This->vbInterface && !This->saxreader->contentHandler))
1191 return;
1192
1193 cur = (xmlChar*)ch;
1194 if(*(ch-1)=='\r') cur--;
1195 end = cur;
1196
1197 if(ch<This->pParserCtxt->input->base || ch>This->pParserCtxt->input->end)
1198 This->column++;
1199
1200 while(1)
1201 {
1202 while(end-ch<len && *end!='\r') end++;
1203 if(end-ch==len)
1204 {
1205 end--;
1206 lastEvent = TRUE;
1207 }
1208
1209 if(!lastEvent) *end = '\n';
1210
1211 Chars = bstr_from_xmlCharN(cur, end-cur+1);
1212 if(This->vbInterface)
1213 hr = IVBSAXContentHandler_characters(
1214 This->saxreader->vbcontentHandler, &Chars);
1215 else
1216 hr = ISAXContentHandler_characters(
1217 This->saxreader->contentHandler,
1218 Chars, SysStringLen(Chars));
1219 SysFreeString(Chars);
1220
1221 if(hr != S_OK)
1222 {
1223 format_error_message_from_id(This, hr);
1224 return;
1225 }
1226
1227 This->column += end-cur+1;
1228
1229 if(lastEvent)
1230 break;
1231
1232 *end = '\r';
1233 end++;
1234 if(*end == '\n')
1235 {
1236 end++;
1237 This->column++;
1238 }
1239 cur = end;
1240
1241 if(end-ch == len) break;
1242 }
1243
1244 if(ch<This->pParserCtxt->input->base || ch>This->pParserCtxt->input->end)
1245 This->column = This->realColumn
1246 +This->pParserCtxt->input->cur-This->lastCur;
1247 }
1248
1249 static void libxmlSetDocumentLocator(
1250 void *ctx,
1251 xmlSAXLocatorPtr loc)
1252 {
1253 saxlocator *This = ctx;
1254 HRESULT hr;
1255
1256 if(This->vbInterface)
1257 hr = IVBSAXContentHandler_putref_documentLocator(
1258 This->saxreader->vbcontentHandler,
1259 (IVBSAXLocator*)&This->lpVBSAXLocatorVtbl);
1260 else
1261 hr = ISAXContentHandler_putDocumentLocator(
1262 This->saxreader->contentHandler,
1263 (ISAXLocator*)&This->lpSAXLocatorVtbl);
1264
1265 if(FAILED(hr))
1266 format_error_message_from_id(This, hr);
1267 }
1268
1269 static void libxmlComment(void *ctx, const xmlChar *value)
1270 {
1271 saxlocator *This = ctx;
1272 BSTR bValue;
1273 HRESULT hr;
1274 xmlChar *beg = (xmlChar*)This->pParserCtxt->input->cur;
1275
1276 while(memcmp(beg-4, "<!--", sizeof(char[4]))) beg--;
1277 update_position(This, beg);
1278
1279 if(!This->vbInterface && !This->saxreader->lexicalHandler) return;
1280 if(This->vbInterface && !This->saxreader->vblexicalHandler) return;
1281
1282 bValue = bstr_from_xmlChar(value);
1283
1284 if(This->vbInterface)
1285 hr = IVBSAXLexicalHandler_comment(
1286 This->saxreader->vblexicalHandler, &bValue);
1287 else
1288 hr = ISAXLexicalHandler_comment(
1289 This->saxreader->lexicalHandler,
1290 bValue, SysStringLen(bValue));
1291
1292 SysFreeString(bValue);
1293
1294 if(FAILED(hr))
1295 format_error_message_from_id(This, hr);
1296
1297 update_position(This, NULL);
1298 }
1299
1300 static void libxmlFatalError(void *ctx, const char *msg, ...)
1301 {
1302 saxlocator *This = ctx;
1303 char message[1024];
1304 WCHAR *wszError;
1305 DWORD len;
1306 va_list args;
1307
1308 if((This->vbInterface && !This->saxreader->vberrorHandler)
1309 || (!This->vbInterface && !This->saxreader->errorHandler))
1310 {
1311 xmlStopParser(This->pParserCtxt);
1312 This->ret = E_FAIL;
1313 return;
1314 }
1315
1316 FIXME("Error handling is not compatible.\n");
1317
1318 va_start(args, msg);
1319 vsprintf(message, msg, args);
1320 va_end(args);
1321
1322 len = MultiByteToWideChar(CP_UNIXCP, 0, message, -1, NULL, 0);
1323 wszError = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len);
1324 if(wszError)
1325 MultiByteToWideChar(CP_UNIXCP, 0, message, -1, wszError, len);
1326
1327 if(This->vbInterface)
1328 {
1329 BSTR bstrError = SysAllocString(wszError);
1330 IVBSAXErrorHandler_fatalError(This->saxreader->vberrorHandler,
1331 (IVBSAXLocator*)&This->lpVBSAXLocatorVtbl, &bstrError, E_FAIL);
1332 }
1333 else
1334 ISAXErrorHandler_fatalError(This->saxreader->errorHandler,
1335 (ISAXLocator*)&This->lpSAXLocatorVtbl, wszError, E_FAIL);
1336
1337 HeapFree(GetProcessHeap(), 0, wszError);
1338
1339 xmlStopParser(This->pParserCtxt);
1340 This->ret = E_FAIL;
1341 }
1342
1343 static void libxmlCDataBlock(void *ctx, const xmlChar *value, int len)
1344 {
1345 saxlocator *This = ctx;
1346 HRESULT hr = S_OK;
1347 xmlChar *beg = (xmlChar*)This->pParserCtxt->input->cur-len;
1348 xmlChar *cur, *end;
1349 int realLen;
1350 BSTR Chars;
1351 BOOL lastEvent = FALSE, change;
1352
1353 while(memcmp(beg-9, "<![CDATA[", sizeof(char[9]))) beg--;
1354 update_position(This, beg);
1355
1356 if(This->vbInterface && This->saxreader->vblexicalHandler)
1357 hr = IVBSAXLexicalHandler_startCDATA(This->saxreader->vblexicalHandler);
1358 if(!This->vbInterface && This->saxreader->lexicalHandler)
1359 hr = ISAXLexicalHandler_startCDATA(This->saxreader->lexicalHandler);
1360
1361 if(FAILED(hr))
1362 {
1363 format_error_message_from_id(This, hr);
1364 return;
1365 }
1366
1367 realLen = This->pParserCtxt->input->cur-beg-3;
1368 cur = beg;
1369 end = beg;
1370
1371 while(1)
1372 {
1373 while(end-beg<realLen && *end!='\r') end++;
1374 if(end-beg==realLen)
1375 {
1376 end--;
1377 lastEvent = TRUE;
1378 }
1379 else if(end-beg==realLen-1 && *end=='\r' && *(end+1)=='\n')
1380 lastEvent = TRUE;
1381
1382 if(*end == '\r') change = TRUE;
1383 else change = FALSE;
1384
1385 if(change) *end = '\n';
1386
1387 if((This->vbInterface && This->saxreader->vbcontentHandler) ||
1388 (!This->vbInterface && This->saxreader->contentHandler))
1389 {
1390 Chars = bstr_from_xmlCharN(cur, end-cur+1);
1391 if(This->vbInterface)
1392 hr = IVBSAXContentHandler_characters(
1393 This->saxreader->vbcontentHandler, &Chars);
1394 else
1395 hr = ISAXContentHandler_characters(
1396 This->saxreader->contentHandler,
1397 Chars, SysStringLen(Chars));
1398 SysFreeString(Chars);
1399 }
1400
1401 if(change) *end = '\r';
1402
1403 if(lastEvent)
1404 break;
1405
1406 This->column += end-cur+2;
1407 end += 2;
1408 cur = end;
1409 }
1410
1411 if(This->vbInterface && This->saxreader->vblexicalHandler)
1412 hr = IVBSAXLexicalHandler_endCDATA(This->saxreader->vblexicalHandler);
1413 if(!This->vbInterface && This->saxreader->lexicalHandler)
1414 hr = ISAXLexicalHandler_endCDATA(This->saxreader->lexicalHandler);
1415
1416 if(FAILED(hr))
1417 format_error_message_from_id(This, hr);
1418
1419 This->column += 4+end-cur;
1420 }
1421
1422 /*** IVBSAXLocator interface ***/
1423 /*** IUnknown methods ***/
1424 static HRESULT WINAPI ivbsaxlocator_QueryInterface(IVBSAXLocator* iface, REFIID riid, void **ppvObject)
1425 {
1426 saxlocator *This = impl_from_IVBSAXLocator( iface );
1427
1428 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject);
1429
1430 *ppvObject = NULL;
1431
1432 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
1433 IsEqualGUID( riid, &IID_IDispatch) ||
1434 IsEqualGUID( riid, &IID_IVBSAXLocator ))
1435 {
1436 *ppvObject = iface;
1437 }
1438 else
1439 {
1440 FIXME("interface %s not implemented\n", debugstr_guid(riid));
1441 return E_NOINTERFACE;
1442 }
1443
1444 IVBSAXLocator_AddRef( iface );
1445
1446 return S_OK;
1447 }
1448
1449 static ULONG WINAPI ivbsaxlocator_AddRef(IVBSAXLocator* iface)
1450 {
1451 saxlocator *This = impl_from_IVBSAXLocator( iface );
1452 TRACE("%p\n", This );
1453 return InterlockedIncrement( &This->ref );
1454 }
1455
1456 static ULONG WINAPI ivbsaxlocator_Release(
1457 IVBSAXLocator* iface)
1458 {
1459 saxlocator *This = impl_from_IVBSAXLocator( iface );
1460 return ISAXLocator_Release((ISAXLocator*)&This->lpVBSAXLocatorVtbl);
1461 }
1462
1463 /*** IDispatch methods ***/
1464 static HRESULT WINAPI ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator *iface, UINT* pctinfo )
1465 {
1466 saxlocator *This = impl_from_IVBSAXLocator( iface );
1467
1468 TRACE("(%p)->(%p)\n", This, pctinfo);
1469
1470 *pctinfo = 1;
1471
1472 return S_OK;
1473 }
1474
1475 static HRESULT WINAPI ivbsaxlocator_GetTypeInfo(
1476 IVBSAXLocator *iface,
1477 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
1478 {
1479 saxlocator *This = impl_from_IVBSAXLocator( iface );
1480 HRESULT hr;
1481
1482 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1483
1484 hr = get_typeinfo(IVBSAXLocator_tid, ppTInfo);
1485
1486 return hr;
1487 }
1488
1489 static HRESULT WINAPI ivbsaxlocator_GetIDsOfNames(
1490 IVBSAXLocator *iface,
1491 REFIID riid,
1492 LPOLESTR* rgszNames,
1493 UINT cNames,
1494 LCID lcid,
1495 DISPID* rgDispId)
1496 {
1497 saxlocator *This = impl_from_IVBSAXLocator( iface );
1498 ITypeInfo *typeinfo;
1499 HRESULT hr;
1500
1501 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1502 lcid, rgDispId);
1503
1504 if(!rgszNames || cNames == 0 || !rgDispId)
1505 return E_INVALIDARG;
1506
1507 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo);
1508 if(SUCCEEDED(hr))
1509 {
1510 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1511 ITypeInfo_Release(typeinfo);
1512 }
1513
1514 return hr;
1515 }
1516
1517 static HRESULT WINAPI ivbsaxlocator_Invoke(
1518 IVBSAXLocator *iface,
1519 DISPID dispIdMember,
1520 REFIID riid,
1521 LCID lcid,
1522 WORD wFlags,
1523 DISPPARAMS* pDispParams,
1524 VARIANT* pVarResult,
1525 EXCEPINFO* pExcepInfo,
1526 UINT* puArgErr)
1527 {
1528 saxlocator *This = impl_from_IVBSAXLocator( iface );
1529 ITypeInfo *typeinfo;
1530 HRESULT hr;
1531
1532 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1533 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1534
1535 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo);
1536 if(SUCCEEDED(hr))
1537 {
1538 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVBSAXLocatorVtbl), dispIdMember, wFlags, pDispParams,
1539 pVarResult, pExcepInfo, puArgErr);
1540 ITypeInfo_Release(typeinfo);
1541 }
1542
1543 return hr;
1544 }
1545
1546 /*** IVBSAXLocator methods ***/
1547 static HRESULT WINAPI ivbsaxlocator_get_columnNumber(
1548 IVBSAXLocator* iface,
1549 int *pnColumn)
1550 {
1551 saxlocator *This = impl_from_IVBSAXLocator( iface );
1552 return ISAXLocator_getColumnNumber(
1553 (ISAXLocator*)&This->lpVBSAXLocatorVtbl,
1554 pnColumn);
1555 }
1556
1557 static HRESULT WINAPI ivbsaxlocator_get_lineNumber(
1558 IVBSAXLocator* iface,
1559 int *pnLine)
1560 {
1561 saxlocator *This = impl_from_IVBSAXLocator( iface );
1562 return ISAXLocator_getLineNumber(
1563 (ISAXLocator*)&This->lpVBSAXLocatorVtbl,
1564 pnLine);
1565 }
1566
1567 static HRESULT WINAPI ivbsaxlocator_get_publicId(
1568 IVBSAXLocator* iface,
1569 BSTR* publicId)
1570 {
1571 saxlocator *This = impl_from_IVBSAXLocator( iface );
1572 return ISAXLocator_getPublicId(
1573 (ISAXLocator*)&This->lpVBSAXLocatorVtbl,
1574 (const WCHAR**)publicId);
1575 }
1576
1577 static HRESULT WINAPI ivbsaxlocator_get_systemId(
1578 IVBSAXLocator* iface,
1579 BSTR* systemId)
1580 {
1581 saxlocator *This = impl_from_IVBSAXLocator( iface );
1582 return ISAXLocator_getSystemId(
1583 (ISAXLocator*)&This->lpVBSAXLocatorVtbl,
1584 (const WCHAR**)systemId);
1585 }
1586
1587 static const struct IVBSAXLocatorVtbl ivbsaxlocator_vtbl =
1588 {
1589 ivbsaxlocator_QueryInterface,
1590 ivbsaxlocator_AddRef,
1591 ivbsaxlocator_Release,
1592 ivbsaxlocator_GetTypeInfoCount,
1593 ivbsaxlocator_GetTypeInfo,
1594 ivbsaxlocator_GetIDsOfNames,
1595 ivbsaxlocator_Invoke,
1596 ivbsaxlocator_get_columnNumber,
1597 ivbsaxlocator_get_lineNumber,
1598 ivbsaxlocator_get_publicId,
1599 ivbsaxlocator_get_systemId
1600 };
1601
1602 /*** ISAXLocator interface ***/
1603 /*** IUnknown methods ***/
1604 static HRESULT WINAPI isaxlocator_QueryInterface(ISAXLocator* iface, REFIID riid, void **ppvObject)
1605 {
1606 saxlocator *This = impl_from_ISAXLocator( iface );
1607
1608 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
1609
1610 *ppvObject = NULL;
1611
1612 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
1613 IsEqualGUID( riid, &IID_ISAXLocator ))
1614 {
1615 *ppvObject = iface;
1616 }
1617 else
1618 {
1619 FIXME("interface %s not implemented\n", debugstr_guid(riid));
1620 return E_NOINTERFACE;
1621 }
1622
1623 ISAXLocator_AddRef( iface );
1624
1625 return S_OK;
1626 }
1627
1628 static ULONG WINAPI isaxlocator_AddRef(ISAXLocator* iface)
1629 {
1630 saxlocator *This = impl_from_ISAXLocator( iface );
1631 TRACE("%p\n", This );
1632 return InterlockedIncrement( &This->ref );
1633 }
1634
1635 static ULONG WINAPI isaxlocator_Release(
1636 ISAXLocator* iface)
1637 {
1638 saxlocator *This = impl_from_ISAXLocator( iface );
1639 LONG ref;
1640
1641 TRACE("%p\n", This );
1642
1643 ref = InterlockedDecrement( &This->ref );
1644 if ( ref == 0 )
1645 {
1646 SysFreeString(This->publicId);
1647 SysFreeString(This->systemId);
1648 HeapFree(GetProcessHeap(), 0, This->nsStack);
1649
1650 ISAXXMLReader_Release((ISAXXMLReader*)&This->saxreader->lpSAXXMLReaderVtbl);
1651 HeapFree( GetProcessHeap(), 0, This );
1652 }
1653
1654 return ref;
1655 }
1656
1657 /*** ISAXLocator methods ***/
1658 static HRESULT WINAPI isaxlocator_getColumnNumber(
1659 ISAXLocator* iface,
1660 int *pnColumn)
1661 {
1662 saxlocator *This = impl_from_ISAXLocator( iface );
1663
1664 *pnColumn = This->column;
1665 return S_OK;
1666 }
1667
1668 static HRESULT WINAPI isaxlocator_getLineNumber(
1669 ISAXLocator* iface,
1670 int *pnLine)
1671 {
1672 saxlocator *This = impl_from_ISAXLocator( iface );
1673
1674 *pnLine = This->line;
1675 return S_OK;
1676 }
1677
1678 static HRESULT WINAPI isaxlocator_getPublicId(
1679 ISAXLocator* iface,
1680 const WCHAR ** ppwchPublicId)
1681 {
1682 BSTR publicId;
1683 saxlocator *This = impl_from_ISAXLocator( iface );
1684
1685 SysFreeString(This->publicId);
1686
1687 publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt));
1688 if(SysStringLen(publicId))
1689 This->publicId = (WCHAR*)&publicId;
1690 else
1691 {
1692 SysFreeString(publicId);
1693 This->publicId = NULL;
1694 }
1695
1696 *ppwchPublicId = This->publicId;
1697 return S_OK;
1698 }
1699
1700 static HRESULT WINAPI isaxlocator_getSystemId(
1701 ISAXLocator* iface,
1702 const WCHAR ** ppwchSystemId)
1703 {
1704 BSTR systemId;
1705 saxlocator *This = impl_from_ISAXLocator( iface );
1706
1707 SysFreeString(This->systemId);
1708
1709 systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt));
1710 if(SysStringLen(systemId))
1711 This->systemId = (WCHAR*)&systemId;
1712 else
1713 {
1714 SysFreeString(systemId);
1715 This->systemId = NULL;
1716 }
1717
1718 *ppwchSystemId = This->systemId;
1719 return S_OK;
1720 }
1721
1722 static const struct ISAXLocatorVtbl isaxlocator_vtbl =
1723 {
1724 isaxlocator_QueryInterface,
1725 isaxlocator_AddRef,
1726 isaxlocator_Release,
1727 isaxlocator_getColumnNumber,
1728 isaxlocator_getLineNumber,
1729 isaxlocator_getPublicId,
1730 isaxlocator_getSystemId
1731 };
1732
1733 static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator, BOOL vbInterface)
1734 {
1735 saxlocator *locator;
1736
1737 locator = HeapAlloc( GetProcessHeap(), 0, sizeof (*locator) );
1738 if( !locator )
1739 return E_OUTOFMEMORY;
1740
1741 locator->lpVBSAXLocatorVtbl = &ivbsaxlocator_vtbl;
1742 locator->lpSAXLocatorVtbl = &isaxlocator_vtbl;
1743 locator->ref = 1;
1744 locator->vbInterface = vbInterface;
1745
1746 locator->saxreader = reader;
1747 ISAXXMLReader_AddRef((ISAXXMLReader*)&reader->lpSAXXMLReaderVtbl);
1748
1749 locator->pParserCtxt = NULL;
1750 locator->publicId = NULL;
1751 locator->systemId = NULL;
1752 locator->lastCur = NULL;
1753 locator->line = 0;
1754 locator->column = 0;
1755 locator->ret = S_OK;
1756 locator->nsStackSize = 8;
1757 locator->nsStackLast = 0;
1758 locator->nsStack = HeapAlloc(GetProcessHeap(), 0, locator->nsStackSize);
1759 if(!locator->nsStack)
1760 {
1761 ISAXXMLReader_Release((ISAXXMLReader*)&reader->lpSAXXMLReaderVtbl);
1762 HeapFree(GetProcessHeap(), 0, locator);
1763 return E_OUTOFMEMORY;
1764 }
1765
1766 *ppsaxlocator = locator;
1767
1768 TRACE("returning %p\n", *ppsaxlocator);
1769
1770 return S_OK;
1771 }
1772
1773 /*** SAXXMLReader internal functions ***/
1774 static HRESULT internal_parseBuffer(saxreader *This, const char *buffer, int size, BOOL vbInterface)
1775 {
1776 saxlocator *locator;
1777 HRESULT hr;
1778
1779 hr = SAXLocator_create(This, &locator, vbInterface);
1780 if(FAILED(hr))
1781 return hr;
1782
1783 locator->pParserCtxt = xmlCreateMemoryParserCtxt(buffer, size);
1784 if(!locator->pParserCtxt)
1785 {
1786 ISAXLocator_Release((ISAXLocator*)&locator->lpSAXLocatorVtbl);
1787 return E_FAIL;
1788 }
1789
1790 locator->pParserCtxt->sax = &locator->saxreader->sax;
1791 locator->pParserCtxt->userData = locator;
1792
1793 This->isParsing = TRUE;
1794 if(xmlParseDocument(locator->pParserCtxt)) hr = E_FAIL;
1795 else hr = locator->ret;
1796 This->isParsing = FALSE;
1797
1798 if(locator->pParserCtxt)
1799 {
1800 locator->pParserCtxt->sax = NULL;
1801 xmlFreeParserCtxt(locator->pParserCtxt);
1802 locator->pParserCtxt = NULL;
1803 }
1804
1805 ISAXLocator_Release((ISAXLocator*)&locator->lpSAXLocatorVtbl);
1806 return hr;
1807 }
1808
1809 static HRESULT internal_parseStream(saxreader *This, IStream *stream, BOOL vbInterface)
1810 {
1811 saxlocator *locator;
1812 HRESULT hr;
1813 ULONG dataRead;
1814 char data[1024];
1815
1816 hr = IStream_Read(stream, data, sizeof(data), &dataRead);
1817 if(hr != S_OK)
1818 return hr;
1819
1820 hr = SAXLocator_create(This, &locator, vbInterface);
1821 if(FAILED(hr))
1822 return hr;
1823
1824 locator->pParserCtxt = xmlCreatePushParserCtxt(
1825 &locator->saxreader->sax, locator,
1826 data, dataRead, NULL);
1827 if(!locator->pParserCtxt)
1828 {
1829 ISAXLocator_Release((ISAXLocator*)&locator->lpSAXLocatorVtbl);
1830 return E_FAIL;
1831 }
1832
1833 This->isParsing = TRUE;
1834 while(1)
1835 {
1836 hr = IStream_Read(stream, data, sizeof(data), &dataRead);
1837 if(hr != S_OK)
1838 break;
1839
1840 if(xmlParseChunk(locator->pParserCtxt, data, dataRead, 0)) hr = E_FAIL;
1841 else hr = locator->ret;
1842
1843 if(hr != S_OK) break;
1844
1845 if(dataRead != sizeof(data))
1846 {
1847 if(xmlParseChunk(locator->pParserCtxt, data, 0, 1)) hr = E_FAIL;
1848 else hr = locator->ret;
1849
1850 break;
1851 }
1852 }
1853 This->isParsing = FALSE;
1854
1855 locator->pParserCtxt->sax = NULL;
1856 xmlFreeParserCtxt(locator->pParserCtxt);
1857 locator->pParserCtxt = NULL;
1858 ISAXLocator_Release((ISAXLocator*)&locator->lpSAXLocatorVtbl);
1859 return hr;
1860 }
1861
1862 static HRESULT internal_getEntityResolver(
1863 saxreader *This,
1864 void *pEntityResolver,
1865 BOOL vbInterface)
1866 {
1867 FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
1868 return E_NOTIMPL;
1869 }
1870
1871 static HRESULT internal_putEntityResolver(
1872 saxreader *This,
1873 void *pEntityResolver,
1874 BOOL vbInterface)
1875 {
1876 FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
1877 return E_NOTIMPL;
1878 }
1879
1880 static HRESULT internal_getContentHandler(
1881 saxreader* This,
1882 void *pContentHandler,
1883 BOOL vbInterface)
1884 {
1885 TRACE("(%p)->(%p)\n", This, pContentHandler);
1886 if(pContentHandler == NULL)
1887 return E_POINTER;
1888 if((vbInterface && This->vbcontentHandler)
1889 || (!vbInterface && This->contentHandler))
1890 {
1891 if(vbInterface)
1892 IVBSAXContentHandler_AddRef(This->vbcontentHandler);
1893 else
1894 ISAXContentHandler_AddRef(This->contentHandler);
1895 }
1896 if(vbInterface) *(IVBSAXContentHandler**)pContentHandler =
1897 This->vbcontentHandler;
1898 else *(ISAXContentHandler**)pContentHandler = This->contentHandler;
1899
1900 return S_OK;
1901 }
1902
1903 static HRESULT internal_putContentHandler(
1904 saxreader* This,
1905 void *contentHandler,
1906 BOOL vbInterface)
1907 {
1908 TRACE("(%p)->(%p)\n", This, contentHandler);
1909 if(contentHandler)
1910 {
1911 if(vbInterface)
1912 IVBSAXContentHandler_AddRef((IVBSAXContentHandler*)contentHandler);
1913 else
1914 ISAXContentHandler_AddRef((ISAXContentHandler*)contentHandler);
1915 }
1916 if((vbInterface && This->vbcontentHandler)
1917 || (!vbInterface && This->contentHandler))
1918 {
1919 if(vbInterface)
1920 IVBSAXContentHandler_Release(This->vbcontentHandler);
1921 else
1922 ISAXContentHandler_Release(This->contentHandler);
1923 }
1924 if(vbInterface)
1925 This->vbcontentHandler = contentHandler;
1926 else
1927 This->contentHandler = contentHandler;
1928
1929 return S_OK;
1930 }
1931
1932 static HRESULT internal_getDTDHandler(
1933 saxreader* This,
1934 void *pDTDHandler,
1935 BOOL vbInterface)
1936 {
1937 FIXME("(%p)->(%p) stub\n", This, pDTDHandler);
1938 return E_NOTIMPL;
1939 }
1940
1941 static HRESULT internal_putDTDHandler(
1942 saxreader* This,
1943 void *pDTDHandler,
1944 BOOL vbInterface)
1945 {
1946 FIXME("(%p)->(%p) stub\n", This, pDTDHandler);
1947 return E_NOTIMPL;
1948 }
1949
1950 static HRESULT internal_getErrorHandler(
1951 saxreader* This,
1952 void *pErrorHandler,
1953 BOOL vbInterface)
1954 {
1955 TRACE("(%p)->(%p)\n", This, pErrorHandler);
1956 if(pErrorHandler == NULL)
1957 return E_POINTER;
1958
1959 if(vbInterface && This->vberrorHandler)
1960 IVBSAXErrorHandler_AddRef(This->vberrorHandler);
1961 else if(!vbInterface && This->errorHandler)
1962 ISAXErrorHandler_AddRef(This->errorHandler);
1963
1964 if(vbInterface)
1965 *(IVBSAXErrorHandler**)pErrorHandler = This->vberrorHandler;
1966 else
1967 *(ISAXErrorHandler**)pErrorHandler = This->errorHandler;
1968
1969 return S_OK;
1970
1971 }
1972
1973 static HRESULT internal_putErrorHandler(
1974 saxreader* This,
1975 void *errorHandler,
1976 BOOL vbInterface)
1977 {
1978 TRACE("(%p)->(%p)\n", This, errorHandler);
1979 if(errorHandler)
1980 {
1981 if(vbInterface)
1982 IVBSAXErrorHandler_AddRef((IVBSAXErrorHandler*)errorHandler);
1983 else
1984 ISAXErrorHandler_AddRef((ISAXErrorHandler*)errorHandler);
1985 }
1986
1987 if(vbInterface && This->vberrorHandler)
1988 IVBSAXErrorHandler_Release(This->vberrorHandler);
1989 else if(!vbInterface && This->errorHandler)
1990 ISAXErrorHandler_Release(This->errorHandler);
1991
1992 if(vbInterface)
1993 This->vberrorHandler = errorHandler;
1994 else
1995 This->errorHandler = errorHandler;
1996
1997 return S_OK;
1998
1999 }
2000
2001 static HRESULT internal_parse(
2002 saxreader* This,
2003 VARIANT varInput,
2004 BOOL vbInterface)
2005 {
2006 HRESULT hr;
2007
2008 TRACE("(%p)\n", This);
2009
2010 hr = S_OK;
2011 switch(V_VT(&varInput))
2012 {
2013 case VT_BSTR:
2014 hr = internal_parseBuffer(This, (const char*)V_BSTR(&varInput),
2015 SysStringByteLen(V_BSTR(&varInput)), vbInterface);
2016 break;
2017 case VT_ARRAY|VT_UI1: {
2018 void *pSAData;
2019 LONG lBound, uBound;
2020 ULONG dataRead;
2021
2022 hr = SafeArrayGetLBound(V_ARRAY(&varInput), 1, &lBound);
2023 if(hr != S_OK) break;
2024 hr = SafeArrayGetUBound(V_ARRAY(&varInput), 1, &uBound);
2025 if(hr != S_OK) break;
2026 dataRead = (uBound-lBound)*SafeArrayGetElemsize(V_ARRAY(&varInput));
2027 hr = SafeArrayAccessData(V_ARRAY(&varInput), &pSAData);
2028 if(hr != S_OK) break;
2029 hr = internal_parseBuffer(This, pSAData, dataRead, vbInterface);
2030 SafeArrayUnaccessData(V_ARRAY(&varInput));
2031 break;
2032 }
2033 case VT_UNKNOWN:
2034 case VT_DISPATCH: {
2035 IPersistStream *persistStream;
2036 IStream *stream = NULL;
2037 IXMLDOMDocument *xmlDoc;
2038
2039 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2040 &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK)
2041 {
2042 BSTR bstrData;
2043
2044 IXMLDOMDocument_get_xml(xmlDoc, &bstrData);
2045 hr = internal_parseBuffer(This, (const char*)bstrData,
2046 SysStringByteLen(bstrData), vbInterface);
2047 IXMLDOMDocument_Release(xmlDoc);
2048 break;
2049 }
2050 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2051 &IID_IPersistStream, (void**)&persistStream) == S_OK)
2052 {
2053 hr = IPersistStream_Save(persistStream, stream, TRUE);
2054 IPersistStream_Release(persistStream);
2055 if(hr != S_OK) break;
2056 }
2057 if(stream || IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2058 &IID_IStream, (void**)&stream) == S_OK)
2059 {
2060 hr = internal_parseStream(This, stream, vbInterface);
2061 IStream_Release(stream);
2062 break;
2063 }
2064 }
2065 default:
2066 WARN("vt %d not implemented\n", V_VT(&varInput));
2067 hr = E_INVALIDARG;
2068 }
2069
2070 return hr;
2071 }
2072
2073 static HRESULT internal_vbonDataAvailable(void *obj, char *ptr, DWORD len)
2074 {
2075 saxreader *This = obj;
2076
2077 return internal_parseBuffer(This, ptr, len, TRUE);
2078 }
2079
2080 static HRESULT internal_onDataAvailable(void *obj, char *ptr, DWORD len)
2081 {
2082 saxreader *This = obj;
2083
2084 return internal_parseBuffer(This, ptr, len, FALSE);
2085 }
2086
2087 static HRESULT internal_parseURL(
2088 saxreader* This,
2089 const WCHAR *url,
2090 BOOL vbInterface)
2091 {
2092 bsc_t *bsc;
2093 HRESULT hr;
2094
2095 TRACE("(%p)->(%s)\n", This, debugstr_w(url));
2096
2097 if(vbInterface) hr = bind_url(url, internal_vbonDataAvailable, This, &bsc);
2098 else hr = bind_url(url, internal_onDataAvailable, This, &bsc);
2099
2100 if(FAILED(hr))
2101 return hr;
2102
2103 detach_bsc(bsc);
2104
2105 return S_OK;
2106 }
2107
2108 static HRESULT internal_putProperty(
2109 saxreader* This,
2110 const WCHAR *pProp,
2111 VARIANT value,
2112 BOOL vbInterface)
2113 {
2114 static const WCHAR wszCharset[] = {
2115 'c','h','a','r','s','e','t',0
2116 };
2117 static const WCHAR wszDeclarationHandler[] = {
2118 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
2119 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
2120 'd','e','c','l','a','r','a','t','i','o','n',
2121 '-','h','a','n','d','l','e','r',0
2122 };
2123 static const WCHAR wszDomNode[] = {
2124 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
2125 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
2126 'd','o','m','-','n','o','d','e',0
2127 };
2128 static const WCHAR wszInputSource[] = {
2129 'i','n','p','u','t','-','s','o','u','r','c','e',0
2130 };
2131 static const WCHAR wszLexicalHandler[] = {
2132 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
2133 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
2134 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
2135 };
2136 static const WCHAR wszMaxElementDepth[] = {
2137 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
2138 };
2139 static const WCHAR wszMaxXMLSize[] = {
2140 'm','a','x','-','x','m','l','-','s','i','z','e',0
2141 };
2142 static const WCHAR wszSchemaDeclarationHandler[] = {
2143 's','c','h','e','m','a','-',
2144 'd','e','c','l','a','r','a','t','i','o','n','-',
2145 'h','a','n','d','l','e','r',0
2146 };
2147 static const WCHAR wszXMLDeclEncoding[] = {
2148 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
2149 };
2150 static const WCHAR wszXMLDeclStandalone[] = {
2151 'x','m','l','d','e','c','l',
2152 '-','s','t','a','n','d','a','l','o','n','e',0
2153 };
2154 static const WCHAR wszXMLDeclVersion[] = {
2155 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
2156 };
2157
2158 FIXME("(%p)->(%s): semi-stub\n", This, debugstr_w(pProp));
2159
2160 if(!memcmp(pProp, wszCharset, sizeof(wszCharset)))
2161 return E_NOTIMPL;
2162
2163 if(!memcmp(pProp, wszDeclarationHandler, sizeof(wszDeclarationHandler)))
2164 {
2165 if(This->isParsing) return E_FAIL;
2166
2167 if(V_UNKNOWN(&value))
2168 {
2169 if(vbInterface)
2170 IVBSAXDeclHandler_AddRef((IVBSAXDeclHandler*)V_UNKNOWN(&value));
2171 else
2172 ISAXDeclHandler_AddRef((ISAXDeclHandler*)V_UNKNOWN(&value));
2173 }
2174 if((vbInterface && This->vbdeclHandler)
2175 || (!vbInterface && This->declHandler))
2176 {
2177 if(vbInterface)
2178 IVBSAXDeclHandler_Release(This->vbdeclHandler);
2179 else
2180 ISAXDeclHandler_Release(This->declHandler);
2181 }
2182 if(vbInterface)
2183 This->vbdeclHandler = (IVBSAXDeclHandler*)V_UNKNOWN(&value);
2184 else
2185 This->declHandler = (ISAXDeclHandler*)V_UNKNOWN(&value);
2186 return S_OK;
2187 }
2188
2189 if(!memcmp(pProp, wszDomNode, sizeof(wszDomNode)))
2190 return E_FAIL;
2191
2192 if(!memcmp(pProp, wszInputSource, sizeof(wszInputSource)))
2193 return E_NOTIMPL;
2194
2195 if(!memcmp(pProp, wszLexicalHandler, sizeof(wszLexicalHandler)))
2196 {
2197 if(This->isParsing) return E_FAIL;
2198
2199 if(V_UNKNOWN(&value))
2200 {
2201 if(vbInterface)
2202 IVBSAXLexicalHandler_AddRef(
2203 (IVBSAXLexicalHandler*)V_UNKNOWN(&value));
2204 else
2205 ISAXLexicalHandler_AddRef(
2206 (ISAXLexicalHandler*)V_UNKNOWN(&value));
2207 }
2208 if((vbInterface && This->vblexicalHandler)
2209 || (!vbInterface && This->lexicalHandler))
2210 {
2211 if(vbInterface)
2212 IVBSAXLexicalHandler_Release(This->vblexicalHandler);
2213 else
2214 ISAXLexicalHandler_Release(This->lexicalHandler);
2215 }
2216 if(vbInterface)
2217 This->vblexicalHandler = (IVBSAXLexicalHandler*)V_UNKNOWN(&value);
2218 else
2219 This->lexicalHandler = (ISAXLexicalHandler*)V_UNKNOWN(&value);
2220 return S_OK;
2221 }
2222
2223 if(!memcmp(pProp, wszMaxElementDepth, sizeof(wszMaxElementDepth)))
2224 return E_NOTIMPL;
2225
2226 if(!memcmp(pProp, wszMaxXMLSize, sizeof(wszMaxXMLSize)))
2227 return E_NOTIMPL;
2228
2229 if(!memcmp(pProp, wszSchemaDeclarationHandler,
2230 sizeof(wszSchemaDeclarationHandler)))
2231 return E_NOTIMPL;
2232
2233 if(!memcmp(pProp, wszXMLDeclEncoding, sizeof(wszXMLDeclEncoding)))
2234 return E_FAIL;
2235
2236 if(!memcmp(pProp, wszXMLDeclStandalone, sizeof(wszXMLDeclStandalone)))
2237 return E_FAIL;
2238
2239 if(!memcmp(pProp, wszXMLDeclVersion, sizeof(wszXMLDeclVersion)))
2240 return E_FAIL;
2241
2242 return E_INVALIDARG;
2243 }
2244
2245 /*** IVBSAXXMLReader interface ***/
2246 /*** IUnknown methods ***/
2247 static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject)
2248 {
2249 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2250
2251 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
2252
2253 *ppvObject = NULL;
2254
2255 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2256 IsEqualGUID( riid, &IID_IDispatch ) ||
2257 IsEqualGUID( riid, &IID_IVBSAXXMLReader ))
2258 {
2259 *ppvObject = iface;
2260 }
2261 else if( IsEqualGUID( riid, &IID_ISAXXMLReader ))
2262 {
2263 *ppvObject = &This->lpSAXXMLReaderVtbl;
2264 }
2265 else
2266 {
2267 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2268 return E_NOINTERFACE;
2269 }
2270
2271 IVBSAXXMLReader_AddRef( iface );
2272
2273 return S_OK;
2274 }
2275
2276 static ULONG WINAPI saxxmlreader_AddRef(IVBSAXXMLReader* iface)
2277 {
2278 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2279 TRACE("%p\n", This );
2280 return InterlockedIncrement( &This->ref );
2281 }
2282
2283 static ULONG WINAPI saxxmlreader_Release(
2284 IVBSAXXMLReader* iface)
2285 {
2286 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2287 LONG ref;
2288
2289 TRACE("%p\n", This );
2290
2291 ref = InterlockedDecrement( &This->ref );
2292 if ( ref == 0 )
2293 {
2294 if(This->contentHandler)
2295 ISAXContentHandler_Release(This->contentHandler);
2296
2297 if(This->vbcontentHandler)
2298 IVBSAXContentHandler_Release(This->vbcontentHandler);
2299
2300 if(This->errorHandler)
2301 ISAXErrorHandler_Release(This->errorHandler);
2302
2303 if(This->vberrorHandler)
2304 IVBSAXErrorHandler_Release(This->vberrorHandler);
2305
2306 if(This->lexicalHandler)
2307 ISAXLexicalHandler_Release(This->lexicalHandler);
2308
2309 if(This->vblexicalHandler)
2310 IVBSAXLexicalHandler_Release(This->vblexicalHandler);
2311
2312 if(This->declHandler)
2313 ISAXDeclHandler_Release(This->declHandler);
2314
2315 if(This->vbdeclHandler)
2316 IVBSAXDeclHandler_Release(This->vbdeclHandler);
2317
2318 HeapFree( GetProcessHeap(), 0, This );
2319 }
2320
2321 return ref;
2322 }
2323 /*** IDispatch ***/
2324 static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo )
2325 {
2326 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2327
2328 TRACE("(%p)->(%p)\n", This, pctinfo);
2329
2330 *pctinfo = 1;
2331
2332 return S_OK;
2333 }
2334
2335 static HRESULT WINAPI saxxmlreader_GetTypeInfo(
2336 IVBSAXXMLReader *iface,
2337 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
2338 {
2339 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2340 HRESULT hr;
2341
2342 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
2343
2344 hr = get_typeinfo(IVBSAXXMLReader_tid, ppTInfo);
2345
2346 return hr;
2347 }
2348
2349 static HRESULT WINAPI saxxmlreader_GetIDsOfNames(
2350 IVBSAXXMLReader *iface,
2351 REFIID riid,
2352 LPOLESTR* rgszNames,
2353 UINT cNames,
2354 LCID lcid,
2355 DISPID* rgDispId)
2356 {
2357 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2358 ITypeInfo *typeinfo;
2359 HRESULT hr;
2360
2361 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
2362 lcid, rgDispId);
2363
2364 if(!rgszNames || cNames == 0 || !rgDispId)
2365 return E_INVALIDARG;
2366
2367 hr = get_typeinfo(IVBSAXXMLReader_tid, &typeinfo);
2368 if(SUCCEEDED(hr))
2369 {
2370 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
2371 ITypeInfo_Release(typeinfo);
2372 }
2373
2374 return hr;
2375 }
2376
2377 static HRESULT WINAPI saxxmlreader_Invoke(
2378 IVBSAXXMLReader *iface,
2379 DISPID dispIdMember,
2380 REFIID riid,
2381 LCID lcid,
2382 WORD wFlags,
2383 DISPPARAMS* pDispParams,
2384 VARIANT* pVarResult,
2385 EXCEPINFO* pExcepInfo,
2386 UINT* puArgErr)
2387 {
2388 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2389 ITypeInfo *typeinfo;
2390 HRESULT hr;
2391
2392 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2393 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2394
2395 hr = get_typeinfo(IVBSAXXMLReader_tid, &typeinfo);
2396 if(SUCCEEDED(hr))
2397 {
2398 hr = ITypeInfo_Invoke(typeinfo, &(This->lpVBSAXXMLReaderVtbl), dispIdMember, wFlags, pDispParams,
2399 pVarResult, pExcepInfo, puArgErr);
2400 ITypeInfo_Release(typeinfo);
2401 }
2402
2403 return hr;
2404 }
2405
2406 /*** IVBSAXXMLReader methods ***/
2407 static HRESULT WINAPI saxxmlreader_getFeature(
2408 IVBSAXXMLReader* iface,
2409 const WCHAR *pFeature,
2410 VARIANT_BOOL *pValue)
2411 {
2412 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2413
2414 FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pFeature), pValue);
2415 return E_NOTIMPL;
2416 }
2417
2418 static HRESULT WINAPI saxxmlreader_putFeature(
2419 IVBSAXXMLReader* iface,
2420 const WCHAR *pFeature,
2421 VARIANT_BOOL vfValue)
2422 {
2423 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2424
2425 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(pFeature), vfValue);
2426 return E_NOTIMPL;
2427 }
2428
2429 static HRESULT WINAPI saxxmlreader_getProperty(
2430 IVBSAXXMLReader* iface,
2431 const WCHAR *pProp,
2432 VARIANT *pValue)
2433 {
2434 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2435
2436 FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pProp), pValue);
2437 return E_NOTIMPL;
2438 }
2439
2440 static HRESULT WINAPI saxxmlreader_putProperty(
2441 IVBSAXXMLReader* iface,
2442 const WCHAR *pProp,
2443 VARIANT value)
2444 {
2445 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2446 return internal_putProperty(This, pProp, value, TRUE);
2447 }
2448
2449 static HRESULT WINAPI saxxmlreader_get_entityResolver(
2450 IVBSAXXMLReader* iface,
2451 IVBSAXEntityResolver **pEntityResolver)
2452 {
2453 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2454 return internal_getEntityResolver(This, pEntityResolver, TRUE);
2455 }
2456
2457 static HRESULT WINAPI saxxmlreader_put_entityResolver(
2458 IVBSAXXMLReader* iface,
2459 IVBSAXEntityResolver *pEntityResolver)
2460 {
2461 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2462 return internal_putEntityResolver(This, pEntityResolver, TRUE);
2463 }
2464
2465 static HRESULT WINAPI saxxmlreader_get_contentHandler(
2466 IVBSAXXMLReader* iface,
2467 IVBSAXContentHandler **ppContentHandler)
2468 {
2469 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2470 return internal_getContentHandler(This, ppContentHandler, TRUE);
2471 }
2472
2473 static HRESULT WINAPI saxxmlreader_put_contentHandler(
2474 IVBSAXXMLReader* iface,
2475 IVBSAXContentHandler *contentHandler)
2476 {
2477 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2478 return internal_putContentHandler(This, contentHandler, TRUE);
2479 }
2480
2481 static HRESULT WINAPI saxxmlreader_get_dtdHandler(
2482 IVBSAXXMLReader* iface,
2483 IVBSAXDTDHandler **pDTDHandler)
2484 {
2485 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2486 return internal_getDTDHandler(This, pDTDHandler, TRUE);
2487 }
2488
2489 static HRESULT WINAPI saxxmlreader_put_dtdHandler(
2490 IVBSAXXMLReader* iface,
2491 IVBSAXDTDHandler *pDTDHandler)
2492 {
2493 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2494 return internal_putDTDHandler(This, pDTDHandler, TRUE);
2495 }
2496
2497 static HRESULT WINAPI saxxmlreader_get_errorHandler(
2498 IVBSAXXMLReader* iface,
2499 IVBSAXErrorHandler **pErrorHandler)
2500 {
2501 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2502 return internal_getErrorHandler(This, pErrorHandler, TRUE);
2503 }
2504
2505 static HRESULT WINAPI saxxmlreader_put_errorHandler(
2506 IVBSAXXMLReader* iface,
2507 IVBSAXErrorHandler *errorHandler)
2508 {
2509 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2510 return internal_putErrorHandler(This, errorHandler, TRUE);
2511 }
2512
2513 static HRESULT WINAPI saxxmlreader_get_baseURL(
2514 IVBSAXXMLReader* iface,
2515 const WCHAR **pBaseUrl)
2516 {
2517 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2518
2519 FIXME("(%p)->(%p) stub\n", This, pBaseUrl);
2520 return E_NOTIMPL;
2521 }
2522
2523 static HRESULT WINAPI saxxmlreader_put_baseURL(
2524 IVBSAXXMLReader* iface,
2525 const WCHAR *pBaseUrl)
2526 {
2527 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2528
2529 FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl));
2530 return E_NOTIMPL;
2531 }
2532
2533 static HRESULT WINAPI saxxmlreader_get_secureBaseURL(
2534 IVBSAXXMLReader* iface,
2535 const WCHAR **pSecureBaseUrl)
2536 {
2537 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2538
2539 FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
2540 return E_NOTIMPL;
2541 }
2542
2543
2544 static HRESULT WINAPI saxxmlreader_put_secureBaseURL(
2545 IVBSAXXMLReader* iface,
2546 const WCHAR *secureBaseUrl)
2547 {
2548 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2549
2550 FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl));
2551 return E_NOTIMPL;
2552 }
2553
2554 static HRESULT WINAPI saxxmlreader_parse(
2555 IVBSAXXMLReader* iface,
2556 VARIANT varInput)
2557 {
2558 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2559 return internal_parse(This, varInput, TRUE);
2560 }
2561
2562 static HRESULT WINAPI saxxmlreader_parseURL(
2563 IVBSAXXMLReader* iface,
2564 const WCHAR *url)
2565 {
2566 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2567 return internal_parseURL(This, url, TRUE);
2568 }
2569
2570 static const struct IVBSAXXMLReaderVtbl saxreader_vtbl =
2571 {
2572 saxxmlreader_QueryInterface,
2573 saxxmlreader_AddRef,
2574 saxxmlreader_Release,
2575 saxxmlreader_GetTypeInfoCount,
2576 saxxmlreader_GetTypeInfo,
2577 saxxmlreader_GetIDsOfNames,
2578 saxxmlreader_Invoke,
2579 saxxmlreader_getFeature,
2580 saxxmlreader_putFeature,
2581 saxxmlreader_getProperty,
2582 saxxmlreader_putProperty,
2583 saxxmlreader_get_entityResolver,
2584 saxxmlreader_put_entityResolver,
2585 saxxmlreader_get_contentHandler,
2586 saxxmlreader_put_contentHandler,
2587 saxxmlreader_get_dtdHandler,
2588 saxxmlreader_put_dtdHandler,
2589 saxxmlreader_get_errorHandler,
2590 saxxmlreader_put_errorHandler,
2591 saxxmlreader_get_baseURL,
2592 saxxmlreader_put_baseURL,
2593 saxxmlreader_get_secureBaseURL,
2594 saxxmlreader_put_secureBaseURL,
2595 saxxmlreader_parse,
2596 saxxmlreader_parseURL
2597 };
2598
2599 /*** ISAXXMLReader interface ***/
2600 /*** IUnknown methods ***/
2601 static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject)
2602 {
2603 saxreader *This = impl_from_ISAXXMLReader( iface );
2604 return saxxmlreader_QueryInterface((IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl, riid, ppvObject);
2605 }
2606
2607 static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface)
2608 {
2609 saxreader *This = impl_from_ISAXXMLReader( iface );
2610 return saxxmlreader_AddRef((IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl);
2611 }
2612
2613 static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface)
2614 {
2615 saxreader *This = impl_from_ISAXXMLReader( iface );
2616 return saxxmlreader_Release((IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl);
2617 }
2618
2619 /*** ISAXXMLReader methods ***/
2620 static HRESULT WINAPI isaxxmlreader_getFeature(
2621 ISAXXMLReader* iface,
2622 const WCHAR *pFeature,
2623 VARIANT_BOOL *pValue)
2624 {
2625 saxreader *This = impl_from_ISAXXMLReader( iface );
2626 return IVBSAXXMLReader_getFeature(
2627 (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl,
2628 pFeature, pValue);
2629 }
2630
2631 static HRESULT WINAPI isaxxmlreader_putFeature(
2632 ISAXXMLReader* iface,
2633 const WCHAR *pFeature,
2634 VARIANT_BOOL vfValue)
2635 {
2636 saxreader *This = impl_from_ISAXXMLReader( iface );
2637 return IVBSAXXMLReader_putFeature(
2638 (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl,
2639 pFeature, vfValue);
2640 }
2641
2642 static HRESULT WINAPI isaxxmlreader_getProperty(
2643 ISAXXMLReader* iface,
2644 const WCHAR *pProp,
2645 VARIANT *pValue)
2646 {
2647 saxreader *This = impl_from_ISAXXMLReader( iface );
2648 return IVBSAXXMLReader_getProperty(
2649 (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl,
2650 pProp, pValue);
2651 }
2652
2653 static HRESULT WINAPI isaxxmlreader_putProperty(
2654 ISAXXMLReader* iface,
2655 const WCHAR *pProp,
2656 VARIANT value)
2657 {
2658 saxreader *This = impl_from_ISAXXMLReader( iface );
2659 return internal_putProperty(This, pProp, value, FALSE);
2660 }
2661
2662 static HRESULT WINAPI isaxxmlreader_getEntityResolver(
2663 ISAXXMLReader* iface,
2664 ISAXEntityResolver **ppEntityResolver)
2665 {
2666 saxreader *This = impl_from_ISAXXMLReader( iface );
2667 return internal_getEntityResolver(This, ppEntityResolver, FALSE);
2668 }
2669
2670 static HRESULT WINAPI isaxxmlreader_putEntityResolver(
2671 ISAXXMLReader* iface,
2672 ISAXEntityResolver *pEntityResolver)
2673 {
2674 saxreader *This = impl_from_ISAXXMLReader( iface );
2675 return internal_putEntityResolver(This, pEntityResolver, FALSE);
2676 }
2677
2678 static HRESULT WINAPI isaxxmlreader_getContentHandler(
2679 ISAXXMLReader* iface,
2680 ISAXContentHandler **pContentHandler)
2681 {
2682 saxreader *This = impl_from_ISAXXMLReader( iface );
2683 return internal_getContentHandler(This, pContentHandler, FALSE);
2684 }
2685
2686 static HRESULT WINAPI isaxxmlreader_putContentHandler(
2687 ISAXXMLReader* iface,
2688 ISAXContentHandler *contentHandler)
2689 {
2690 saxreader *This = impl_from_ISAXXMLReader( iface );
2691 return internal_putContentHandler(This, contentHandler, FALSE);
2692 }
2693
2694 static HRESULT WINAPI isaxxmlreader_getDTDHandler(
2695 ISAXXMLReader* iface,
2696 ISAXDTDHandler **pDTDHandler)
2697 {
2698 saxreader *This = impl_from_ISAXXMLReader( iface );
2699 return internal_getDTDHandler(This, pDTDHandler, FALSE);
2700 }
2701
2702 static HRESULT WINAPI isaxxmlreader_putDTDHandler(
2703 ISAXXMLReader* iface,
2704 ISAXDTDHandler *pDTDHandler)
2705 {
2706 saxreader *This = impl_from_ISAXXMLReader( iface );
2707 return internal_putDTDHandler(This, pDTDHandler, FALSE);
2708 }
2709
2710 static HRESULT WINAPI isaxxmlreader_getErrorHandler(
2711 ISAXXMLReader* iface,
2712 ISAXErrorHandler **pErrorHandler)
2713 {
2714 saxreader *This = impl_from_ISAXXMLReader( iface );
2715 return internal_getErrorHandler(This, pErrorHandler, FALSE);
2716 }
2717
2718 static HRESULT WINAPI isaxxmlreader_putErrorHandler(
2719 ISAXXMLReader* iface,
2720 ISAXErrorHandler *errorHandler)
2721 {
2722 saxreader *This = impl_from_ISAXXMLReader( iface );
2723 return internal_putErrorHandler(This, errorHandler, FALSE);
2724 }
2725
2726 static HRESULT WINAPI isaxxmlreader_getBaseURL(
2727 ISAXXMLReader* iface,
2728 const WCHAR **pBaseUrl)
2729 {
2730 saxreader *This = impl_from_ISAXXMLReader( iface );
2731 return IVBSAXXMLReader_get_baseURL(
2732 (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl,
2733 pBaseUrl);
2734 }
2735
2736 static HRESULT WINAPI isaxxmlreader_putBaseURL(
2737 ISAXXMLReader* iface,
2738 const WCHAR *pBaseUrl)
2739 {
2740 saxreader *This = impl_from_ISAXXMLReader( iface );
2741 return IVBSAXXMLReader_put_baseURL(
2742 (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl,
2743 pBaseUrl);
2744 }
2745
2746 static HRESULT WINAPI isaxxmlreader_getSecureBaseURL(
2747 ISAXXMLReader* iface,
2748 const WCHAR **pSecureBaseUrl)
2749 {
2750 saxreader *This = impl_from_ISAXXMLReader( iface );
2751 return IVBSAXXMLReader_get_secureBaseURL(
2752 (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl,
2753 pSecureBaseUrl);
2754 }
2755
2756 static HRESULT WINAPI isaxxmlreader_putSecureBaseURL(
2757 ISAXXMLReader* iface,
2758 const WCHAR *secureBaseUrl)
2759 {
2760 saxreader *This = impl_from_ISAXXMLReader( iface );
2761 return IVBSAXXMLReader_put_secureBaseURL(
2762 (IVBSAXXMLReader*)&This->lpVBSAXXMLReaderVtbl,
2763 secureBaseUrl);
2764 }
2765
2766 static HRESULT WINAPI isaxxmlreader_parse(
2767 ISAXXMLReader* iface,
2768 VARIANT varInput)
2769 {
2770 saxreader *This = impl_from_ISAXXMLReader( iface );
2771 return internal_parse(This, varInput, FALSE);
2772 }
2773
2774 static HRESULT WINAPI isaxxmlreader_parseURL(
2775 ISAXXMLReader* iface,
2776 const WCHAR *url)
2777 {
2778 saxreader *This = impl_from_ISAXXMLReader( iface );
2779 return internal_parseURL(This, url, FALSE);
2780 }
2781
2782 static const struct ISAXXMLReaderVtbl isaxreader_vtbl =
2783 {
2784 isaxxmlreader_QueryInterface,
2785 isaxxmlreader_AddRef,
2786 isaxxmlreader_Release,
2787 isaxxmlreader_getFeature,
2788 isaxxmlreader_putFeature,
2789 isaxxmlreader_getProperty,
2790 isaxxmlreader_putProperty,
2791 isaxxmlreader_getEntityResolver,
2792 isaxxmlreader_putEntityResolver,
2793 isaxxmlreader_getContentHandler,
2794 isaxxmlreader_putContentHandler,
2795 isaxxmlreader_getDTDHandler,
2796 isaxxmlreader_putDTDHandler,
2797 isaxxmlreader_getErrorHandler,
2798 isaxxmlreader_putErrorHandler,
2799 isaxxmlreader_getBaseURL,
2800 isaxxmlreader_putBaseURL,
2801 isaxxmlreader_getSecureBaseURL,
2802 isaxxmlreader_putSecureBaseURL,
2803 isaxxmlreader_parse,
2804 isaxxmlreader_parseURL
2805 };
2806
2807 HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2808 {
2809 saxreader *reader;
2810
2811 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
2812
2813 reader = HeapAlloc( GetProcessHeap(), 0, sizeof (*reader) );
2814 if( !reader )
2815 return E_OUTOFMEMORY;
2816
2817 reader->lpVBSAXXMLReaderVtbl = &saxreader_vtbl;
2818 reader->lpSAXXMLReaderVtbl = &isaxreader_vtbl;
2819 reader->ref = 1;
2820 reader->contentHandler = NULL;
2821 reader->vbcontentHandler = NULL;
2822 reader->errorHandler = NULL;
2823 reader->vberrorHandler = NULL;
2824 reader->lexicalHandler = NULL;
2825 reader->vblexicalHandler = NULL;
2826 reader->declHandler = NULL;
2827 reader->vbdeclHandler = NULL;
2828 reader->isParsing = FALSE;
2829
2830 memset(&reader->sax, 0, sizeof(xmlSAXHandler));
2831 reader->sax.initialized = XML_SAX2_MAGIC;
2832 reader->sax.startDocument = libxmlStartDocument;
2833 reader->sax.endDocument = libxmlEndDocument;
2834 reader->sax.startElementNs = libxmlStartElementNS;
2835 reader->sax.endElementNs = libxmlEndElementNS;
2836 reader->sax.characters = libxmlCharacters;
2837 reader->sax.setDocumentLocator = libxmlSetDocumentLocator;
2838 reader->sax.comment = libxmlComment;
2839 reader->sax.error = libxmlFatalError;
2840 reader->sax.fatalError = libxmlFatalError;
2841 reader->sax.cdataBlock = libxmlCDataBlock;
2842
2843 *ppObj = &reader->lpVBSAXXMLReaderVtbl;
2844
2845 TRACE("returning iface %p\n", *ppObj);
2846
2847 return S_OK;
2848 }
2849
2850 #else
2851
2852 HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj)
2853 {
2854 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
2855 "libxml2 support was not present at compile time.\n");
2856 return E_NOTIMPL;
2857 }
2858
2859 #endif