msxml3: Added IDispatchEx support for SAXReader.
[wine/multimedia.git] / dlls / msxml3 / saxreader.c
blob58918143a6439ccf6275585f74d2d516ae45f72c
1 /*
2 * SAX Reader implementation
4 * Copyright 2008 Alistair Leslie-Hughes
5 * Copyright 2008 Piotr Caban
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.
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.
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
21 #define COBJMACROS
23 #include "config.h"
25 #include <stdarg.h>
26 #ifdef HAVE_LIBXML2
27 # include <libxml/parser.h>
28 # include <libxml/xmlerror.h>
29 # include <libxml/SAX2.h>
30 # include <libxml/parserInternals.h>
31 #endif
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winuser.h"
36 #include "winnls.h"
37 #include "ole2.h"
38 #include "msxml6.h"
39 #include "wininet.h"
40 #include "urlmon.h"
41 #include "winreg.h"
42 #include "shlwapi.h"
44 #include "wine/debug.h"
46 #include "msxml_private.h"
48 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
50 #ifdef HAVE_LIBXML2
52 enum ReaderFeatures
54 ExhaustiveErrors = 1 << 1,
55 ExternalGeneralEntities = 1 << 2,
56 ExternalParameterEntities = 1 << 3,
57 ForcedResync = 1 << 4,
58 NamespacePrefixes = 1 << 5,
59 Namespaces = 1 << 6,
60 ParameterEntities = 1 << 7,
61 PreserveSystemIndentifiers = 1 << 8,
62 ProhibitDTD = 1 << 9,
63 SchemaValidation = 1 << 10,
64 ServerHttpRequest = 1 << 11,
65 SuppressValidationfatalError = 1 << 12,
66 UseInlineSchema = 1 << 13,
67 UseSchemaLocation = 1 << 14,
68 LexicalHandlerParEntities = 1 << 15
71 struct bstrpool
73 BSTR *pool;
74 unsigned int index;
75 unsigned int len;
78 typedef struct _saxreader
80 DispatchEx dispex;
81 IVBSAXXMLReader IVBSAXXMLReader_iface;
82 ISAXXMLReader ISAXXMLReader_iface;
83 LONG ref;
84 struct ISAXContentHandler *contentHandler;
85 struct IVBSAXContentHandler *vbcontentHandler;
86 struct ISAXErrorHandler *errorHandler;
87 struct IVBSAXErrorHandler *vberrorHandler;
88 struct ISAXLexicalHandler *lexicalHandler;
89 struct IVBSAXLexicalHandler *vblexicalHandler;
90 struct ISAXDeclHandler *declHandler;
91 struct IVBSAXDeclHandler *vbdeclHandler;
92 xmlSAXHandler sax;
93 BOOL isParsing;
94 struct bstrpool pool;
95 enum ReaderFeatures features;
96 MSXML_VERSION version;
97 } saxreader;
99 typedef struct _saxlocator
101 IVBSAXLocator IVBSAXLocator_iface;
102 ISAXLocator ISAXLocator_iface;
103 IVBSAXAttributes IVBSAXAttributes_iface;
104 ISAXAttributes ISAXAttributes_iface;
105 LONG ref;
106 saxreader *saxreader;
107 HRESULT ret;
108 xmlParserCtxtPtr pParserCtxt;
109 WCHAR *publicId;
110 WCHAR *systemId;
111 xmlChar *lastCur;
112 int line;
113 int realLine;
114 int column;
115 int realColumn;
116 BOOL vbInterface;
117 int nsStackSize;
118 int nsStackLast;
119 struct nsstack
121 const xmlChar *ptr;
122 BSTR prefix;
123 BSTR uri;
124 } *nsStack;
126 BSTR namespaceUri;
127 int attributesSize;
128 int nb_attributes;
129 struct _attributes
131 BSTR szLocalname;
132 BSTR szURI;
133 BSTR szValue;
134 BSTR szQName;
135 } *attributes;
136 } saxlocator;
138 static inline saxreader *impl_from_IVBSAXXMLReader( IVBSAXXMLReader *iface )
140 return CONTAINING_RECORD(iface, saxreader, IVBSAXXMLReader_iface);
143 static inline saxreader *impl_from_ISAXXMLReader( ISAXXMLReader *iface )
145 return CONTAINING_RECORD(iface, saxreader, ISAXXMLReader_iface);
148 static inline saxlocator *impl_from_IVBSAXLocator( IVBSAXLocator *iface )
150 return CONTAINING_RECORD(iface, saxlocator, IVBSAXLocator_iface);
153 static inline saxlocator *impl_from_ISAXLocator( ISAXLocator *iface )
155 return CONTAINING_RECORD(iface, saxlocator, ISAXLocator_iface);
158 static inline saxlocator *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface )
160 return CONTAINING_RECORD(iface, saxlocator, IVBSAXAttributes_iface);
163 static inline saxlocator *impl_from_ISAXAttributes( ISAXAttributes *iface )
165 return CONTAINING_RECORD(iface, saxlocator, ISAXAttributes_iface);
168 /* property names */
169 static const WCHAR PropertyCharsetW[] = {
170 'c','h','a','r','s','e','t',0
172 static const WCHAR PropertyDeclHandlerW[] = {
173 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
174 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
175 'd','e','c','l','a','r','a','t','i','o','n',
176 '-','h','a','n','d','l','e','r',0
178 static const WCHAR PropertyDomNodeW[] = {
179 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
180 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
181 'd','o','m','-','n','o','d','e',0
183 static const WCHAR PropertyInputSourceW[] = {
184 'i','n','p','u','t','-','s','o','u','r','c','e',0
186 static const WCHAR PropertyLexicalHandlerW[] = {
187 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/',
188 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/',
189 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0
191 static const WCHAR PropertyMaxElementDepthW[] = {
192 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0
194 static const WCHAR PropertyMaxXMLSizeW[] = {
195 'm','a','x','-','x','m','l','-','s','i','z','e',0
197 static const WCHAR PropertySchemaDeclHandlerW[] = {
198 's','c','h','e','m','a','-','d','e','c','l','a','r','a','t','i','o','n','-',
199 'h','a','n','d','l','e','r',0
201 static const WCHAR PropertyXMLDeclEncodingW[] = {
202 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0
204 static const WCHAR PropertyXMLDeclStandaloneW[] = {
205 'x','m','l','d','e','c','l','-','s','t','a','n','d','a','l','o','n','e',0
207 static const WCHAR PropertyXMLDeclVersionW[] = {
208 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0
211 /* feature names */
212 static const WCHAR FeatureExternalGeneralEntitiesW[] = {
213 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/',
214 'f','e','a','t','u','r','e','s','/','e','x','t','e','r','n','a','l','-','g','e','n','e','r','a','l',
215 '-','e','n','t','i','t','i','e','s',0
218 static const WCHAR FeatureExternalParameterEntitiesW[] = {
219 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
220 '/','e','x','t','e','r','n','a','l','-','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0
223 static const WCHAR FeatureLexicalHandlerParEntitiesW[] = {
224 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
225 '/','l','e','x','i','c','a','l','-','h','a','n','d','l','e','r','/','p','a','r','a','m','e','t','e','r','-','e','n','t','i','t','i','e','s',0
228 static const WCHAR FeatureProhibitDTDW[] = {
229 'p','r','o','h','i','b','i','t','-','d','t','d',0
232 static const WCHAR FeatureNamespacesW[] = {
233 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/','s','a','x','/','f','e','a','t','u','r','e','s',
234 '/','n','a','m','e','s','p','a','c','e','s',0
237 static inline HRESULT set_feature_value(saxreader *reader, enum ReaderFeatures feature, VARIANT_BOOL value)
239 if (value == VARIANT_TRUE)
240 reader->features |= feature;
241 else
242 reader->features &= ~feature;
244 return S_OK;
247 static inline HRESULT get_feature_value(const saxreader *reader, enum ReaderFeatures feature, VARIANT_BOOL *value)
249 *value = reader->features & feature ? VARIANT_TRUE : VARIANT_FALSE;
250 return S_OK;
253 static inline BOOL has_content_handler(const saxlocator *locator)
255 return (locator->vbInterface && locator->saxreader->vbcontentHandler) ||
256 (!locator->vbInterface && locator->saxreader->contentHandler);
259 static inline BOOL has_error_handler(const saxlocator *locator)
261 return (locator->vbInterface && locator->saxreader->vberrorHandler) ||
262 (!locator->vbInterface && locator->saxreader->errorHandler);
265 static HRESULT namespacePush(saxlocator *locator, const xmlChar *prefix,
266 const xmlChar *uri)
268 if(locator->nsStackLast>=locator->nsStackSize)
270 struct nsstack *new_stack;
272 new_stack = HeapReAlloc(GetProcessHeap(), 0,
273 locator->nsStack, sizeof(struct nsstack)*locator->nsStackSize*2);
274 if(!new_stack) return E_OUTOFMEMORY;
275 locator->nsStack = new_stack;
276 locator->nsStackSize *= 2;
279 locator->nsStack[locator->nsStackLast].ptr = uri;
280 if(uri)
282 locator->nsStack[locator->nsStackLast].prefix = bstr_from_xmlChar(prefix);
283 if(!locator->nsStack[locator->nsStackLast].prefix)
284 return E_OUTOFMEMORY;
285 locator->nsStack[locator->nsStackLast].uri = bstr_from_xmlChar(uri);
286 if(!locator->nsStack[locator->nsStackLast].uri)
288 SysFreeString(locator->nsStack[locator->nsStackLast].prefix);
289 return E_OUTOFMEMORY;
292 else
294 locator->nsStack[locator->nsStackLast].prefix = NULL;
295 locator->nsStack[locator->nsStackLast].uri = NULL;
298 locator->nsStackLast++;
300 return S_OK;
303 static HRESULT namespacePop(saxlocator *locator)
305 if(locator->nsStackLast == 0)
307 ERR("namespace stack is empty\n");
308 return E_UNEXPECTED;
311 SysFreeString(locator->nsStack[--locator->nsStackLast].prefix);
312 SysFreeString(locator->nsStack[locator->nsStackLast].uri);
313 locator->nsStack[locator->nsStackLast].prefix = NULL;
314 locator->nsStack[locator->nsStackLast].uri = NULL;
315 return S_OK;
318 static BSTR namespaceFind(saxlocator *locator, const xmlChar *ptr)
320 int i;
322 for(i=locator->nsStackLast-1; i>=0; i--)
324 if(ptr == locator->nsStack[i].ptr)
325 return locator->nsStack[i].uri;
328 ERR("namespace not found\n");
329 return NULL;
332 static BOOL bstr_pool_insert(struct bstrpool *pool, BSTR pool_entry)
334 if (!pool->pool)
336 pool->pool = HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(*pool->pool));
337 if (!pool->pool)
338 return FALSE;
340 pool->index = 0;
341 pool->len = 16;
343 else if (pool->index == pool->len)
345 BSTR *realloc = HeapReAlloc(GetProcessHeap(), 0, pool->pool, pool->len * 2 * sizeof(*realloc));
347 if (!realloc)
348 return FALSE;
350 pool->pool = realloc;
351 pool->len *= 2;
354 pool->pool[pool->index++] = pool_entry;
355 return TRUE;
358 static void free_bstr_pool(struct bstrpool *pool)
360 unsigned int i;
362 for (i = 0; i < pool->index; i++)
363 SysFreeString(pool->pool[i]);
365 HeapFree(GetProcessHeap(), 0, pool->pool);
367 pool->pool = NULL;
368 pool->index = pool->len = 0;
371 static BSTR bstr_from_xmlCharN(const xmlChar *buf, int len)
373 DWORD dLen;
374 BSTR bstr;
376 if (!buf)
377 return NULL;
379 dLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0);
380 if(len != -1) dLen++;
381 bstr = SysAllocStringLen(NULL, dLen-1);
382 if (!bstr)
383 return NULL;
384 MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, bstr, dLen);
385 if(len != -1) bstr[dLen-1] = '\0';
387 return bstr;
390 static BSTR QName_from_xmlChar(const xmlChar *prefix, const xmlChar *name)
392 xmlChar *qname;
393 BSTR bstr;
395 if(!name) return NULL;
397 if(!prefix || !*prefix)
398 return bstr_from_xmlChar(name);
400 qname = xmlBuildQName(name, prefix, NULL, 0);
401 bstr = bstr_from_xmlChar(qname);
402 xmlFree(qname);
404 return bstr;
407 static BSTR pooled_bstr_from_xmlChar(struct bstrpool *pool, const xmlChar *buf)
409 BSTR pool_entry = bstr_from_xmlChar(buf);
411 if (pool_entry && !bstr_pool_insert(pool, pool_entry))
413 SysFreeString(pool_entry);
414 return NULL;
417 return pool_entry;
420 static BSTR pooled_bstr_from_xmlCharN(struct bstrpool *pool, const xmlChar *buf, int len)
422 BSTR pool_entry = bstr_from_xmlCharN(buf, len);
424 if (pool_entry && !bstr_pool_insert(pool, pool_entry))
426 SysFreeString(pool_entry);
427 return NULL;
430 return pool_entry;
433 static BSTR pooled_QName_from_xmlChar(struct bstrpool *pool, const xmlChar *prefix, const xmlChar *name)
435 BSTR pool_entry = QName_from_xmlChar(prefix, name);
437 if (pool_entry && !bstr_pool_insert(pool, pool_entry))
439 SysFreeString(pool_entry);
440 return NULL;
443 return pool_entry;
446 static void format_error_message_from_id(saxlocator *This, HRESULT hr)
448 xmlStopParser(This->pParserCtxt);
449 This->ret = hr;
451 if(has_error_handler(This))
453 WCHAR msg[1024];
454 if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
455 NULL, hr, 0, msg, sizeof(msg), NULL))
457 FIXME("MSXML errors not yet supported.\n");
458 msg[0] = '\0';
461 if(This->vbInterface)
463 BSTR bstrMsg = SysAllocString(msg);
464 IVBSAXErrorHandler_fatalError(This->saxreader->vberrorHandler,
465 &This->IVBSAXLocator_iface, &bstrMsg, hr);
466 SysFreeString(bstrMsg);
468 else
469 ISAXErrorHandler_fatalError(This->saxreader->errorHandler,
470 &This->ISAXLocator_iface, msg, hr);
474 static void update_position(saxlocator *This, xmlChar *end)
476 if(This->lastCur == NULL)
478 This->lastCur = (xmlChar*)This->pParserCtxt->input->base;
479 This->realLine = 1;
480 This->realColumn = 1;
482 else if(This->lastCur < This->pParserCtxt->input->base)
484 This->lastCur = (xmlChar*)This->pParserCtxt->input->base;
485 This->realLine = 1;
486 This->realColumn = 1;
489 if(This->pParserCtxt->input->cur<This->lastCur)
491 This->lastCur = (xmlChar*)This->pParserCtxt->input->base;
492 This->realLine -= 1;
493 This->realColumn = 1;
496 if(!end) end = (xmlChar*)This->pParserCtxt->input->cur;
498 while(This->lastCur < end)
500 if(*(This->lastCur) == '\n')
502 This->realLine++;
503 This->realColumn = 1;
505 else if(*(This->lastCur) == '\r' &&
506 (This->lastCur==This->pParserCtxt->input->end ||
507 *(This->lastCur+1)!='\n'))
509 This->realLine++;
510 This->realColumn = 1;
512 else This->realColumn++;
514 This->lastCur++;
516 /* Count multibyte UTF8 encoded characters once */
517 while((*(This->lastCur)&0xC0) == 0x80) This->lastCur++;
520 This->line = This->realLine;
521 This->column = This->realColumn;
524 /*** IVBSAXAttributes interface ***/
525 /*** IUnknown methods ***/
526 static HRESULT WINAPI ivbsaxattributes_QueryInterface(
527 IVBSAXAttributes* iface,
528 REFIID riid,
529 void **ppvObject)
531 saxlocator *This = impl_from_IVBSAXAttributes(iface);
532 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
533 return IVBSAXLocator_QueryInterface(&This->IVBSAXLocator_iface, riid, ppvObject);
536 static ULONG WINAPI ivbsaxattributes_AddRef(IVBSAXAttributes* iface)
538 saxlocator *This = impl_from_IVBSAXAttributes(iface);
539 return ISAXLocator_AddRef(&This->ISAXLocator_iface);
542 static ULONG WINAPI ivbsaxattributes_Release(IVBSAXAttributes* iface)
544 saxlocator *This = impl_from_IVBSAXAttributes(iface);
545 return ISAXLocator_Release(&This->ISAXLocator_iface);
548 /*** IDispatch methods ***/
549 static HRESULT WINAPI ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo )
551 saxlocator *This = impl_from_IVBSAXAttributes( iface );
553 TRACE("(%p)->(%p)\n", This, pctinfo);
555 *pctinfo = 1;
557 return S_OK;
560 static HRESULT WINAPI ivbsaxattributes_GetTypeInfo(
561 IVBSAXAttributes *iface,
562 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
564 saxlocator *This = impl_from_IVBSAXAttributes( iface );
565 HRESULT hr;
567 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
569 hr = get_typeinfo(IVBSAXAttributes_tid, ppTInfo);
571 return hr;
574 static HRESULT WINAPI ivbsaxattributes_GetIDsOfNames(
575 IVBSAXAttributes *iface,
576 REFIID riid,
577 LPOLESTR* rgszNames,
578 UINT cNames,
579 LCID lcid,
580 DISPID* rgDispId)
582 saxlocator *This = impl_from_IVBSAXAttributes( iface );
583 ITypeInfo *typeinfo;
584 HRESULT hr;
586 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
587 lcid, rgDispId);
589 if(!rgszNames || cNames == 0 || !rgDispId)
590 return E_INVALIDARG;
592 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
593 if(SUCCEEDED(hr))
595 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
596 ITypeInfo_Release(typeinfo);
599 return hr;
602 static HRESULT WINAPI ivbsaxattributes_Invoke(
603 IVBSAXAttributes *iface,
604 DISPID dispIdMember,
605 REFIID riid,
606 LCID lcid,
607 WORD wFlags,
608 DISPPARAMS* pDispParams,
609 VARIANT* pVarResult,
610 EXCEPINFO* pExcepInfo,
611 UINT* puArgErr)
613 saxlocator *This = impl_from_IVBSAXAttributes( iface );
614 ITypeInfo *typeinfo;
615 HRESULT hr;
617 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
618 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
620 hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo);
621 if(SUCCEEDED(hr))
623 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags,
624 pDispParams, pVarResult, pExcepInfo, puArgErr);
625 ITypeInfo_Release(typeinfo);
628 return hr;
631 /*** IVBSAXAttributes methods ***/
632 static HRESULT WINAPI ivbsaxattributes_get_length(
633 IVBSAXAttributes* iface,
634 int *nLength)
636 saxlocator *This = impl_from_IVBSAXAttributes( iface );
637 return ISAXAttributes_getLength(&This->ISAXAttributes_iface, nLength);
640 static HRESULT WINAPI ivbsaxattributes_getURI(
641 IVBSAXAttributes* iface,
642 int nIndex,
643 BSTR *uri)
645 int len;
646 saxlocator *This = impl_from_IVBSAXAttributes( iface );
647 return ISAXAttributes_getURI(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)uri, &len);
650 static HRESULT WINAPI ivbsaxattributes_getLocalName(
651 IVBSAXAttributes* iface,
652 int nIndex,
653 BSTR *localName)
655 int len;
656 saxlocator *This = impl_from_IVBSAXAttributes( iface );
657 return ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, nIndex,
658 (const WCHAR**)localName, &len);
661 static HRESULT WINAPI ivbsaxattributes_getQName(
662 IVBSAXAttributes* iface,
663 int nIndex,
664 BSTR *QName)
666 int len;
667 saxlocator *This = impl_from_IVBSAXAttributes( iface );
668 return ISAXAttributes_getQName(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)QName, &len);
671 static HRESULT WINAPI ivbsaxattributes_getIndexFromName(
672 IVBSAXAttributes* iface,
673 BSTR uri,
674 BSTR localName,
675 int *index)
677 saxlocator *This = impl_from_IVBSAXAttributes( iface );
678 return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
679 localName, SysStringLen(localName), index);
682 static HRESULT WINAPI ivbsaxattributes_getIndexFromQName(
683 IVBSAXAttributes* iface,
684 BSTR QName,
685 int *index)
687 saxlocator *This = impl_from_IVBSAXAttributes( iface );
688 return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, QName,
689 SysStringLen(QName), index);
692 static HRESULT WINAPI ivbsaxattributes_getType(
693 IVBSAXAttributes* iface,
694 int nIndex,
695 BSTR *type)
697 int len;
698 saxlocator *This = impl_from_IVBSAXAttributes( iface );
699 return ISAXAttributes_getType(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)type, &len);
702 static HRESULT WINAPI ivbsaxattributes_getTypeFromName(
703 IVBSAXAttributes* iface,
704 BSTR uri,
705 BSTR localName,
706 BSTR *type)
708 int len;
709 saxlocator *This = impl_from_IVBSAXAttributes( iface );
710 return ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
711 localName, SysStringLen(localName), (const WCHAR**)type, &len);
714 static HRESULT WINAPI ivbsaxattributes_getTypeFromQName(
715 IVBSAXAttributes* iface,
716 BSTR QName,
717 BSTR *type)
719 int len;
720 saxlocator *This = impl_from_IVBSAXAttributes( iface );
721 return ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, QName, SysStringLen(QName),
722 (const WCHAR**)type, &len);
725 static HRESULT WINAPI ivbsaxattributes_getValue(
726 IVBSAXAttributes* iface,
727 int nIndex,
728 BSTR *value)
730 int len;
731 saxlocator *This = impl_from_IVBSAXAttributes( iface );
732 return ISAXAttributes_getValue(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)value, &len);
735 static HRESULT WINAPI ivbsaxattributes_getValueFromName(
736 IVBSAXAttributes* iface,
737 BSTR uri,
738 BSTR localName,
739 BSTR *value)
741 int len;
742 saxlocator *This = impl_from_IVBSAXAttributes( iface );
743 return ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri),
744 localName, SysStringLen(localName), (const WCHAR**)value, &len);
747 static HRESULT WINAPI ivbsaxattributes_getValueFromQName(
748 IVBSAXAttributes* iface,
749 BSTR QName,
750 BSTR *value)
752 int len;
753 saxlocator *This = impl_from_IVBSAXAttributes( iface );
754 return ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, QName,
755 SysStringLen(QName), (const WCHAR**)value, &len);
758 static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl =
760 ivbsaxattributes_QueryInterface,
761 ivbsaxattributes_AddRef,
762 ivbsaxattributes_Release,
763 ivbsaxattributes_GetTypeInfoCount,
764 ivbsaxattributes_GetTypeInfo,
765 ivbsaxattributes_GetIDsOfNames,
766 ivbsaxattributes_Invoke,
767 ivbsaxattributes_get_length,
768 ivbsaxattributes_getURI,
769 ivbsaxattributes_getLocalName,
770 ivbsaxattributes_getQName,
771 ivbsaxattributes_getIndexFromName,
772 ivbsaxattributes_getIndexFromQName,
773 ivbsaxattributes_getType,
774 ivbsaxattributes_getTypeFromName,
775 ivbsaxattributes_getTypeFromQName,
776 ivbsaxattributes_getValue,
777 ivbsaxattributes_getValueFromName,
778 ivbsaxattributes_getValueFromQName
781 /*** ISAXAttributes interface ***/
782 /*** IUnknown methods ***/
783 static HRESULT WINAPI isaxattributes_QueryInterface(
784 ISAXAttributes* iface,
785 REFIID riid,
786 void **ppvObject)
788 saxlocator *This = impl_from_ISAXAttributes(iface);
789 TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
790 return ISAXLocator_QueryInterface(&This->ISAXLocator_iface, riid, ppvObject);
793 static ULONG WINAPI isaxattributes_AddRef(ISAXAttributes* iface)
795 saxlocator *This = impl_from_ISAXAttributes(iface);
796 TRACE("%p\n", This);
797 return ISAXLocator_AddRef(&This->ISAXLocator_iface);
800 static ULONG WINAPI isaxattributes_Release(ISAXAttributes* iface)
802 saxlocator *This = impl_from_ISAXAttributes(iface);
804 TRACE("%p\n", This);
805 return ISAXLocator_Release(&This->ISAXLocator_iface);
808 /*** ISAXAttributes methods ***/
809 static HRESULT WINAPI isaxattributes_getLength(
810 ISAXAttributes* iface,
811 int *length)
813 saxlocator *This = impl_from_ISAXAttributes( iface );
815 *length = This->nb_attributes;
816 TRACE("Length set to %d\n", *length);
817 return S_OK;
820 static HRESULT WINAPI isaxattributes_getURI(
821 ISAXAttributes* iface,
822 int index,
823 const WCHAR **url,
824 int *size)
826 saxlocator *This = impl_from_ISAXAttributes( iface );
827 TRACE("(%p)->(%d)\n", This, index);
829 if(index >= This->nb_attributes || index < 0) return E_INVALIDARG;
830 if(!url || !size) return E_POINTER;
832 *size = SysStringLen(This->attributes[index].szURI);
833 *url = This->attributes[index].szURI;
835 TRACE("(%s:%d)\n", debugstr_w(This->attributes[index].szURI), *size);
837 return S_OK;
840 static HRESULT WINAPI isaxattributes_getLocalName(
841 ISAXAttributes* iface,
842 int nIndex,
843 const WCHAR **pLocalName,
844 int *pLocalNameLength)
846 saxlocator *This = impl_from_ISAXAttributes( iface );
847 TRACE("(%p)->(%d)\n", This, nIndex);
849 if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
850 if(!pLocalName || !pLocalNameLength) return E_POINTER;
852 *pLocalNameLength = SysStringLen(This->attributes[nIndex].szLocalname);
853 *pLocalName = This->attributes[nIndex].szLocalname;
855 return S_OK;
858 static HRESULT WINAPI isaxattributes_getQName(
859 ISAXAttributes* iface,
860 int nIndex,
861 const WCHAR **pQName,
862 int *pQNameLength)
864 saxlocator *This = impl_from_ISAXAttributes( iface );
865 TRACE("(%p)->(%d)\n", This, nIndex);
867 if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG;
868 if(!pQName || !pQNameLength) return E_POINTER;
870 *pQNameLength = SysStringLen(This->attributes[nIndex].szQName);
871 *pQName = This->attributes[nIndex].szQName;
873 return S_OK;
876 static HRESULT WINAPI isaxattributes_getName(
877 ISAXAttributes* iface,
878 int index,
879 const WCHAR **uri,
880 int *pUriLength,
881 const WCHAR **localName,
882 int *pLocalNameSize,
883 const WCHAR **QName,
884 int *pQNameLength)
886 saxlocator *This = impl_from_ISAXAttributes( iface );
887 TRACE("(%p)->(%d)\n", This, index);
889 if(index>=This->nb_attributes || index<0) return E_INVALIDARG;
890 if(!uri || !pUriLength || !localName || !pLocalNameSize
891 || !QName || !pQNameLength) return E_POINTER;
893 *pUriLength = SysStringLen(This->attributes[index].szURI);
894 *uri = This->attributes[index].szURI;
895 *pLocalNameSize = SysStringLen(This->attributes[index].szLocalname);
896 *localName = This->attributes[index].szLocalname;
897 *pQNameLength = SysStringLen(This->attributes[index].szQName);
898 *QName = This->attributes[index].szQName;
900 TRACE("(%s, %s, %s)\n", debugstr_w(*uri), debugstr_w(*localName), debugstr_w(*QName));
902 return S_OK;
905 static HRESULT WINAPI isaxattributes_getIndexFromName(
906 ISAXAttributes* iface,
907 const WCHAR *pUri,
908 int cUriLength,
909 const WCHAR *pLocalName,
910 int cocalNameLength,
911 int *index)
913 saxlocator *This = impl_from_ISAXAttributes( iface );
914 int i;
915 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), cUriLength,
916 debugstr_w(pLocalName), cocalNameLength);
918 if(!pUri || !pLocalName || !index) return E_POINTER;
920 for(i=0; i<This->nb_attributes; i++)
922 if(cUriLength!=SysStringLen(This->attributes[i].szURI)
923 || cocalNameLength!=SysStringLen(This->attributes[i].szLocalname))
924 continue;
925 if(cUriLength && memcmp(pUri, This->attributes[i].szURI,
926 sizeof(WCHAR)*cUriLength))
927 continue;
928 if(cocalNameLength && memcmp(pLocalName, This->attributes[i].szLocalname,
929 sizeof(WCHAR)*cocalNameLength))
930 continue;
932 *index = i;
933 return S_OK;
936 return E_INVALIDARG;
939 static HRESULT WINAPI isaxattributes_getIndexFromQName(
940 ISAXAttributes* iface,
941 const WCHAR *pQName,
942 int nQNameLength,
943 int *index)
945 saxlocator *This = impl_from_ISAXAttributes( iface );
946 int i;
947 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQNameLength);
949 if(!pQName || !index) return E_POINTER;
950 if(!nQNameLength) return E_INVALIDARG;
952 for(i=0; i<This->nb_attributes; i++)
954 if(nQNameLength!=SysStringLen(This->attributes[i].szQName)) continue;
955 if(memcmp(pQName, This->attributes[i].szQName, sizeof(WCHAR)*nQNameLength)) continue;
957 *index = i;
958 return S_OK;
961 return E_INVALIDARG;
964 static HRESULT WINAPI isaxattributes_getType(
965 ISAXAttributes* iface,
966 int nIndex,
967 const WCHAR **pType,
968 int *pTypeLength)
970 saxlocator *This = impl_from_ISAXAttributes( iface );
972 FIXME("(%p)->(%d) stub\n", This, nIndex);
973 return E_NOTIMPL;
976 static HRESULT WINAPI isaxattributes_getTypeFromName(
977 ISAXAttributes* iface,
978 const WCHAR *pUri,
979 int nUri,
980 const WCHAR *pLocalName,
981 int nLocalName,
982 const WCHAR **pType,
983 int *nType)
985 saxlocator *This = impl_from_ISAXAttributes( iface );
987 FIXME("(%p)->(%s, %d, %s, %d) stub\n", This, debugstr_w(pUri), nUri,
988 debugstr_w(pLocalName), nLocalName);
989 return E_NOTIMPL;
992 static HRESULT WINAPI isaxattributes_getTypeFromQName(
993 ISAXAttributes* iface,
994 const WCHAR *pQName,
995 int nQName,
996 const WCHAR **pType,
997 int *nType)
999 saxlocator *This = impl_from_ISAXAttributes( iface );
1001 FIXME("(%p)->(%s, %d) stub\n", This, debugstr_w(pQName), nQName);
1002 return E_NOTIMPL;
1005 static HRESULT WINAPI isaxattributes_getValue(
1006 ISAXAttributes* iface,
1007 int index,
1008 const WCHAR **value,
1009 int *nValue)
1011 saxlocator *This = impl_from_ISAXAttributes( iface );
1012 TRACE("(%p)->(%d)\n", This, index);
1014 if(index>=This->nb_attributes || index<0) return E_INVALIDARG;
1015 if(!value || !nValue) return E_POINTER;
1017 *nValue = SysStringLen(This->attributes[index].szValue);
1018 *value = This->attributes[index].szValue;
1020 TRACE("(%s:%d)\n", debugstr_w(*value), *nValue);
1022 return S_OK;
1025 static HRESULT WINAPI isaxattributes_getValueFromName(
1026 ISAXAttributes* iface,
1027 const WCHAR *pUri,
1028 int nUri,
1029 const WCHAR *pLocalName,
1030 int nLocalName,
1031 const WCHAR **pValue,
1032 int *nValue)
1034 HRESULT hr;
1035 int index;
1036 saxlocator *This = impl_from_ISAXAttributes( iface );
1037 TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), nUri,
1038 debugstr_w(pLocalName), nLocalName);
1040 hr = ISAXAttributes_getIndexFromName(iface,
1041 pUri, nUri, pLocalName, nLocalName, &index);
1042 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
1044 return hr;
1047 static HRESULT WINAPI isaxattributes_getValueFromQName(
1048 ISAXAttributes* iface,
1049 const WCHAR *pQName,
1050 int nQName,
1051 const WCHAR **pValue,
1052 int *nValue)
1054 HRESULT hr;
1055 int index;
1056 saxlocator *This = impl_from_ISAXAttributes( iface );
1057 TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQName);
1059 hr = ISAXAttributes_getIndexFromQName(iface, pQName, nQName, &index);
1060 if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue);
1062 return hr;
1065 static const struct ISAXAttributesVtbl isaxattributes_vtbl =
1067 isaxattributes_QueryInterface,
1068 isaxattributes_AddRef,
1069 isaxattributes_Release,
1070 isaxattributes_getLength,
1071 isaxattributes_getURI,
1072 isaxattributes_getLocalName,
1073 isaxattributes_getQName,
1074 isaxattributes_getName,
1075 isaxattributes_getIndexFromName,
1076 isaxattributes_getIndexFromQName,
1077 isaxattributes_getType,
1078 isaxattributes_getTypeFromName,
1079 isaxattributes_getTypeFromQName,
1080 isaxattributes_getValue,
1081 isaxattributes_getValueFromName,
1082 isaxattributes_getValueFromQName
1085 static HRESULT SAXAttributes_populate(saxlocator *locator,
1086 int nb_namespaces, const xmlChar **xmlNamespaces,
1087 int nb_attributes, const xmlChar **xmlAttributes)
1089 static const xmlChar xmlns[] = "xmlns";
1090 static const WCHAR xmlnsW[] = { 'x','m','l','n','s',0 };
1092 struct _attributes *attrs;
1093 int index;
1095 locator->nb_attributes = nb_namespaces+nb_attributes;
1096 if(locator->nb_attributes > locator->attributesSize)
1098 attrs = heap_realloc(locator->attributes, sizeof(struct _attributes)*locator->nb_attributes*2);
1099 if(!attrs)
1101 locator->nb_attributes = 0;
1102 return E_OUTOFMEMORY;
1104 locator->attributes = attrs;
1106 else
1108 attrs = locator->attributes;
1111 for(index=0; index<nb_namespaces; index++)
1113 attrs[nb_attributes+index].szLocalname = SysAllocStringLen(NULL, 0);
1114 attrs[nb_attributes+index].szURI = locator->namespaceUri;
1115 attrs[nb_attributes+index].szValue = bstr_from_xmlChar(xmlNamespaces[2*index+1]);
1116 if(!xmlNamespaces[2*index])
1117 attrs[nb_attributes+index].szQName = SysAllocString(xmlnsW);
1118 else
1119 attrs[nb_attributes+index].szQName = QName_from_xmlChar(xmlns, xmlNamespaces[2*index]);
1122 for(index=0; index<nb_attributes; index++)
1124 attrs[index].szLocalname = bstr_from_xmlChar(xmlAttributes[index*5]);
1125 attrs[index].szURI = namespaceFind(locator, xmlAttributes[index*5+2]);
1126 attrs[index].szValue = bstr_from_xmlCharN(xmlAttributes[index*5+3],
1127 xmlAttributes[index*5+4]-xmlAttributes[index*5+3]);
1128 attrs[index].szQName = QName_from_xmlChar(xmlAttributes[index*5+1],
1129 xmlAttributes[index*5]);
1132 return S_OK;
1135 /*** LibXML callbacks ***/
1136 static void libxmlStartDocument(void *ctx)
1138 saxlocator *This = ctx;
1139 HRESULT hr;
1141 if(This->saxreader->version >= MSXML6) {
1142 xmlChar *end = (xmlChar*)This->pParserCtxt->input->cur;
1143 while(end>This->pParserCtxt->input->base && *end!='>')
1144 end--;
1145 update_position(This, end);
1148 if(has_content_handler(This))
1150 if(This->vbInterface)
1151 hr = IVBSAXContentHandler_startDocument(This->saxreader->vbcontentHandler);
1152 else
1153 hr = ISAXContentHandler_startDocument(This->saxreader->contentHandler);
1155 if(This->saxreader->version>=MSXML6 ? FAILED(hr) : hr!=S_OK)
1156 format_error_message_from_id(This, hr);
1159 update_position(This, NULL);
1162 static void libxmlEndDocument(void *ctx)
1164 saxlocator *This = ctx;
1165 HRESULT hr;
1167 if(This->saxreader->version >= MSXML6) {
1168 update_position(This, NULL);
1169 if(This->column > 1)
1170 This->line++;
1171 This->column = 0;
1172 } else {
1173 This->column = 0;
1174 This->line = 0;
1177 if(This->ret != S_OK) return;
1179 if(has_content_handler(This))
1181 if(This->vbInterface)
1182 hr = IVBSAXContentHandler_endDocument(This->saxreader->vbcontentHandler);
1183 else
1184 hr = ISAXContentHandler_endDocument(This->saxreader->contentHandler);
1186 if(This->saxreader->version>=MSXML6 ? FAILED(hr) : hr!=S_OK)
1187 format_error_message_from_id(This, hr);
1191 static void libxmlStartElementNS(
1192 void *ctx,
1193 const xmlChar *localname,
1194 const xmlChar *prefix,
1195 const xmlChar *URI,
1196 int nb_namespaces,
1197 const xmlChar **namespaces,
1198 int nb_attributes,
1199 int nb_defaulted,
1200 const xmlChar **attributes)
1202 BSTR NamespaceUri, LocalName, QName;
1203 saxlocator *This = ctx;
1204 HRESULT hr;
1205 int index;
1207 index = 0;
1208 if(*(This->pParserCtxt->input->cur) == '/')
1209 index++;
1210 if(This->saxreader->version < MSXML6)
1211 index++;
1212 update_position(This, (xmlChar*)This->pParserCtxt->input->cur+index);
1214 hr = namespacePush(This, NULL, NULL);
1215 for(index=0; hr==S_OK && index<nb_namespaces; index++)
1216 hr = namespacePush(This, namespaces[2*index], namespaces[2*index+1]);
1217 if(hr != S_OK)
1219 for(; index>=0; index--)
1220 namespacePop(This);
1221 namespacePop(This);
1224 if(hr==S_OK && has_content_handler(This))
1226 for(index=0; index<nb_namespaces; index++)
1228 if(This->vbInterface)
1229 hr = IVBSAXContentHandler_startPrefixMapping(
1230 This->saxreader->vbcontentHandler,
1231 &This->nsStack[This->nsStackLast-nb_namespaces+index].prefix,
1232 &This->nsStack[This->nsStackLast-nb_namespaces+index].uri);
1233 else
1234 hr = ISAXContentHandler_startPrefixMapping(
1235 This->saxreader->contentHandler,
1236 This->nsStack[This->nsStackLast-nb_namespaces+index].prefix,
1237 SysStringLen(This->nsStack[This->nsStackLast-nb_namespaces+index].prefix),
1238 This->nsStack[This->nsStackLast-nb_namespaces+index].uri,
1239 SysStringLen(This->nsStack[This->nsStackLast-nb_namespaces+index].uri));
1241 if(This->saxreader->version>=MSXML6 ? FAILED(hr) : hr!=S_OK)
1243 format_error_message_from_id(This, hr);
1244 return;
1248 NamespaceUri = namespaceFind(This, URI);
1249 LocalName = pooled_bstr_from_xmlChar(&This->saxreader->pool, localname);
1250 QName = pooled_QName_from_xmlChar(&This->saxreader->pool, prefix, localname);
1252 hr = SAXAttributes_populate(This, nb_namespaces, namespaces, nb_attributes, attributes);
1253 if(hr == S_OK)
1255 if(This->vbInterface)
1256 hr = IVBSAXContentHandler_startElement(This->saxreader->vbcontentHandler,
1257 &NamespaceUri, &LocalName, &QName, &This->IVBSAXAttributes_iface);
1258 else
1259 hr = ISAXContentHandler_startElement(This->saxreader->contentHandler, NamespaceUri,
1260 SysStringLen(NamespaceUri), LocalName, SysStringLen(LocalName), QName,
1261 SysStringLen(QName), &This->ISAXAttributes_iface);
1265 if(This->saxreader->version>=MSXML6 ? FAILED(hr) : hr!=S_OK)
1266 format_error_message_from_id(This, hr);
1269 static void libxmlEndElementNS(
1270 void *ctx,
1271 const xmlChar *localname,
1272 const xmlChar *prefix,
1273 const xmlChar *URI)
1275 BSTR NamespaceUri, LocalName, QName;
1276 saxlocator *This = ctx;
1277 HRESULT hr;
1278 xmlChar *end;
1279 struct nsstack *elem = &This->nsStack[This->nsStackLast-1];
1281 end = (xmlChar*)This->pParserCtxt->input->cur;
1282 if(This->saxreader->version >= MSXML6) {
1283 while(end>This->pParserCtxt->input->base && *end!='>')
1284 end--;
1285 } else if(*(end-1) != '>' || *(end-2) != '/') {
1286 while(end-2>=This->pParserCtxt->input->base
1287 && *(end-2)!='<' && *(end-1)!='/') end--;
1290 update_position(This, end);
1292 if(has_content_handler(This))
1294 NamespaceUri = namespaceFind(This, URI);
1295 LocalName = pooled_bstr_from_xmlChar(&This->saxreader->pool, localname);
1296 QName = pooled_QName_from_xmlChar(&This->saxreader->pool, prefix, localname);
1298 if(This->vbInterface)
1299 hr = IVBSAXContentHandler_endElement(
1300 This->saxreader->vbcontentHandler,
1301 &NamespaceUri, &LocalName, &QName);
1302 else
1303 hr = ISAXContentHandler_endElement(
1304 This->saxreader->contentHandler,
1305 NamespaceUri, SysStringLen(NamespaceUri),
1306 LocalName, SysStringLen(LocalName),
1307 QName, SysStringLen(QName));
1309 This->nb_attributes = 0;
1311 if(This->saxreader->version>=MSXML6 ? FAILED(hr) : hr!=S_OK)
1313 format_error_message_from_id(This, hr);
1314 return;
1317 if(This->saxreader->version >= MSXML6)
1319 while(elem->ptr) {
1320 elem--;
1322 elem++;
1324 while(elem < &This->nsStack[This->nsStackLast]) {
1325 if(This->vbInterface)
1326 hr = IVBSAXContentHandler_endPrefixMapping(
1327 This->saxreader->vbcontentHandler, &elem->prefix);
1328 else
1329 hr = ISAXContentHandler_endPrefixMapping(
1330 This->saxreader->contentHandler,
1331 elem->prefix, SysStringLen(elem->prefix));
1333 if(hr != S_OK)
1335 format_error_message_from_id(This, hr);
1336 return;
1339 elem++;
1342 elem--;
1343 while(elem->ptr) {
1344 namespacePop(This);
1345 elem--;
1348 else
1350 while(1) {
1351 if(!elem->ptr)
1352 break;
1354 if(This->vbInterface)
1355 hr = IVBSAXContentHandler_endPrefixMapping(
1356 This->saxreader->vbcontentHandler, &elem->prefix);
1357 else
1358 hr = ISAXContentHandler_endPrefixMapping(
1359 This->saxreader->contentHandler,
1360 elem->prefix, SysStringLen(elem->prefix));
1362 if(FAILED(hr))
1364 format_error_message_from_id(This, hr);
1365 return;
1368 namespacePop(This);
1369 elem--;
1373 else
1375 This->nb_attributes = 0;
1376 while(elem->ptr) {
1377 namespacePop(This);
1378 elem--;
1381 namespacePop(This);
1383 update_position(This, NULL);
1386 static void libxmlCharacters(
1387 void *ctx,
1388 const xmlChar *ch,
1389 int len)
1391 saxlocator *This = ctx;
1392 BSTR Chars;
1393 HRESULT hr;
1394 xmlChar *cur;
1395 xmlChar *end;
1396 BOOL lastEvent = FALSE;
1398 if(!(has_content_handler(This))) return;
1400 cur = (xmlChar*)ch;
1401 if(*(ch-1)=='\r') cur--;
1402 end = cur;
1404 if(ch<This->pParserCtxt->input->base || ch>This->pParserCtxt->input->end)
1405 This->column++;
1407 while(1)
1409 while(end-ch<len && *end!='\r') end++;
1410 if(end-ch==len)
1412 end--;
1413 lastEvent = TRUE;
1416 if(!lastEvent) *end = '\n';
1418 if(This->saxreader->version >= MSXML6) {
1419 update_position(This, end);
1420 if(*end == '\n') {
1421 This->line++;
1422 This->column = 1;
1423 } else
1424 This->column++;
1426 if(!lastEvent)
1427 This->column = 0;
1430 Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur+1);
1431 if(This->vbInterface)
1432 hr = IVBSAXContentHandler_characters(
1433 This->saxreader->vbcontentHandler, &Chars);
1434 else
1435 hr = ISAXContentHandler_characters(
1436 This->saxreader->contentHandler,
1437 Chars, SysStringLen(Chars));
1439 if(This->saxreader->version>=MSXML6 ? FAILED(hr) : hr!=S_OK)
1441 format_error_message_from_id(This, hr);
1442 return;
1445 This->column += end-cur+1;
1447 if(lastEvent)
1448 break;
1450 *end = '\r';
1451 end++;
1452 if(*end == '\n')
1454 end++;
1455 This->column++;
1457 cur = end;
1459 if(end-ch == len) break;
1462 if(ch<This->pParserCtxt->input->base || ch>This->pParserCtxt->input->end)
1463 This->column = This->realColumn
1464 +This->pParserCtxt->input->cur-This->lastCur;
1467 static void libxmlSetDocumentLocator(
1468 void *ctx,
1469 xmlSAXLocatorPtr loc)
1471 saxlocator *This = ctx;
1472 HRESULT hr = S_OK;
1474 if(has_content_handler(This))
1476 if(This->vbInterface)
1477 hr = IVBSAXContentHandler_putref_documentLocator(This->saxreader->vbcontentHandler,
1478 &This->IVBSAXLocator_iface);
1479 else
1480 hr = ISAXContentHandler_putDocumentLocator(This->saxreader->contentHandler,
1481 &This->ISAXLocator_iface);
1484 if(FAILED(hr))
1485 format_error_message_from_id(This, hr);
1488 static void libxmlComment(void *ctx, const xmlChar *value)
1490 saxlocator *This = ctx;
1491 BSTR bValue;
1492 HRESULT hr;
1493 xmlChar *beg = (xmlChar*)This->pParserCtxt->input->cur;
1495 while(beg-4>=This->pParserCtxt->input->base
1496 && memcmp(beg-4, "<!--", sizeof(char[4]))) beg--;
1497 update_position(This, beg);
1499 if(!This->vbInterface && !This->saxreader->lexicalHandler) return;
1500 if(This->vbInterface && !This->saxreader->vblexicalHandler) return;
1502 bValue = pooled_bstr_from_xmlChar(&This->saxreader->pool, value);
1504 if(This->vbInterface)
1505 hr = IVBSAXLexicalHandler_comment(
1506 This->saxreader->vblexicalHandler, &bValue);
1507 else
1508 hr = ISAXLexicalHandler_comment(
1509 This->saxreader->lexicalHandler,
1510 bValue, SysStringLen(bValue));
1512 if(FAILED(hr))
1513 format_error_message_from_id(This, hr);
1515 update_position(This, NULL);
1518 static void libxmlFatalError(void *ctx, const char *msg, ...)
1520 saxlocator *This = ctx;
1521 char message[1024];
1522 WCHAR *error;
1523 DWORD len;
1524 va_list args;
1526 if(This->ret != S_OK) {
1527 xmlStopParser(This->pParserCtxt);
1528 return;
1531 va_start(args, msg);
1532 vsprintf(message, msg, args);
1533 va_end(args);
1535 len = MultiByteToWideChar(CP_UNIXCP, 0, message, -1, NULL, 0);
1536 error = heap_alloc(sizeof(WCHAR)*len);
1537 if(error)
1539 MultiByteToWideChar(CP_UNIXCP, 0, message, -1, error, len);
1540 TRACE("fatal error for %p: %s\n", This, debugstr_w(error));
1543 if(!has_error_handler(This))
1545 xmlStopParser(This->pParserCtxt);
1546 This->ret = E_FAIL;
1547 heap_free(error);
1548 return;
1551 FIXME("Error handling is not compatible.\n");
1553 if(This->vbInterface)
1555 BSTR bstrError = SysAllocString(error);
1556 IVBSAXErrorHandler_fatalError(This->saxreader->vberrorHandler, &This->IVBSAXLocator_iface,
1557 &bstrError, E_FAIL);
1558 SysFreeString(bstrError);
1560 else
1561 ISAXErrorHandler_fatalError(This->saxreader->errorHandler, &This->ISAXLocator_iface,
1562 error, E_FAIL);
1564 heap_free(error);
1566 xmlStopParser(This->pParserCtxt);
1567 This->ret = E_FAIL;
1570 static void libxmlCDataBlock(void *ctx, const xmlChar *value, int len)
1572 saxlocator *This = ctx;
1573 HRESULT hr = S_OK;
1574 xmlChar *beg = (xmlChar*)This->pParserCtxt->input->cur-len;
1575 xmlChar *cur, *end;
1576 int realLen;
1577 BSTR Chars;
1578 BOOL lastEvent = FALSE, change;
1580 while(beg-9>=This->pParserCtxt->input->base
1581 && memcmp(beg-9, "<![CDATA[", sizeof(char[9]))) beg--;
1582 update_position(This, beg);
1584 if(This->vbInterface && This->saxreader->vblexicalHandler)
1585 hr = IVBSAXLexicalHandler_startCDATA(This->saxreader->vblexicalHandler);
1586 if(!This->vbInterface && This->saxreader->lexicalHandler)
1587 hr = ISAXLexicalHandler_startCDATA(This->saxreader->lexicalHandler);
1589 if(FAILED(hr))
1591 format_error_message_from_id(This, hr);
1592 return;
1595 realLen = This->pParserCtxt->input->cur-beg-3;
1596 cur = beg;
1597 end = beg;
1599 while(1)
1601 while(end-beg<realLen && *end!='\r') end++;
1602 if(end-beg==realLen)
1604 end--;
1605 lastEvent = TRUE;
1607 else if(end-beg==realLen-1 && *end=='\r' && *(end+1)=='\n')
1608 lastEvent = TRUE;
1610 if(*end == '\r') change = TRUE;
1611 else change = FALSE;
1613 if(change) *end = '\n';
1615 if(has_content_handler(This))
1617 Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur+1);
1618 if(This->vbInterface)
1619 hr = IVBSAXContentHandler_characters(
1620 This->saxreader->vbcontentHandler, &Chars);
1621 else
1622 hr = ISAXContentHandler_characters(
1623 This->saxreader->contentHandler,
1624 Chars, SysStringLen(Chars));
1627 if(change) *end = '\r';
1629 if(lastEvent)
1630 break;
1632 This->column += end-cur+2;
1633 end += 2;
1634 cur = end;
1637 if(This->vbInterface && This->saxreader->vblexicalHandler)
1638 hr = IVBSAXLexicalHandler_endCDATA(This->saxreader->vblexicalHandler);
1639 if(!This->vbInterface && This->saxreader->lexicalHandler)
1640 hr = ISAXLexicalHandler_endCDATA(This->saxreader->lexicalHandler);
1642 if(FAILED(hr))
1643 format_error_message_from_id(This, hr);
1645 This->column += 4+end-cur;
1648 /*** IVBSAXLocator interface ***/
1649 /*** IUnknown methods ***/
1650 static HRESULT WINAPI ivbsaxlocator_QueryInterface(IVBSAXLocator* iface, REFIID riid, void **ppvObject)
1652 saxlocator *This = impl_from_IVBSAXLocator( iface );
1654 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject);
1656 *ppvObject = NULL;
1658 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
1659 IsEqualGUID( riid, &IID_IDispatch) ||
1660 IsEqualGUID( riid, &IID_IVBSAXLocator ))
1662 *ppvObject = iface;
1664 else if ( IsEqualGUID( riid, &IID_IVBSAXAttributes ))
1666 *ppvObject = &This->IVBSAXAttributes_iface;
1668 else
1670 FIXME("interface %s not implemented\n", debugstr_guid(riid));
1671 return E_NOINTERFACE;
1674 IVBSAXLocator_AddRef( iface );
1676 return S_OK;
1679 static ULONG WINAPI ivbsaxlocator_AddRef(IVBSAXLocator* iface)
1681 saxlocator *This = impl_from_IVBSAXLocator( iface );
1682 TRACE("%p\n", This );
1683 return InterlockedIncrement( &This->ref );
1686 static ULONG WINAPI ivbsaxlocator_Release(
1687 IVBSAXLocator* iface)
1689 saxlocator *This = impl_from_IVBSAXLocator( iface );
1690 return ISAXLocator_Release((ISAXLocator*)&This->IVBSAXLocator_iface);
1693 /*** IDispatch methods ***/
1694 static HRESULT WINAPI ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator *iface, UINT* pctinfo )
1696 saxlocator *This = impl_from_IVBSAXLocator( iface );
1698 TRACE("(%p)->(%p)\n", This, pctinfo);
1700 *pctinfo = 1;
1702 return S_OK;
1705 static HRESULT WINAPI ivbsaxlocator_GetTypeInfo(
1706 IVBSAXLocator *iface,
1707 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
1709 saxlocator *This = impl_from_IVBSAXLocator( iface );
1710 HRESULT hr;
1712 TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1714 hr = get_typeinfo(IVBSAXLocator_tid, ppTInfo);
1716 return hr;
1719 static HRESULT WINAPI ivbsaxlocator_GetIDsOfNames(
1720 IVBSAXLocator *iface,
1721 REFIID riid,
1722 LPOLESTR* rgszNames,
1723 UINT cNames,
1724 LCID lcid,
1725 DISPID* rgDispId)
1727 saxlocator *This = impl_from_IVBSAXLocator( iface );
1728 ITypeInfo *typeinfo;
1729 HRESULT hr;
1731 TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1732 lcid, rgDispId);
1734 if(!rgszNames || cNames == 0 || !rgDispId)
1735 return E_INVALIDARG;
1737 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo);
1738 if(SUCCEEDED(hr))
1740 hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId);
1741 ITypeInfo_Release(typeinfo);
1744 return hr;
1747 static HRESULT WINAPI ivbsaxlocator_Invoke(
1748 IVBSAXLocator *iface,
1749 DISPID dispIdMember,
1750 REFIID riid,
1751 LCID lcid,
1752 WORD wFlags,
1753 DISPPARAMS* pDispParams,
1754 VARIANT* pVarResult,
1755 EXCEPINFO* pExcepInfo,
1756 UINT* puArgErr)
1758 saxlocator *This = impl_from_IVBSAXLocator( iface );
1759 ITypeInfo *typeinfo;
1760 HRESULT hr;
1762 TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1763 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1765 hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo);
1766 if(SUCCEEDED(hr))
1768 hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXLocator_iface, dispIdMember, wFlags,
1769 pDispParams, pVarResult, pExcepInfo, puArgErr);
1770 ITypeInfo_Release(typeinfo);
1773 return hr;
1776 /*** IVBSAXLocator methods ***/
1777 static HRESULT WINAPI ivbsaxlocator_get_columnNumber(
1778 IVBSAXLocator* iface,
1779 int *pnColumn)
1781 saxlocator *This = impl_from_IVBSAXLocator( iface );
1782 return ISAXLocator_getColumnNumber((ISAXLocator*)&This->IVBSAXLocator_iface, pnColumn);
1785 static HRESULT WINAPI ivbsaxlocator_get_lineNumber(
1786 IVBSAXLocator* iface,
1787 int *pnLine)
1789 saxlocator *This = impl_from_IVBSAXLocator( iface );
1790 return ISAXLocator_getLineNumber((ISAXLocator*)&This->IVBSAXLocator_iface, pnLine);
1793 static HRESULT WINAPI ivbsaxlocator_get_publicId(
1794 IVBSAXLocator* iface,
1795 BSTR* publicId)
1797 saxlocator *This = impl_from_IVBSAXLocator( iface );
1798 return ISAXLocator_getPublicId((ISAXLocator*)&This->IVBSAXLocator_iface,
1799 (const WCHAR**)publicId);
1802 static HRESULT WINAPI ivbsaxlocator_get_systemId(
1803 IVBSAXLocator* iface,
1804 BSTR* systemId)
1806 saxlocator *This = impl_from_IVBSAXLocator( iface );
1807 return ISAXLocator_getSystemId((ISAXLocator*)&This->IVBSAXLocator_iface,
1808 (const WCHAR**)systemId);
1811 static const struct IVBSAXLocatorVtbl ivbsaxlocator_vtbl =
1813 ivbsaxlocator_QueryInterface,
1814 ivbsaxlocator_AddRef,
1815 ivbsaxlocator_Release,
1816 ivbsaxlocator_GetTypeInfoCount,
1817 ivbsaxlocator_GetTypeInfo,
1818 ivbsaxlocator_GetIDsOfNames,
1819 ivbsaxlocator_Invoke,
1820 ivbsaxlocator_get_columnNumber,
1821 ivbsaxlocator_get_lineNumber,
1822 ivbsaxlocator_get_publicId,
1823 ivbsaxlocator_get_systemId
1826 /*** ISAXLocator interface ***/
1827 /*** IUnknown methods ***/
1828 static HRESULT WINAPI isaxlocator_QueryInterface(ISAXLocator* iface, REFIID riid, void **ppvObject)
1830 saxlocator *This = impl_from_ISAXLocator( iface );
1832 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
1834 *ppvObject = NULL;
1836 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
1837 IsEqualGUID( riid, &IID_ISAXLocator ))
1839 *ppvObject = iface;
1841 else if ( IsEqualGUID( riid, &IID_ISAXAttributes ))
1843 *ppvObject = &This->ISAXAttributes_iface;
1845 else
1847 FIXME("interface %s not implemented\n", debugstr_guid(riid));
1848 return E_NOINTERFACE;
1851 ISAXLocator_AddRef( iface );
1853 return S_OK;
1856 static ULONG WINAPI isaxlocator_AddRef(ISAXLocator* iface)
1858 saxlocator *This = impl_from_ISAXLocator( iface );
1859 TRACE("%p\n", This );
1860 return InterlockedIncrement( &This->ref );
1863 static ULONG WINAPI isaxlocator_Release(
1864 ISAXLocator* iface)
1866 saxlocator *This = impl_from_ISAXLocator( iface );
1867 LONG ref;
1869 TRACE("%p\n", This );
1871 ref = InterlockedDecrement( &This->ref );
1872 if ( ref == 0 )
1874 int index;
1876 SysFreeString(This->publicId);
1877 SysFreeString(This->systemId);
1878 SysFreeString(This->namespaceUri);
1879 while(This->nsStackLast)
1880 namespacePop(This);
1881 heap_free(This->nsStack);
1883 for(index=0; index<This->nb_attributes; index++)
1885 SysFreeString(This->attributes[index].szLocalname);
1886 SysFreeString(This->attributes[index].szValue);
1887 SysFreeString(This->attributes[index].szQName);
1889 heap_free(This->attributes);
1891 ISAXXMLReader_Release(&This->saxreader->ISAXXMLReader_iface);
1892 heap_free( This );
1895 return ref;
1898 /*** ISAXLocator methods ***/
1899 static HRESULT WINAPI isaxlocator_getColumnNumber(
1900 ISAXLocator* iface,
1901 int *pnColumn)
1903 saxlocator *This = impl_from_ISAXLocator( iface );
1905 *pnColumn = This->column;
1906 return S_OK;
1909 static HRESULT WINAPI isaxlocator_getLineNumber(
1910 ISAXLocator* iface,
1911 int *pnLine)
1913 saxlocator *This = impl_from_ISAXLocator( iface );
1915 *pnLine = This->line;
1916 return S_OK;
1919 static HRESULT WINAPI isaxlocator_getPublicId(
1920 ISAXLocator* iface,
1921 const WCHAR ** ppwchPublicId)
1923 BSTR publicId;
1924 saxlocator *This = impl_from_ISAXLocator( iface );
1926 SysFreeString(This->publicId);
1928 publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt));
1929 if(SysStringLen(publicId))
1930 This->publicId = (WCHAR*)&publicId;
1931 else
1933 SysFreeString(publicId);
1934 This->publicId = NULL;
1937 *ppwchPublicId = This->publicId;
1938 return S_OK;
1941 static HRESULT WINAPI isaxlocator_getSystemId(
1942 ISAXLocator* iface,
1943 const WCHAR ** ppwchSystemId)
1945 BSTR systemId;
1946 saxlocator *This = impl_from_ISAXLocator( iface );
1948 SysFreeString(This->systemId);
1950 systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt));
1951 if(SysStringLen(systemId))
1952 This->systemId = (WCHAR*)&systemId;
1953 else
1955 SysFreeString(systemId);
1956 This->systemId = NULL;
1959 *ppwchSystemId = This->systemId;
1960 return S_OK;
1963 static const struct ISAXLocatorVtbl isaxlocator_vtbl =
1965 isaxlocator_QueryInterface,
1966 isaxlocator_AddRef,
1967 isaxlocator_Release,
1968 isaxlocator_getColumnNumber,
1969 isaxlocator_getLineNumber,
1970 isaxlocator_getPublicId,
1971 isaxlocator_getSystemId
1974 static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator, BOOL vbInterface)
1976 static const WCHAR w3xmlns[] = { 'h','t','t','p',':','/','/', 'w','w','w','.','w','3','.',
1977 'o','r','g','/','2','0','0','0','/','x','m','l','n','s','/',0 };
1979 saxlocator *locator;
1981 locator = heap_alloc( sizeof (*locator) );
1982 if( !locator )
1983 return E_OUTOFMEMORY;
1985 locator->IVBSAXLocator_iface.lpVtbl = &ivbsaxlocator_vtbl;
1986 locator->ISAXLocator_iface.lpVtbl = &isaxlocator_vtbl;
1987 locator->IVBSAXAttributes_iface.lpVtbl = &ivbsaxattributes_vtbl;
1988 locator->ISAXAttributes_iface.lpVtbl = &isaxattributes_vtbl;
1989 locator->ref = 1;
1990 locator->vbInterface = vbInterface;
1992 locator->saxreader = reader;
1993 ISAXXMLReader_AddRef(&reader->ISAXXMLReader_iface);
1995 locator->pParserCtxt = NULL;
1996 locator->publicId = NULL;
1997 locator->systemId = NULL;
1998 locator->lastCur = NULL;
1999 locator->line = (reader->version>=MSXML6 ? 1 : 0);
2000 locator->column = 0;
2001 locator->ret = S_OK;
2002 if(locator->saxreader->version >= MSXML6)
2003 locator->namespaceUri = SysAllocString(w3xmlns);
2004 else
2005 locator->namespaceUri = SysAllocStringLen(NULL, 0);
2006 if(!locator->namespaceUri)
2008 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
2009 heap_free(locator);
2010 return E_OUTOFMEMORY;
2012 locator->nsStackSize = 8;
2013 locator->nsStackLast = 0;
2014 locator->nsStack = heap_alloc(sizeof(struct nsstack)*locator->nsStackSize);
2015 if(!locator->nsStack)
2017 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
2018 SysFreeString(locator->namespaceUri);
2019 heap_free(locator);
2020 return E_OUTOFMEMORY;
2023 locator->attributesSize = 8;
2024 locator->nb_attributes = 0;
2025 locator->attributes = heap_alloc(sizeof(struct _attributes)*locator->attributesSize);
2026 if(!locator->attributes)
2028 ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);
2029 SysFreeString(locator->namespaceUri);
2030 heap_free(locator->nsStack);
2031 heap_free(locator);
2032 return E_OUTOFMEMORY;
2035 *ppsaxlocator = locator;
2037 TRACE("returning %p\n", *ppsaxlocator);
2039 return S_OK;
2042 /*** SAXXMLReader internal functions ***/
2043 static HRESULT internal_parseBuffer(saxreader *This, const char *buffer, int size, BOOL vbInterface)
2045 xmlCharEncoding encoding = XML_CHAR_ENCODING_NONE;
2046 xmlChar *enc_name = NULL;
2047 saxlocator *locator;
2048 HRESULT hr;
2050 hr = SAXLocator_create(This, &locator, vbInterface);
2051 if(FAILED(hr))
2052 return hr;
2054 if (size >= 4)
2056 const unsigned char *buff = (unsigned char*)buffer;
2058 encoding = xmlDetectCharEncoding((xmlChar*)buffer, 4);
2059 enc_name = (xmlChar*)xmlGetCharEncodingName(encoding);
2060 TRACE("detected encoding: %s\n", enc_name);
2061 /* skip BOM, parser won't switch encodings and so won't skip it on its own */
2062 if ((encoding == XML_CHAR_ENCODING_UTF8) &&
2063 buff[0] == 0xEF && buff[1] == 0xBB && buff[2] == 0xBF)
2065 buffer += 3;
2066 size -= 3;
2070 locator->pParserCtxt = xmlCreateMemoryParserCtxt(buffer, size);
2071 if(!locator->pParserCtxt)
2073 ISAXLocator_Release(&locator->ISAXLocator_iface);
2074 return E_FAIL;
2077 if (encoding == XML_CHAR_ENCODING_UTF8)
2078 locator->pParserCtxt->encoding = xmlStrdup(enc_name);
2080 xmlFree(locator->pParserCtxt->sax);
2081 locator->pParserCtxt->sax = &locator->saxreader->sax;
2082 locator->pParserCtxt->userData = locator;
2084 This->isParsing = TRUE;
2085 if(xmlParseDocument(locator->pParserCtxt)==-1 && locator->ret==S_OK)
2086 hr = E_FAIL;
2087 else
2088 hr = locator->ret;
2089 This->isParsing = FALSE;
2091 if(locator->pParserCtxt)
2093 locator->pParserCtxt->sax = NULL;
2094 xmlFreeParserCtxt(locator->pParserCtxt);
2095 locator->pParserCtxt = NULL;
2098 ISAXLocator_Release(&locator->ISAXLocator_iface);
2099 return hr;
2102 static HRESULT internal_parseStream(saxreader *This, IStream *stream, BOOL vbInterface)
2104 saxlocator *locator;
2105 HRESULT hr;
2106 ULONG dataRead;
2107 char data[1024];
2108 int ret;
2110 dataRead = 0;
2111 hr = IStream_Read(stream, data, sizeof(data), &dataRead);
2112 if(FAILED(hr)) return hr;
2114 hr = SAXLocator_create(This, &locator, vbInterface);
2115 if(FAILED(hr)) return hr;
2117 locator->pParserCtxt = xmlCreatePushParserCtxt(
2118 &locator->saxreader->sax, locator,
2119 data, dataRead, NULL);
2120 if(!locator->pParserCtxt)
2122 ISAXLocator_Release(&locator->ISAXLocator_iface);
2123 return E_FAIL;
2126 This->isParsing = TRUE;
2128 if(dataRead != sizeof(data))
2130 ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
2131 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2133 else
2135 while(1)
2137 dataRead = 0;
2138 hr = IStream_Read(stream, data, sizeof(data), &dataRead);
2139 if (FAILED(hr)) break;
2141 ret = xmlParseChunk(locator->pParserCtxt, data, dataRead, 0);
2142 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2144 if (hr != S_OK) break;
2146 if (dataRead != sizeof(data))
2148 ret = xmlParseChunk(locator->pParserCtxt, data, 0, 1);
2149 hr = ret!=XML_ERR_OK && locator->ret==S_OK ? E_FAIL : locator->ret;
2150 break;
2155 This->isParsing = FALSE;
2157 xmlFreeParserCtxt(locator->pParserCtxt);
2158 locator->pParserCtxt = NULL;
2159 ISAXLocator_Release(&locator->ISAXLocator_iface);
2160 return hr;
2163 static HRESULT internal_getEntityResolver(
2164 saxreader *This,
2165 void *pEntityResolver,
2166 BOOL vbInterface)
2168 FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
2169 return E_NOTIMPL;
2172 static HRESULT internal_putEntityResolver(
2173 saxreader *This,
2174 void *pEntityResolver,
2175 BOOL vbInterface)
2177 FIXME("(%p)->(%p) stub\n", This, pEntityResolver);
2178 return E_NOTIMPL;
2181 static HRESULT internal_getContentHandler(
2182 saxreader* This,
2183 void *pContentHandler,
2184 BOOL vbInterface)
2186 TRACE("(%p)->(%p)\n", This, pContentHandler);
2187 if(pContentHandler == NULL)
2188 return E_POINTER;
2189 if((vbInterface && This->vbcontentHandler)
2190 || (!vbInterface && This->contentHandler))
2192 if(vbInterface)
2193 IVBSAXContentHandler_AddRef(This->vbcontentHandler);
2194 else
2195 ISAXContentHandler_AddRef(This->contentHandler);
2197 if(vbInterface) *(IVBSAXContentHandler**)pContentHandler =
2198 This->vbcontentHandler;
2199 else *(ISAXContentHandler**)pContentHandler = This->contentHandler;
2201 return S_OK;
2204 static HRESULT internal_putContentHandler(
2205 saxreader* This,
2206 void *contentHandler,
2207 BOOL vbInterface)
2209 TRACE("(%p)->(%p)\n", This, contentHandler);
2210 if(contentHandler)
2212 if(vbInterface)
2213 IVBSAXContentHandler_AddRef((IVBSAXContentHandler*)contentHandler);
2214 else
2215 ISAXContentHandler_AddRef((ISAXContentHandler*)contentHandler);
2217 if((vbInterface && This->vbcontentHandler)
2218 || (!vbInterface && This->contentHandler))
2220 if(vbInterface)
2221 IVBSAXContentHandler_Release(This->vbcontentHandler);
2222 else
2223 ISAXContentHandler_Release(This->contentHandler);
2225 if(vbInterface)
2226 This->vbcontentHandler = contentHandler;
2227 else
2228 This->contentHandler = contentHandler;
2230 return S_OK;
2233 static HRESULT internal_getDTDHandler(
2234 saxreader* This,
2235 void *pDTDHandler,
2236 BOOL vbInterface)
2238 FIXME("(%p)->(%p) stub\n", This, pDTDHandler);
2239 return E_NOTIMPL;
2242 static HRESULT internal_putDTDHandler(
2243 saxreader* This,
2244 void *pDTDHandler,
2245 BOOL vbInterface)
2247 FIXME("(%p)->(%p) stub\n", This, pDTDHandler);
2248 return E_NOTIMPL;
2251 static HRESULT internal_getErrorHandler(
2252 saxreader* This,
2253 void *pErrorHandler,
2254 BOOL vbInterface)
2256 TRACE("(%p)->(%p)\n", This, pErrorHandler);
2257 if(pErrorHandler == NULL)
2258 return E_POINTER;
2260 if(vbInterface && This->vberrorHandler)
2261 IVBSAXErrorHandler_AddRef(This->vberrorHandler);
2262 else if(!vbInterface && This->errorHandler)
2263 ISAXErrorHandler_AddRef(This->errorHandler);
2265 if(vbInterface)
2266 *(IVBSAXErrorHandler**)pErrorHandler = This->vberrorHandler;
2267 else
2268 *(ISAXErrorHandler**)pErrorHandler = This->errorHandler;
2270 return S_OK;
2274 static HRESULT internal_putErrorHandler(
2275 saxreader* This,
2276 void *errorHandler,
2277 BOOL vbInterface)
2279 TRACE("(%p)->(%p)\n", This, errorHandler);
2280 if(errorHandler)
2282 if(vbInterface)
2283 IVBSAXErrorHandler_AddRef((IVBSAXErrorHandler*)errorHandler);
2284 else
2285 ISAXErrorHandler_AddRef((ISAXErrorHandler*)errorHandler);
2288 if(vbInterface && This->vberrorHandler)
2289 IVBSAXErrorHandler_Release(This->vberrorHandler);
2290 else if(!vbInterface && This->errorHandler)
2291 ISAXErrorHandler_Release(This->errorHandler);
2293 if(vbInterface)
2294 This->vberrorHandler = errorHandler;
2295 else
2296 This->errorHandler = errorHandler;
2298 return S_OK;
2302 static HRESULT internal_parse(
2303 saxreader* This,
2304 VARIANT varInput,
2305 BOOL vbInterface)
2307 HRESULT hr;
2309 TRACE("(%p)->(%s)\n", This, debugstr_variant(&varInput));
2311 /* Dispose of the BSTRs in the pool from a prior run, if any. */
2312 free_bstr_pool(&This->pool);
2314 switch(V_VT(&varInput))
2316 case VT_BSTR:
2317 hr = internal_parseBuffer(This, (const char*)V_BSTR(&varInput),
2318 SysStringByteLen(V_BSTR(&varInput)), vbInterface);
2319 break;
2320 case VT_ARRAY|VT_UI1: {
2321 void *pSAData;
2322 LONG lBound, uBound;
2323 ULONG dataRead;
2325 hr = SafeArrayGetLBound(V_ARRAY(&varInput), 1, &lBound);
2326 if(hr != S_OK) break;
2327 hr = SafeArrayGetUBound(V_ARRAY(&varInput), 1, &uBound);
2328 if(hr != S_OK) break;
2329 dataRead = (uBound-lBound)*SafeArrayGetElemsize(V_ARRAY(&varInput));
2330 hr = SafeArrayAccessData(V_ARRAY(&varInput), &pSAData);
2331 if(hr != S_OK) break;
2332 hr = internal_parseBuffer(This, pSAData, dataRead, vbInterface);
2333 SafeArrayUnaccessData(V_ARRAY(&varInput));
2334 break;
2336 case VT_UNKNOWN:
2337 case VT_DISPATCH: {
2338 IPersistStream *persistStream;
2339 IStream *stream = NULL;
2340 IXMLDOMDocument *xmlDoc;
2342 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2343 &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK)
2345 BSTR bstrData;
2347 IXMLDOMDocument_get_xml(xmlDoc, &bstrData);
2348 hr = internal_parseBuffer(This, (const char*)bstrData,
2349 SysStringByteLen(bstrData), vbInterface);
2350 IXMLDOMDocument_Release(xmlDoc);
2351 SysFreeString(bstrData);
2352 break;
2355 if(IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2356 &IID_IPersistStream, (void**)&persistStream) == S_OK)
2358 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
2359 if(hr != S_OK)
2361 IPersistStream_Release(persistStream);
2362 return hr;
2365 hr = IPersistStream_Save(persistStream, stream, TRUE);
2366 IPersistStream_Release(persistStream);
2367 if(hr != S_OK)
2369 IStream_Release(stream);
2370 break;
2373 if(stream || IUnknown_QueryInterface(V_UNKNOWN(&varInput),
2374 &IID_IStream, (void**)&stream) == S_OK)
2376 hr = internal_parseStream(This, stream, vbInterface);
2377 IStream_Release(stream);
2378 break;
2381 default:
2382 WARN("vt %d not implemented\n", V_VT(&varInput));
2383 hr = E_INVALIDARG;
2386 return hr;
2389 static HRESULT internal_vbonDataAvailable(void *obj, char *ptr, DWORD len)
2391 saxreader *This = obj;
2393 return internal_parseBuffer(This, ptr, len, TRUE);
2396 static HRESULT internal_onDataAvailable(void *obj, char *ptr, DWORD len)
2398 saxreader *This = obj;
2400 return internal_parseBuffer(This, ptr, len, FALSE);
2403 static HRESULT internal_parseURL(
2404 saxreader* This,
2405 const WCHAR *url,
2406 BOOL vbInterface)
2408 bsc_t *bsc;
2409 HRESULT hr;
2411 TRACE("(%p)->(%s)\n", This, debugstr_w(url));
2413 if(vbInterface) hr = bind_url(url, internal_vbonDataAvailable, This, &bsc);
2414 else hr = bind_url(url, internal_onDataAvailable, This, &bsc);
2416 if(FAILED(hr))
2417 return hr;
2419 return detach_bsc(bsc);
2422 static HRESULT internal_putProperty(
2423 saxreader* This,
2424 const WCHAR *prop,
2425 VARIANT value,
2426 BOOL vbInterface)
2428 TRACE("(%p)->(%s %s)\n", This, debugstr_w(prop), debugstr_variant(&value));
2430 if(!memcmp(prop, PropertyDeclHandlerW, sizeof(PropertyDeclHandlerW)))
2432 if(This->isParsing) return E_FAIL;
2434 switch (V_VT(&value))
2436 case VT_EMPTY:
2437 if (vbInterface)
2439 if (This->vbdeclHandler)
2441 IVBSAXDeclHandler_Release(This->vbdeclHandler);
2442 This->vbdeclHandler = NULL;
2445 else
2446 if (This->declHandler)
2448 ISAXDeclHandler_Release(This->declHandler);
2449 This->declHandler = NULL;
2451 break;
2452 case VT_UNKNOWN:
2453 if (V_UNKNOWN(&value)) IUnknown_AddRef(V_UNKNOWN(&value));
2455 if ((vbInterface && This->vbdeclHandler) ||
2456 (!vbInterface && This->declHandler))
2458 if (vbInterface)
2459 IVBSAXDeclHandler_Release(This->vbdeclHandler);
2460 else
2461 ISAXDeclHandler_Release(This->declHandler);
2464 if (vbInterface)
2465 This->vbdeclHandler = (IVBSAXDeclHandler*)V_UNKNOWN(&value);
2466 else
2467 This->declHandler = (ISAXDeclHandler*)V_UNKNOWN(&value);
2468 break;
2469 default:
2470 return E_INVALIDARG;
2473 return S_OK;
2476 if(!memcmp(prop, PropertyLexicalHandlerW, sizeof(PropertyLexicalHandlerW)))
2478 if(This->isParsing) return E_FAIL;
2480 switch (V_VT(&value))
2482 case VT_EMPTY:
2483 if (vbInterface)
2485 if (This->vblexicalHandler)
2487 IVBSAXLexicalHandler_Release(This->vblexicalHandler);
2488 This->vblexicalHandler = NULL;
2491 else
2492 if (This->lexicalHandler)
2494 ISAXLexicalHandler_Release(This->lexicalHandler);
2495 This->lexicalHandler = NULL;
2497 break;
2498 case VT_UNKNOWN:
2499 if (V_UNKNOWN(&value)) IUnknown_AddRef(V_UNKNOWN(&value));
2501 if ((vbInterface && This->vblexicalHandler) ||
2502 (!vbInterface && This->lexicalHandler))
2504 if (vbInterface)
2505 IVBSAXLexicalHandler_Release(This->vblexicalHandler);
2506 else
2507 ISAXLexicalHandler_Release(This->lexicalHandler);
2510 if (vbInterface)
2511 This->vblexicalHandler = (IVBSAXLexicalHandler*)V_UNKNOWN(&value);
2512 else
2513 This->lexicalHandler = (ISAXLexicalHandler*)V_UNKNOWN(&value);
2514 break;
2515 default:
2516 return E_INVALIDARG;
2519 return S_OK;
2522 if(!memcmp(prop, PropertyMaxXMLSizeW, sizeof(PropertyMaxXMLSizeW)))
2524 if (V_VT(&value) == VT_I4 && V_I4(&value) == 0) return S_OK;
2525 FIXME("(%p)->(%s): max-xml-size unsupported\n", This, debugstr_variant(&value));
2526 return E_NOTIMPL;
2529 if(!memcmp(prop, PropertyMaxElementDepthW, sizeof(PropertyMaxElementDepthW)))
2531 if (V_VT(&value) == VT_I4 && V_I4(&value) == 0) return S_OK;
2532 FIXME("(%p)->(%s): max-element-depth unsupported\n", This, debugstr_variant(&value));
2533 return E_NOTIMPL;
2536 FIXME("(%p)->(%s:%s): unsupported property\n", This, debugstr_w(prop), debugstr_variant(&value));
2538 if(!memcmp(prop, PropertyCharsetW, sizeof(PropertyCharsetW)))
2539 return E_NOTIMPL;
2541 if(!memcmp(prop, PropertyDomNodeW, sizeof(PropertyDomNodeW)))
2542 return E_FAIL;
2544 if(!memcmp(prop, PropertyInputSourceW, sizeof(PropertyInputSourceW)))
2545 return E_NOTIMPL;
2547 if(!memcmp(prop, PropertySchemaDeclHandlerW, sizeof(PropertySchemaDeclHandlerW)))
2548 return E_NOTIMPL;
2550 if(!memcmp(prop, PropertyXMLDeclEncodingW, sizeof(PropertyXMLDeclEncodingW)))
2551 return E_FAIL;
2553 if(!memcmp(prop, PropertyXMLDeclStandaloneW, sizeof(PropertyXMLDeclStandaloneW)))
2554 return E_FAIL;
2556 if(!memcmp(prop, PropertyXMLDeclVersionW, sizeof(PropertyXMLDeclVersionW)))
2557 return E_FAIL;
2559 return E_INVALIDARG;
2562 static HRESULT internal_getProperty(const saxreader* This, const WCHAR *prop, VARIANT *value, BOOL vb)
2564 TRACE("(%p)->(%s)\n", This, debugstr_w(prop));
2566 if (!value) return E_POINTER;
2568 if (!memcmp(PropertyLexicalHandlerW, prop, sizeof(PropertyLexicalHandlerW)))
2570 V_VT(value) = VT_UNKNOWN;
2571 V_UNKNOWN(value) = vb ? (IUnknown*)This->vblexicalHandler : (IUnknown*)This->lexicalHandler;
2572 if (V_UNKNOWN(value)) IUnknown_AddRef(V_UNKNOWN(value));
2573 return S_OK;
2576 if (!memcmp(PropertyDeclHandlerW, prop, sizeof(PropertyDeclHandlerW)))
2578 V_VT(value) = VT_UNKNOWN;
2579 V_UNKNOWN(value) = vb ? (IUnknown*)This->vbdeclHandler : (IUnknown*)This->declHandler;
2580 if (V_UNKNOWN(value)) IUnknown_AddRef(V_UNKNOWN(value));
2581 return S_OK;
2584 FIXME("(%p)->(%s) unsupported property\n", This, debugstr_w(prop));
2586 return E_NOTIMPL;
2589 /*** IVBSAXXMLReader interface ***/
2590 /*** IUnknown methods ***/
2591 static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject)
2593 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2595 TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject );
2597 *ppvObject = NULL;
2599 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
2600 IsEqualGUID( riid, &IID_IDispatch ) ||
2601 IsEqualGUID( riid, &IID_IVBSAXXMLReader ))
2603 *ppvObject = iface;
2605 else if( IsEqualGUID( riid, &IID_ISAXXMLReader ))
2607 *ppvObject = &This->ISAXXMLReader_iface;
2609 else if (dispex_query_interface(&This->dispex, riid, ppvObject))
2611 return *ppvObject ? S_OK : E_NOINTERFACE;
2613 else
2615 FIXME("interface %s not implemented\n", debugstr_guid(riid));
2616 return E_NOINTERFACE;
2619 IVBSAXXMLReader_AddRef( iface );
2621 return S_OK;
2624 static ULONG WINAPI saxxmlreader_AddRef(IVBSAXXMLReader* iface)
2626 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2627 TRACE("%p\n", This );
2628 return InterlockedIncrement( &This->ref );
2631 static ULONG WINAPI saxxmlreader_Release(
2632 IVBSAXXMLReader* iface)
2634 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2635 LONG ref;
2637 TRACE("%p\n", This );
2639 ref = InterlockedDecrement( &This->ref );
2640 if ( ref == 0 )
2642 if(This->contentHandler)
2643 ISAXContentHandler_Release(This->contentHandler);
2645 if(This->vbcontentHandler)
2646 IVBSAXContentHandler_Release(This->vbcontentHandler);
2648 if(This->errorHandler)
2649 ISAXErrorHandler_Release(This->errorHandler);
2651 if(This->vberrorHandler)
2652 IVBSAXErrorHandler_Release(This->vberrorHandler);
2654 if(This->lexicalHandler)
2655 ISAXLexicalHandler_Release(This->lexicalHandler);
2657 if(This->vblexicalHandler)
2658 IVBSAXLexicalHandler_Release(This->vblexicalHandler);
2660 if(This->declHandler)
2661 ISAXDeclHandler_Release(This->declHandler);
2663 if(This->vbdeclHandler)
2664 IVBSAXDeclHandler_Release(This->vbdeclHandler);
2666 free_bstr_pool(&This->pool);
2668 release_dispex(&This->dispex);
2669 heap_free( This );
2672 return ref;
2674 /*** IDispatch ***/
2675 static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo )
2677 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2678 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
2681 static HRESULT WINAPI saxxmlreader_GetTypeInfo(
2682 IVBSAXXMLReader *iface,
2683 UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo )
2685 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2686 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface,
2687 iTInfo, lcid, ppTInfo);
2690 static HRESULT WINAPI saxxmlreader_GetIDsOfNames(
2691 IVBSAXXMLReader *iface,
2692 REFIID riid,
2693 LPOLESTR* rgszNames,
2694 UINT cNames,
2695 LCID lcid,
2696 DISPID* rgDispId)
2698 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2699 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface,
2700 riid, rgszNames, cNames, lcid, rgDispId);
2703 static HRESULT WINAPI saxxmlreader_Invoke(
2704 IVBSAXXMLReader *iface,
2705 DISPID dispIdMember,
2706 REFIID riid,
2707 LCID lcid,
2708 WORD wFlags,
2709 DISPPARAMS* pDispParams,
2710 VARIANT* pVarResult,
2711 EXCEPINFO* pExcepInfo,
2712 UINT* puArgErr)
2714 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2715 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface,
2716 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2719 /*** IVBSAXXMLReader methods ***/
2720 static HRESULT WINAPI saxxmlreader_getFeature(
2721 IVBSAXXMLReader* iface,
2722 const WCHAR *feature,
2723 VARIANT_BOOL *value)
2725 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2727 if (!strcmpW(FeatureNamespacesW, feature))
2728 return get_feature_value(This, Namespaces, value);
2730 FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(feature), value);
2731 return E_NOTIMPL;
2734 static HRESULT WINAPI saxxmlreader_putFeature(
2735 IVBSAXXMLReader* iface,
2736 const WCHAR *feature,
2737 VARIANT_BOOL value)
2739 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2741 TRACE("(%p)->(%s %x)\n", This, debugstr_w(feature), value);
2743 if (!strcmpW(FeatureExternalGeneralEntitiesW, feature) && value == VARIANT_FALSE)
2744 return set_feature_value(This, ExternalGeneralEntities, value);
2746 if (!strcmpW(FeatureExternalParameterEntitiesW, feature) && value == VARIANT_FALSE)
2747 return set_feature_value(This, ExternalParameterEntities, value);
2749 if (!strcmpW(FeatureLexicalHandlerParEntitiesW, feature))
2751 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature), value);
2752 return set_feature_value(This, LexicalHandlerParEntities, value);
2755 if (!strcmpW(FeatureProhibitDTDW, feature))
2757 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature), value);
2758 return set_feature_value(This, ProhibitDTD, value);
2761 if (!strcmpW(FeatureNamespacesW, feature) && value == VARIANT_TRUE)
2762 return set_feature_value(This, Namespaces, value);
2764 FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(feature), value);
2765 return E_NOTIMPL;
2768 static HRESULT WINAPI saxxmlreader_getProperty(
2769 IVBSAXXMLReader* iface,
2770 const WCHAR *prop,
2771 VARIANT *value)
2773 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2774 return internal_getProperty(This, prop, value, TRUE);
2777 static HRESULT WINAPI saxxmlreader_putProperty(
2778 IVBSAXXMLReader* iface,
2779 const WCHAR *pProp,
2780 VARIANT value)
2782 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2783 return internal_putProperty(This, pProp, value, TRUE);
2786 static HRESULT WINAPI saxxmlreader_get_entityResolver(
2787 IVBSAXXMLReader* iface,
2788 IVBSAXEntityResolver **pEntityResolver)
2790 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2791 return internal_getEntityResolver(This, pEntityResolver, TRUE);
2794 static HRESULT WINAPI saxxmlreader_put_entityResolver(
2795 IVBSAXXMLReader* iface,
2796 IVBSAXEntityResolver *pEntityResolver)
2798 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2799 return internal_putEntityResolver(This, pEntityResolver, TRUE);
2802 static HRESULT WINAPI saxxmlreader_get_contentHandler(
2803 IVBSAXXMLReader* iface,
2804 IVBSAXContentHandler **ppContentHandler)
2806 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2807 return internal_getContentHandler(This, ppContentHandler, TRUE);
2810 static HRESULT WINAPI saxxmlreader_put_contentHandler(
2811 IVBSAXXMLReader* iface,
2812 IVBSAXContentHandler *contentHandler)
2814 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2815 return internal_putContentHandler(This, contentHandler, TRUE);
2818 static HRESULT WINAPI saxxmlreader_get_dtdHandler(
2819 IVBSAXXMLReader* iface,
2820 IVBSAXDTDHandler **pDTDHandler)
2822 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2823 return internal_getDTDHandler(This, pDTDHandler, TRUE);
2826 static HRESULT WINAPI saxxmlreader_put_dtdHandler(
2827 IVBSAXXMLReader* iface,
2828 IVBSAXDTDHandler *pDTDHandler)
2830 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2831 return internal_putDTDHandler(This, pDTDHandler, TRUE);
2834 static HRESULT WINAPI saxxmlreader_get_errorHandler(
2835 IVBSAXXMLReader* iface,
2836 IVBSAXErrorHandler **pErrorHandler)
2838 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2839 return internal_getErrorHandler(This, pErrorHandler, TRUE);
2842 static HRESULT WINAPI saxxmlreader_put_errorHandler(
2843 IVBSAXXMLReader* iface,
2844 IVBSAXErrorHandler *errorHandler)
2846 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2847 return internal_putErrorHandler(This, errorHandler, TRUE);
2850 static HRESULT WINAPI saxxmlreader_get_baseURL(
2851 IVBSAXXMLReader* iface,
2852 const WCHAR **pBaseUrl)
2854 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2856 FIXME("(%p)->(%p) stub\n", This, pBaseUrl);
2857 return E_NOTIMPL;
2860 static HRESULT WINAPI saxxmlreader_put_baseURL(
2861 IVBSAXXMLReader* iface,
2862 const WCHAR *pBaseUrl)
2864 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2866 FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl));
2867 return E_NOTIMPL;
2870 static HRESULT WINAPI saxxmlreader_get_secureBaseURL(
2871 IVBSAXXMLReader* iface,
2872 const WCHAR **pSecureBaseUrl)
2874 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2876 FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl);
2877 return E_NOTIMPL;
2881 static HRESULT WINAPI saxxmlreader_put_secureBaseURL(
2882 IVBSAXXMLReader* iface,
2883 const WCHAR *secureBaseUrl)
2885 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2887 FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl));
2888 return E_NOTIMPL;
2891 static HRESULT WINAPI saxxmlreader_parse(
2892 IVBSAXXMLReader* iface,
2893 VARIANT varInput)
2895 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2896 return internal_parse(This, varInput, TRUE);
2899 static HRESULT WINAPI saxxmlreader_parseURL(
2900 IVBSAXXMLReader* iface,
2901 const WCHAR *url)
2903 saxreader *This = impl_from_IVBSAXXMLReader( iface );
2904 return internal_parseURL(This, url, TRUE);
2907 static const struct IVBSAXXMLReaderVtbl saxreader_vtbl =
2909 saxxmlreader_QueryInterface,
2910 saxxmlreader_AddRef,
2911 saxxmlreader_Release,
2912 saxxmlreader_GetTypeInfoCount,
2913 saxxmlreader_GetTypeInfo,
2914 saxxmlreader_GetIDsOfNames,
2915 saxxmlreader_Invoke,
2916 saxxmlreader_getFeature,
2917 saxxmlreader_putFeature,
2918 saxxmlreader_getProperty,
2919 saxxmlreader_putProperty,
2920 saxxmlreader_get_entityResolver,
2921 saxxmlreader_put_entityResolver,
2922 saxxmlreader_get_contentHandler,
2923 saxxmlreader_put_contentHandler,
2924 saxxmlreader_get_dtdHandler,
2925 saxxmlreader_put_dtdHandler,
2926 saxxmlreader_get_errorHandler,
2927 saxxmlreader_put_errorHandler,
2928 saxxmlreader_get_baseURL,
2929 saxxmlreader_put_baseURL,
2930 saxxmlreader_get_secureBaseURL,
2931 saxxmlreader_put_secureBaseURL,
2932 saxxmlreader_parse,
2933 saxxmlreader_parseURL
2936 /*** ISAXXMLReader interface ***/
2937 /*** IUnknown methods ***/
2938 static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject)
2940 saxreader *This = impl_from_ISAXXMLReader( iface );
2941 return saxxmlreader_QueryInterface(&This->IVBSAXXMLReader_iface, riid, ppvObject);
2944 static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface)
2946 saxreader *This = impl_from_ISAXXMLReader( iface );
2947 return saxxmlreader_AddRef(&This->IVBSAXXMLReader_iface);
2950 static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface)
2952 saxreader *This = impl_from_ISAXXMLReader( iface );
2953 return saxxmlreader_Release(&This->IVBSAXXMLReader_iface);
2956 /*** ISAXXMLReader methods ***/
2957 static HRESULT WINAPI isaxxmlreader_getFeature(
2958 ISAXXMLReader* iface,
2959 const WCHAR *pFeature,
2960 VARIANT_BOOL *pValue)
2962 saxreader *This = impl_from_ISAXXMLReader( iface );
2963 return IVBSAXXMLReader_getFeature(&This->IVBSAXXMLReader_iface, pFeature, pValue);
2966 static HRESULT WINAPI isaxxmlreader_putFeature(
2967 ISAXXMLReader* iface,
2968 const WCHAR *pFeature,
2969 VARIANT_BOOL vfValue)
2971 saxreader *This = impl_from_ISAXXMLReader( iface );
2972 return IVBSAXXMLReader_putFeature(&This->IVBSAXXMLReader_iface, pFeature, vfValue);
2975 static HRESULT WINAPI isaxxmlreader_getProperty(
2976 ISAXXMLReader* iface,
2977 const WCHAR *prop,
2978 VARIANT *value)
2980 saxreader *This = impl_from_ISAXXMLReader( iface );
2981 return internal_getProperty(This, prop, value, FALSE);
2984 static HRESULT WINAPI isaxxmlreader_putProperty(
2985 ISAXXMLReader* iface,
2986 const WCHAR *pProp,
2987 VARIANT value)
2989 saxreader *This = impl_from_ISAXXMLReader( iface );
2990 return internal_putProperty(This, pProp, value, FALSE);
2993 static HRESULT WINAPI isaxxmlreader_getEntityResolver(
2994 ISAXXMLReader* iface,
2995 ISAXEntityResolver **ppEntityResolver)
2997 saxreader *This = impl_from_ISAXXMLReader( iface );
2998 return internal_getEntityResolver(This, ppEntityResolver, FALSE);
3001 static HRESULT WINAPI isaxxmlreader_putEntityResolver(
3002 ISAXXMLReader* iface,
3003 ISAXEntityResolver *pEntityResolver)
3005 saxreader *This = impl_from_ISAXXMLReader( iface );
3006 return internal_putEntityResolver(This, pEntityResolver, FALSE);
3009 static HRESULT WINAPI isaxxmlreader_getContentHandler(
3010 ISAXXMLReader* iface,
3011 ISAXContentHandler **pContentHandler)
3013 saxreader *This = impl_from_ISAXXMLReader( iface );
3014 return internal_getContentHandler(This, pContentHandler, FALSE);
3017 static HRESULT WINAPI isaxxmlreader_putContentHandler(
3018 ISAXXMLReader* iface,
3019 ISAXContentHandler *contentHandler)
3021 saxreader *This = impl_from_ISAXXMLReader( iface );
3022 return internal_putContentHandler(This, contentHandler, FALSE);
3025 static HRESULT WINAPI isaxxmlreader_getDTDHandler(
3026 ISAXXMLReader* iface,
3027 ISAXDTDHandler **pDTDHandler)
3029 saxreader *This = impl_from_ISAXXMLReader( iface );
3030 return internal_getDTDHandler(This, pDTDHandler, FALSE);
3033 static HRESULT WINAPI isaxxmlreader_putDTDHandler(
3034 ISAXXMLReader* iface,
3035 ISAXDTDHandler *pDTDHandler)
3037 saxreader *This = impl_from_ISAXXMLReader( iface );
3038 return internal_putDTDHandler(This, pDTDHandler, FALSE);
3041 static HRESULT WINAPI isaxxmlreader_getErrorHandler(
3042 ISAXXMLReader* iface,
3043 ISAXErrorHandler **pErrorHandler)
3045 saxreader *This = impl_from_ISAXXMLReader( iface );
3046 return internal_getErrorHandler(This, pErrorHandler, FALSE);
3049 static HRESULT WINAPI isaxxmlreader_putErrorHandler(
3050 ISAXXMLReader* iface,
3051 ISAXErrorHandler *errorHandler)
3053 saxreader *This = impl_from_ISAXXMLReader( iface );
3054 return internal_putErrorHandler(This, errorHandler, FALSE);
3057 static HRESULT WINAPI isaxxmlreader_getBaseURL(
3058 ISAXXMLReader* iface,
3059 const WCHAR **pBaseUrl)
3061 saxreader *This = impl_from_ISAXXMLReader( iface );
3062 return IVBSAXXMLReader_get_baseURL(&This->IVBSAXXMLReader_iface, pBaseUrl);
3065 static HRESULT WINAPI isaxxmlreader_putBaseURL(
3066 ISAXXMLReader* iface,
3067 const WCHAR *pBaseUrl)
3069 saxreader *This = impl_from_ISAXXMLReader( iface );
3070 return IVBSAXXMLReader_put_baseURL(&This->IVBSAXXMLReader_iface, pBaseUrl);
3073 static HRESULT WINAPI isaxxmlreader_getSecureBaseURL(
3074 ISAXXMLReader* iface,
3075 const WCHAR **pSecureBaseUrl)
3077 saxreader *This = impl_from_ISAXXMLReader( iface );
3078 return IVBSAXXMLReader_get_secureBaseURL(&This->IVBSAXXMLReader_iface, pSecureBaseUrl);
3081 static HRESULT WINAPI isaxxmlreader_putSecureBaseURL(
3082 ISAXXMLReader* iface,
3083 const WCHAR *secureBaseUrl)
3085 saxreader *This = impl_from_ISAXXMLReader( iface );
3086 return IVBSAXXMLReader_put_secureBaseURL(&This->IVBSAXXMLReader_iface, secureBaseUrl);
3089 static HRESULT WINAPI isaxxmlreader_parse(
3090 ISAXXMLReader* iface,
3091 VARIANT varInput)
3093 saxreader *This = impl_from_ISAXXMLReader( iface );
3094 return internal_parse(This, varInput, FALSE);
3097 static HRESULT WINAPI isaxxmlreader_parseURL(
3098 ISAXXMLReader* iface,
3099 const WCHAR *url)
3101 saxreader *This = impl_from_ISAXXMLReader( iface );
3102 return internal_parseURL(This, url, FALSE);
3105 static const struct ISAXXMLReaderVtbl isaxreader_vtbl =
3107 isaxxmlreader_QueryInterface,
3108 isaxxmlreader_AddRef,
3109 isaxxmlreader_Release,
3110 isaxxmlreader_getFeature,
3111 isaxxmlreader_putFeature,
3112 isaxxmlreader_getProperty,
3113 isaxxmlreader_putProperty,
3114 isaxxmlreader_getEntityResolver,
3115 isaxxmlreader_putEntityResolver,
3116 isaxxmlreader_getContentHandler,
3117 isaxxmlreader_putContentHandler,
3118 isaxxmlreader_getDTDHandler,
3119 isaxxmlreader_putDTDHandler,
3120 isaxxmlreader_getErrorHandler,
3121 isaxxmlreader_putErrorHandler,
3122 isaxxmlreader_getBaseURL,
3123 isaxxmlreader_putBaseURL,
3124 isaxxmlreader_getSecureBaseURL,
3125 isaxxmlreader_putSecureBaseURL,
3126 isaxxmlreader_parse,
3127 isaxxmlreader_parseURL
3130 static const tid_t saxreader_iface_tids[] = {
3131 IVBSAXXMLReader_tid,
3134 static dispex_static_data_t saxreader_dispex = {
3135 NULL,
3136 IVBSAXXMLReader_tid,
3137 NULL,
3138 saxreader_iface_tids
3141 HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *pUnkOuter, LPVOID *ppObj)
3143 saxreader *reader;
3145 TRACE("(%p,%p)\n", pUnkOuter, ppObj);
3147 reader = heap_alloc( sizeof (*reader) );
3148 if( !reader )
3149 return E_OUTOFMEMORY;
3151 reader->IVBSAXXMLReader_iface.lpVtbl = &saxreader_vtbl;
3152 reader->ISAXXMLReader_iface.lpVtbl = &isaxreader_vtbl;
3153 reader->ref = 1;
3154 reader->contentHandler = NULL;
3155 reader->vbcontentHandler = NULL;
3156 reader->errorHandler = NULL;
3157 reader->vberrorHandler = NULL;
3158 reader->lexicalHandler = NULL;
3159 reader->vblexicalHandler = NULL;
3160 reader->declHandler = NULL;
3161 reader->vbdeclHandler = NULL;
3162 reader->isParsing = FALSE;
3163 reader->pool.pool = NULL;
3164 reader->pool.index = 0;
3165 reader->pool.len = 0;
3166 reader->features = Namespaces;
3167 reader->version = version;
3169 init_dispex(&reader->dispex, (IUnknown*)&reader->IVBSAXXMLReader_iface, &saxreader_dispex);
3171 memset(&reader->sax, 0, sizeof(xmlSAXHandler));
3172 reader->sax.initialized = XML_SAX2_MAGIC;
3173 reader->sax.startDocument = libxmlStartDocument;
3174 reader->sax.endDocument = libxmlEndDocument;
3175 reader->sax.startElementNs = libxmlStartElementNS;
3176 reader->sax.endElementNs = libxmlEndElementNS;
3177 reader->sax.characters = libxmlCharacters;
3178 reader->sax.setDocumentLocator = libxmlSetDocumentLocator;
3179 reader->sax.comment = libxmlComment;
3180 reader->sax.error = libxmlFatalError;
3181 reader->sax.fatalError = libxmlFatalError;
3182 reader->sax.cdataBlock = libxmlCDataBlock;
3184 *ppObj = &reader->IVBSAXXMLReader_iface;
3186 TRACE("returning iface %p\n", *ppObj);
3188 return S_OK;
3191 #else
3193 HRESULT SAXXMLReader_create(MSXML_VERSION version, IUnknown *pUnkOuter, LPVOID *ppObj)
3195 MESSAGE("This program tried to use a SAX XML Reader object, but\n"
3196 "libxml2 support was not present at compile time.\n");
3197 return E_NOTIMPL;
3200 #endif