|  | /* | 
|  | *    SAX Reader implementation | 
|  | * | 
|  | * Copyright 2008 Alistair Leslie-Hughes | 
|  | * Copyright 2008 Piotr Caban | 
|  | * | 
|  | * This library is free software; you can redistribute it and/or | 
|  | * modify it under the terms of the GNU Lesser General Public | 
|  | * License as published by the Free Software Foundation; either | 
|  | * version 2.1 of the License, or (at your option) any later version. | 
|  | * | 
|  | * This library is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|  | * Lesser General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU Lesser General Public | 
|  | * License along with this library; if not, write to the Free Software | 
|  | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | 
|  | */ | 
|  | #define COBJMACROS | 
|  |  | 
|  | #include "config.h" | 
|  |  | 
|  | #include <stdarg.h> | 
|  | #ifdef HAVE_LIBXML2 | 
|  | # include <libxml/parser.h> | 
|  | # include <libxml/xmlerror.h> | 
|  | # include <libxml/SAX2.h> | 
|  | # include <libxml/parserInternals.h> | 
|  | #endif | 
|  |  | 
|  | #include "windef.h" | 
|  | #include "winbase.h" | 
|  | #include "winuser.h" | 
|  | #include "winnls.h" | 
|  | #include "ole2.h" | 
|  | #include "msxml6.h" | 
|  | #include "wininet.h" | 
|  | #include "urlmon.h" | 
|  | #include "winreg.h" | 
|  | #include "shlwapi.h" | 
|  |  | 
|  | #include "wine/debug.h" | 
|  |  | 
|  | #include "msxml_private.h" | 
|  |  | 
|  | WINE_DEFAULT_DEBUG_CHANNEL(msxml); | 
|  |  | 
|  | #ifdef HAVE_LIBXML2 | 
|  |  | 
|  | struct bstrpool | 
|  | { | 
|  | BSTR *pool; | 
|  | unsigned int index; | 
|  | unsigned int len; | 
|  | }; | 
|  |  | 
|  | typedef struct _saxreader | 
|  | { | 
|  | IVBSAXXMLReader IVBSAXXMLReader_iface; | 
|  | ISAXXMLReader ISAXXMLReader_iface; | 
|  | LONG ref; | 
|  | struct ISAXContentHandler *contentHandler; | 
|  | struct IVBSAXContentHandler *vbcontentHandler; | 
|  | struct ISAXErrorHandler *errorHandler; | 
|  | struct IVBSAXErrorHandler *vberrorHandler; | 
|  | struct ISAXLexicalHandler *lexicalHandler; | 
|  | struct IVBSAXLexicalHandler *vblexicalHandler; | 
|  | struct ISAXDeclHandler *declHandler; | 
|  | struct IVBSAXDeclHandler *vbdeclHandler; | 
|  | xmlSAXHandler sax; | 
|  | BOOL isParsing; | 
|  | struct bstrpool pool; | 
|  | } saxreader; | 
|  |  | 
|  | typedef struct _saxlocator | 
|  | { | 
|  | IVBSAXLocator IVBSAXLocator_iface; | 
|  | ISAXLocator ISAXLocator_iface; | 
|  | LONG ref; | 
|  | saxreader *saxreader; | 
|  | HRESULT ret; | 
|  | xmlParserCtxtPtr pParserCtxt; | 
|  | WCHAR *publicId; | 
|  | WCHAR *systemId; | 
|  | xmlChar *lastCur; | 
|  | int line; | 
|  | int realLine; | 
|  | int column; | 
|  | int realColumn; | 
|  | BOOL vbInterface; | 
|  | int nsStackSize; | 
|  | int nsStackLast; | 
|  | int *nsStack; | 
|  | } saxlocator; | 
|  |  | 
|  | typedef struct _saxattributes | 
|  | { | 
|  | IVBSAXAttributes IVBSAXAttributes_iface; | 
|  | ISAXAttributes ISAXAttributes_iface; | 
|  | LONG ref; | 
|  | int nb_attributes; | 
|  | BSTR *szLocalname; | 
|  | BSTR *szURI; | 
|  | BSTR *szValue; | 
|  | BSTR *szQName; | 
|  | } saxattributes; | 
|  |  | 
|  | static inline saxreader *impl_from_IVBSAXXMLReader( IVBSAXXMLReader *iface ) | 
|  | { | 
|  | return CONTAINING_RECORD(iface, saxreader, IVBSAXXMLReader_iface); | 
|  | } | 
|  |  | 
|  | static inline saxreader *impl_from_ISAXXMLReader( ISAXXMLReader *iface ) | 
|  | { | 
|  | return CONTAINING_RECORD(iface, saxreader, ISAXXMLReader_iface); | 
|  | } | 
|  |  | 
|  | static inline saxlocator *impl_from_IVBSAXLocator( IVBSAXLocator *iface ) | 
|  | { | 
|  | return CONTAINING_RECORD(iface, saxlocator, IVBSAXLocator_iface); | 
|  | } | 
|  |  | 
|  | static inline saxlocator *impl_from_ISAXLocator( ISAXLocator *iface ) | 
|  | { | 
|  | return CONTAINING_RECORD(iface, saxlocator, ISAXLocator_iface); | 
|  | } | 
|  |  | 
|  | static inline saxattributes *impl_from_IVBSAXAttributes( IVBSAXAttributes *iface ) | 
|  | { | 
|  | return CONTAINING_RECORD(iface, saxattributes, IVBSAXAttributes_iface); | 
|  | } | 
|  |  | 
|  | static inline saxattributes *impl_from_ISAXAttributes( ISAXAttributes *iface ) | 
|  | { | 
|  | return CONTAINING_RECORD(iface, saxattributes, ISAXAttributes_iface); | 
|  | } | 
|  |  | 
|  | static inline BOOL has_content_handler(const saxlocator *locator) | 
|  | { | 
|  | return  (locator->vbInterface && locator->saxreader->vbcontentHandler) || | 
|  | (!locator->vbInterface && locator->saxreader->contentHandler); | 
|  | } | 
|  |  | 
|  | static inline BOOL has_error_handler(const saxlocator *locator) | 
|  | { | 
|  | return (locator->vbInterface && locator->saxreader->vberrorHandler) || | 
|  | (!locator->vbInterface && locator->saxreader->errorHandler); | 
|  | } | 
|  |  | 
|  | static HRESULT namespacePush(saxlocator *locator, int ns) | 
|  | { | 
|  | if(locator->nsStackLast>=locator->nsStackSize) | 
|  | { | 
|  | int *new_stack; | 
|  |  | 
|  | new_stack = HeapReAlloc(GetProcessHeap(), 0, | 
|  | locator->nsStack, sizeof(int)*locator->nsStackSize*2); | 
|  | if(!new_stack) return E_OUTOFMEMORY; | 
|  | locator->nsStack = new_stack; | 
|  | locator->nsStackSize *= 2; | 
|  | } | 
|  | locator->nsStack[locator->nsStackLast++] = ns; | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static int namespacePop(saxlocator *locator) | 
|  | { | 
|  | if(locator->nsStackLast == 0) return 0; | 
|  | return locator->nsStack[--locator->nsStackLast]; | 
|  | } | 
|  |  | 
|  | static BOOL bstr_pool_insert(struct bstrpool *pool, BSTR pool_entry) | 
|  | { | 
|  | if (!pool->pool) | 
|  | { | 
|  | pool->pool = HeapAlloc(GetProcessHeap(), 0, 16 * sizeof(*pool->pool)); | 
|  | if (!pool->pool) | 
|  | return FALSE; | 
|  |  | 
|  | pool->index = 0; | 
|  | pool->len = 16; | 
|  | } | 
|  | else if (pool->index == pool->len) | 
|  | { | 
|  | BSTR *realloc = HeapReAlloc(GetProcessHeap(), 0, pool->pool, pool->len * 2 * sizeof(*realloc)); | 
|  |  | 
|  | if (!realloc) | 
|  | return FALSE; | 
|  |  | 
|  | pool->pool = realloc; | 
|  | pool->len *= 2; | 
|  | } | 
|  |  | 
|  | pool->pool[pool->index++] = pool_entry; | 
|  | return TRUE; | 
|  | } | 
|  |  | 
|  | static void free_bstr_pool(struct bstrpool *pool) | 
|  | { | 
|  | unsigned int i; | 
|  |  | 
|  | for (i = 0; i < pool->index; i++) | 
|  | SysFreeString(pool->pool[i]); | 
|  |  | 
|  | HeapFree(GetProcessHeap(), 0, pool->pool); | 
|  |  | 
|  | pool->pool = NULL; | 
|  | pool->index = pool->len = 0; | 
|  | } | 
|  |  | 
|  | static BSTR bstr_from_xmlCharN(const xmlChar *buf, int len) | 
|  | { | 
|  | DWORD dLen; | 
|  | BSTR bstr; | 
|  |  | 
|  | if (!buf) | 
|  | return NULL; | 
|  |  | 
|  | dLen = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, NULL, 0); | 
|  | if(len != -1) dLen++; | 
|  | bstr = SysAllocStringLen(NULL, dLen-1); | 
|  | if (!bstr) | 
|  | return NULL; | 
|  | MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)buf, len, bstr, dLen); | 
|  | if(len != -1) bstr[dLen-1] = '\0'; | 
|  |  | 
|  | return bstr; | 
|  | } | 
|  |  | 
|  | static BSTR QName_from_xmlChar(const xmlChar *prefix, const xmlChar *name) | 
|  | { | 
|  | xmlChar *qname; | 
|  | BSTR bstr; | 
|  |  | 
|  | if(!name) return NULL; | 
|  |  | 
|  | if(!prefix || !*prefix) | 
|  | return bstr_from_xmlChar(name); | 
|  |  | 
|  | qname = xmlBuildQName(name, prefix, NULL, 0); | 
|  | bstr = bstr_from_xmlChar(qname); | 
|  | xmlFree(qname); | 
|  |  | 
|  | return bstr; | 
|  | } | 
|  |  | 
|  | static BSTR pooled_bstr_from_xmlChar(struct bstrpool *pool, const xmlChar *buf) | 
|  | { | 
|  | BSTR pool_entry = bstr_from_xmlChar(buf); | 
|  |  | 
|  | if (pool_entry && !bstr_pool_insert(pool, pool_entry)) | 
|  | { | 
|  | SysFreeString(pool_entry); | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | return pool_entry; | 
|  | } | 
|  |  | 
|  | static BSTR pooled_bstr_from_xmlCharN(struct bstrpool *pool, const xmlChar *buf, int len) | 
|  | { | 
|  | BSTR pool_entry = bstr_from_xmlCharN(buf, len); | 
|  |  | 
|  | if (pool_entry && !bstr_pool_insert(pool, pool_entry)) | 
|  | { | 
|  | SysFreeString(pool_entry); | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | return pool_entry; | 
|  | } | 
|  |  | 
|  | static BSTR pooled_QName_from_xmlChar(struct bstrpool *pool, const xmlChar *prefix, const xmlChar *name) | 
|  | { | 
|  | BSTR pool_entry = QName_from_xmlChar(prefix, name); | 
|  |  | 
|  | if (pool_entry && !bstr_pool_insert(pool, pool_entry)) | 
|  | { | 
|  | SysFreeString(pool_entry); | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | return pool_entry; | 
|  | } | 
|  |  | 
|  | static void format_error_message_from_id(saxlocator *This, HRESULT hr) | 
|  | { | 
|  | xmlStopParser(This->pParserCtxt); | 
|  | This->ret = hr; | 
|  |  | 
|  | if(has_error_handler(This)) | 
|  | { | 
|  | WCHAR msg[1024]; | 
|  | if(!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, | 
|  | NULL, hr, 0, msg, sizeof(msg), NULL)) | 
|  | { | 
|  | FIXME("MSXML errors not yet supported.\n"); | 
|  | msg[0] = '\0'; | 
|  | } | 
|  |  | 
|  | if(This->vbInterface) | 
|  | { | 
|  | BSTR bstrMsg = SysAllocString(msg); | 
|  | IVBSAXErrorHandler_fatalError(This->saxreader->vberrorHandler, | 
|  | &This->IVBSAXLocator_iface, &bstrMsg, hr); | 
|  | SysFreeString(bstrMsg); | 
|  | } | 
|  | else | 
|  | ISAXErrorHandler_fatalError(This->saxreader->errorHandler, | 
|  | &This->ISAXLocator_iface, msg, hr); | 
|  | } | 
|  | } | 
|  |  | 
|  | static void update_position(saxlocator *This, xmlChar *end) | 
|  | { | 
|  | if(This->lastCur == NULL) | 
|  | { | 
|  | This->lastCur = (xmlChar*)This->pParserCtxt->input->base; | 
|  | This->realLine = 1; | 
|  | This->realColumn = 1; | 
|  | } | 
|  | else if(This->lastCur < This->pParserCtxt->input->base) | 
|  | { | 
|  | This->lastCur = (xmlChar*)This->pParserCtxt->input->base; | 
|  | This->realLine = 1; | 
|  | This->realColumn = 1; | 
|  | } | 
|  |  | 
|  | if(This->pParserCtxt->input->cur<This->lastCur) | 
|  | { | 
|  | This->lastCur = (xmlChar*)This->pParserCtxt->input->base; | 
|  | This->realLine -= 1; | 
|  | This->realColumn = 1; | 
|  | } | 
|  |  | 
|  | if(!end) end = (xmlChar*)This->pParserCtxt->input->cur; | 
|  |  | 
|  | while(This->lastCur < end) | 
|  | { | 
|  | if(*(This->lastCur) == '\n') | 
|  | { | 
|  | This->realLine++; | 
|  | This->realColumn = 1; | 
|  | } | 
|  | else if(*(This->lastCur) == '\r' && | 
|  | (This->lastCur==This->pParserCtxt->input->end || | 
|  | *(This->lastCur+1)!='\n')) | 
|  | { | 
|  | This->realLine++; | 
|  | This->realColumn = 1; | 
|  | } | 
|  | else This->realColumn++; | 
|  |  | 
|  | This->lastCur++; | 
|  |  | 
|  | /* Count multibyte UTF8 encoded characters once */ | 
|  | while((*(This->lastCur)&0xC0) == 0x80) This->lastCur++; | 
|  | } | 
|  |  | 
|  | This->line = This->realLine; | 
|  | This->column = This->realColumn; | 
|  | } | 
|  |  | 
|  | /*** IVBSAXAttributes interface ***/ | 
|  | /*** IUnknown methods ***/ | 
|  | static HRESULT WINAPI ivbsaxattributes_QueryInterface( | 
|  | IVBSAXAttributes* iface, | 
|  | REFIID riid, | 
|  | void **ppvObject) | 
|  | { | 
|  | saxattributes *This = impl_from_IVBSAXAttributes(iface); | 
|  |  | 
|  | TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); | 
|  |  | 
|  | *ppvObject = NULL; | 
|  |  | 
|  | if (IsEqualGUID(riid, &IID_IUnknown) || | 
|  | IsEqualGUID(riid, &IID_IDispatch) || | 
|  | IsEqualGUID(riid, &IID_IVBSAXAttributes)) | 
|  | { | 
|  | *ppvObject = iface; | 
|  | } | 
|  | else | 
|  | { | 
|  | FIXME("interface %s not implemented\n", debugstr_guid(riid)); | 
|  | return E_NOINTERFACE; | 
|  | } | 
|  |  | 
|  | IVBSAXAttributes_AddRef(iface); | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI ivbsaxattributes_AddRef(IVBSAXAttributes* iface) | 
|  | { | 
|  | saxattributes *This = impl_from_IVBSAXAttributes(iface); | 
|  | return ISAXAttributes_AddRef(&This->ISAXAttributes_iface); | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI ivbsaxattributes_Release(IVBSAXAttributes* iface) | 
|  | { | 
|  | saxattributes *This = impl_from_IVBSAXAttributes(iface); | 
|  | return ISAXAttributes_Release(&This->ISAXAttributes_iface); | 
|  | } | 
|  |  | 
|  | /*** IDispatch methods ***/ | 
|  | static HRESULT WINAPI ivbsaxattributes_GetTypeInfoCount( IVBSAXAttributes *iface, UINT* pctinfo ) | 
|  | { | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  |  | 
|  | TRACE("(%p)->(%p)\n", This, pctinfo); | 
|  |  | 
|  | *pctinfo = 1; | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_GetTypeInfo( | 
|  | IVBSAXAttributes *iface, | 
|  | UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo ) | 
|  | { | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | HRESULT hr; | 
|  |  | 
|  | TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); | 
|  |  | 
|  | hr = get_typeinfo(IVBSAXAttributes_tid, ppTInfo); | 
|  |  | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_GetIDsOfNames( | 
|  | IVBSAXAttributes *iface, | 
|  | REFIID riid, | 
|  | LPOLESTR* rgszNames, | 
|  | UINT cNames, | 
|  | LCID lcid, | 
|  | DISPID* rgDispId) | 
|  | { | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | ITypeInfo *typeinfo; | 
|  | HRESULT hr; | 
|  |  | 
|  | TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, | 
|  | lcid, rgDispId); | 
|  |  | 
|  | if(!rgszNames || cNames == 0 || !rgDispId) | 
|  | return E_INVALIDARG; | 
|  |  | 
|  | hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo); | 
|  | if(SUCCEEDED(hr)) | 
|  | { | 
|  | hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); | 
|  | ITypeInfo_Release(typeinfo); | 
|  | } | 
|  |  | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_Invoke( | 
|  | IVBSAXAttributes *iface, | 
|  | DISPID dispIdMember, | 
|  | REFIID riid, | 
|  | LCID lcid, | 
|  | WORD wFlags, | 
|  | DISPPARAMS* pDispParams, | 
|  | VARIANT* pVarResult, | 
|  | EXCEPINFO* pExcepInfo, | 
|  | UINT* puArgErr) | 
|  | { | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | ITypeInfo *typeinfo; | 
|  | HRESULT hr; | 
|  |  | 
|  | TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), | 
|  | lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); | 
|  |  | 
|  | hr = get_typeinfo(IVBSAXAttributes_tid, &typeinfo); | 
|  | if(SUCCEEDED(hr)) | 
|  | { | 
|  | hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXAttributes_iface, dispIdMember, wFlags, | 
|  | pDispParams, pVarResult, pExcepInfo, puArgErr); | 
|  | ITypeInfo_Release(typeinfo); | 
|  | } | 
|  |  | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | /*** IVBSAXAttributes methods ***/ | 
|  | static HRESULT WINAPI ivbsaxattributes_get_length( | 
|  | IVBSAXAttributes* iface, | 
|  | int *nLength) | 
|  | { | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | return ISAXAttributes_getLength(&This->ISAXAttributes_iface, nLength); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_getURI( | 
|  | IVBSAXAttributes* iface, | 
|  | int nIndex, | 
|  | BSTR *uri) | 
|  | { | 
|  | int len; | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | return ISAXAttributes_getURI(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)uri, &len); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_getLocalName( | 
|  | IVBSAXAttributes* iface, | 
|  | int nIndex, | 
|  | BSTR *localName) | 
|  | { | 
|  | int len; | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | return ISAXAttributes_getLocalName(&This->ISAXAttributes_iface, nIndex, | 
|  | (const WCHAR**)localName, &len); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_getQName( | 
|  | IVBSAXAttributes* iface, | 
|  | int nIndex, | 
|  | BSTR *QName) | 
|  | { | 
|  | int len; | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | return ISAXAttributes_getQName(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)QName, &len); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_getIndexFromName( | 
|  | IVBSAXAttributes* iface, | 
|  | BSTR uri, | 
|  | BSTR localName, | 
|  | int *index) | 
|  | { | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | return ISAXAttributes_getIndexFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri), | 
|  | localName, SysStringLen(localName), index); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_getIndexFromQName( | 
|  | IVBSAXAttributes* iface, | 
|  | BSTR QName, | 
|  | int *index) | 
|  | { | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | return ISAXAttributes_getIndexFromQName(&This->ISAXAttributes_iface, QName, | 
|  | SysStringLen(QName), index); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_getType( | 
|  | IVBSAXAttributes* iface, | 
|  | int nIndex, | 
|  | BSTR *type) | 
|  | { | 
|  | int len; | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | return ISAXAttributes_getType(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)type, &len); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_getTypeFromName( | 
|  | IVBSAXAttributes* iface, | 
|  | BSTR uri, | 
|  | BSTR localName, | 
|  | BSTR *type) | 
|  | { | 
|  | int len; | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | return ISAXAttributes_getTypeFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri), | 
|  | localName, SysStringLen(localName), (const WCHAR**)type, &len); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_getTypeFromQName( | 
|  | IVBSAXAttributes* iface, | 
|  | BSTR QName, | 
|  | BSTR *type) | 
|  | { | 
|  | int len; | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | return ISAXAttributes_getTypeFromQName(&This->ISAXAttributes_iface, QName, SysStringLen(QName), | 
|  | (const WCHAR**)type, &len); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_getValue( | 
|  | IVBSAXAttributes* iface, | 
|  | int nIndex, | 
|  | BSTR *value) | 
|  | { | 
|  | int len; | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | return ISAXAttributes_getValue(&This->ISAXAttributes_iface, nIndex, (const WCHAR**)value, &len); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_getValueFromName( | 
|  | IVBSAXAttributes* iface, | 
|  | BSTR uri, | 
|  | BSTR localName, | 
|  | BSTR *value) | 
|  | { | 
|  | int len; | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | return ISAXAttributes_getValueFromName(&This->ISAXAttributes_iface, uri, SysStringLen(uri), | 
|  | localName, SysStringLen(localName), (const WCHAR**)value, &len); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxattributes_getValueFromQName( | 
|  | IVBSAXAttributes* iface, | 
|  | BSTR QName, | 
|  | BSTR *value) | 
|  | { | 
|  | int len; | 
|  | saxattributes *This = impl_from_IVBSAXAttributes( iface ); | 
|  | return ISAXAttributes_getValueFromQName(&This->ISAXAttributes_iface, QName, | 
|  | SysStringLen(QName), (const WCHAR**)value, &len); | 
|  | } | 
|  |  | 
|  | static const struct IVBSAXAttributesVtbl ivbsaxattributes_vtbl = | 
|  | { | 
|  | ivbsaxattributes_QueryInterface, | 
|  | ivbsaxattributes_AddRef, | 
|  | ivbsaxattributes_Release, | 
|  | ivbsaxattributes_GetTypeInfoCount, | 
|  | ivbsaxattributes_GetTypeInfo, | 
|  | ivbsaxattributes_GetIDsOfNames, | 
|  | ivbsaxattributes_Invoke, | 
|  | ivbsaxattributes_get_length, | 
|  | ivbsaxattributes_getURI, | 
|  | ivbsaxattributes_getLocalName, | 
|  | ivbsaxattributes_getQName, | 
|  | ivbsaxattributes_getIndexFromName, | 
|  | ivbsaxattributes_getIndexFromQName, | 
|  | ivbsaxattributes_getType, | 
|  | ivbsaxattributes_getTypeFromName, | 
|  | ivbsaxattributes_getTypeFromQName, | 
|  | ivbsaxattributes_getValue, | 
|  | ivbsaxattributes_getValueFromName, | 
|  | ivbsaxattributes_getValueFromQName | 
|  | }; | 
|  |  | 
|  | /*** ISAXAttributes interface ***/ | 
|  | /*** IUnknown methods ***/ | 
|  | static HRESULT WINAPI isaxattributes_QueryInterface( | 
|  | ISAXAttributes* iface, | 
|  | REFIID riid, | 
|  | void **ppvObject) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes(iface); | 
|  |  | 
|  | TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject); | 
|  |  | 
|  | *ppvObject = NULL; | 
|  |  | 
|  | if (IsEqualGUID(riid, &IID_IUnknown) || | 
|  | IsEqualGUID(riid, &IID_ISAXAttributes)) | 
|  | { | 
|  | *ppvObject = iface; | 
|  | } | 
|  | else | 
|  | { | 
|  | FIXME("interface %s not implemented\n", debugstr_guid(riid)); | 
|  | return E_NOINTERFACE; | 
|  | } | 
|  |  | 
|  | ISAXAttributes_AddRef(iface); | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI isaxattributes_AddRef(ISAXAttributes* iface) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes(iface); | 
|  | TRACE("%p\n", This); | 
|  | return InterlockedIncrement(&This->ref); | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI isaxattributes_Release(ISAXAttributes* iface) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes(iface); | 
|  | LONG ref; | 
|  |  | 
|  | TRACE("%p\n", This); | 
|  |  | 
|  | ref = InterlockedDecrement(&This->ref); | 
|  | if (ref==0) | 
|  | { | 
|  | int index; | 
|  | for(index=0; index<This->nb_attributes; index++) | 
|  | { | 
|  | SysFreeString(This->szLocalname[index]); | 
|  | SysFreeString(This->szURI[index]); | 
|  | SysFreeString(This->szValue[index]); | 
|  | SysFreeString(This->szQName[index]); | 
|  | } | 
|  |  | 
|  | heap_free(This->szLocalname); | 
|  | heap_free(This->szURI); | 
|  | heap_free(This->szValue); | 
|  | heap_free(This->szQName); | 
|  |  | 
|  | heap_free(This); | 
|  | } | 
|  |  | 
|  | return ref; | 
|  | } | 
|  |  | 
|  | /*** ISAXAttributes methods ***/ | 
|  | static HRESULT WINAPI isaxattributes_getLength( | 
|  | ISAXAttributes* iface, | 
|  | int *length) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes( iface ); | 
|  |  | 
|  | *length = This->nb_attributes; | 
|  | TRACE("Length set to %d\n", *length); | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxattributes_getURI( | 
|  | ISAXAttributes* iface, | 
|  | int nIndex, | 
|  | const WCHAR **pUrl, | 
|  | int *pUriSize) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes( iface ); | 
|  | TRACE("(%p)->(%d)\n", This, nIndex); | 
|  |  | 
|  | if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG; | 
|  | if(!pUrl || !pUriSize) return E_POINTER; | 
|  |  | 
|  | *pUriSize = SysStringLen(This->szURI[nIndex]); | 
|  | *pUrl = This->szURI[nIndex]; | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxattributes_getLocalName( | 
|  | ISAXAttributes* iface, | 
|  | int nIndex, | 
|  | const WCHAR **pLocalName, | 
|  | int *pLocalNameLength) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes( iface ); | 
|  | TRACE("(%p)->(%d)\n", This, nIndex); | 
|  |  | 
|  | if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG; | 
|  | if(!pLocalName || !pLocalNameLength) return E_POINTER; | 
|  |  | 
|  | *pLocalNameLength = SysStringLen(This->szLocalname[nIndex]); | 
|  | *pLocalName = This->szLocalname[nIndex]; | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxattributes_getQName( | 
|  | ISAXAttributes* iface, | 
|  | int nIndex, | 
|  | const WCHAR **pQName, | 
|  | int *pQNameLength) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes( iface ); | 
|  | TRACE("(%p)->(%d)\n", This, nIndex); | 
|  |  | 
|  | if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG; | 
|  | if(!pQName || !pQNameLength) return E_POINTER; | 
|  |  | 
|  | *pQNameLength = SysStringLen(This->szQName[nIndex]); | 
|  | *pQName = This->szQName[nIndex]; | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxattributes_getName( | 
|  | ISAXAttributes* iface, | 
|  | int nIndex, | 
|  | const WCHAR **pUri, | 
|  | int *pUriLength, | 
|  | const WCHAR **pLocalName, | 
|  | int *pLocalNameSize, | 
|  | const WCHAR **pQName, | 
|  | int *pQNameLength) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes( iface ); | 
|  | TRACE("(%p)->(%d)\n", This, nIndex); | 
|  |  | 
|  | if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG; | 
|  | if(!pUri || !pUriLength || !pLocalName || !pLocalNameSize | 
|  | || !pQName || !pQNameLength) return E_POINTER; | 
|  |  | 
|  | *pUriLength = SysStringLen(This->szURI[nIndex]); | 
|  | *pUri = This->szURI[nIndex]; | 
|  | *pLocalNameSize = SysStringLen(This->szLocalname[nIndex]); | 
|  | *pLocalName = This->szLocalname[nIndex]; | 
|  | *pQNameLength = SysStringLen(This->szQName[nIndex]); | 
|  | *pQName = This->szQName[nIndex]; | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxattributes_getIndexFromName( | 
|  | ISAXAttributes* iface, | 
|  | const WCHAR *pUri, | 
|  | int cUriLength, | 
|  | const WCHAR *pLocalName, | 
|  | int cocalNameLength, | 
|  | int *index) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes( iface ); | 
|  | int i; | 
|  | TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), cUriLength, | 
|  | debugstr_w(pLocalName), cocalNameLength); | 
|  |  | 
|  | if(!pUri || !pLocalName || !index) return E_POINTER; | 
|  |  | 
|  | for(i=0; i<This->nb_attributes; i++) | 
|  | { | 
|  | if(cUriLength!=SysStringLen(This->szURI[i]) | 
|  | || cocalNameLength!=SysStringLen(This->szLocalname[i])) | 
|  | continue; | 
|  | if(cUriLength && memcmp(pUri, This->szURI[i], | 
|  | sizeof(WCHAR)*cUriLength)) | 
|  | continue; | 
|  | if(cocalNameLength && memcmp(pLocalName, This->szLocalname[i], | 
|  | sizeof(WCHAR)*cocalNameLength)) | 
|  | continue; | 
|  |  | 
|  | *index = i; | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | return E_INVALIDARG; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxattributes_getIndexFromQName( | 
|  | ISAXAttributes* iface, | 
|  | const WCHAR *pQName, | 
|  | int nQNameLength, | 
|  | int *index) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes( iface ); | 
|  | int i; | 
|  | TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQNameLength); | 
|  |  | 
|  | if(!pQName || !index) return E_POINTER; | 
|  | if(!nQNameLength) return E_INVALIDARG; | 
|  |  | 
|  | for(i=0; i<This->nb_attributes; i++) | 
|  | { | 
|  | if(nQNameLength!=SysStringLen(This->szQName[i])) continue; | 
|  | if(memcmp(pQName, This->szQName, sizeof(WCHAR)*nQNameLength)) continue; | 
|  |  | 
|  | *index = i; | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | return E_INVALIDARG; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxattributes_getType( | 
|  | ISAXAttributes* iface, | 
|  | int nIndex, | 
|  | const WCHAR **pType, | 
|  | int *pTypeLength) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes( iface ); | 
|  |  | 
|  | FIXME("(%p)->(%d) stub\n", This, nIndex); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxattributes_getTypeFromName( | 
|  | ISAXAttributes* iface, | 
|  | const WCHAR *pUri, | 
|  | int nUri, | 
|  | const WCHAR *pLocalName, | 
|  | int nLocalName, | 
|  | const WCHAR **pType, | 
|  | int *nType) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes( iface ); | 
|  |  | 
|  | FIXME("(%p)->(%s, %d, %s, %d) stub\n", This, debugstr_w(pUri), nUri, | 
|  | debugstr_w(pLocalName), nLocalName); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxattributes_getTypeFromQName( | 
|  | ISAXAttributes* iface, | 
|  | const WCHAR *pQName, | 
|  | int nQName, | 
|  | const WCHAR **pType, | 
|  | int *nType) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes( iface ); | 
|  |  | 
|  | FIXME("(%p)->(%s, %d) stub\n", This, debugstr_w(pQName), nQName); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxattributes_getValue( | 
|  | ISAXAttributes* iface, | 
|  | int nIndex, | 
|  | const WCHAR **pValue, | 
|  | int *nValue) | 
|  | { | 
|  | saxattributes *This = impl_from_ISAXAttributes( iface ); | 
|  | TRACE("(%p)->(%d)\n", This, nIndex); | 
|  |  | 
|  | if(nIndex>=This->nb_attributes || nIndex<0) return E_INVALIDARG; | 
|  | if(!pValue || !nValue) return E_POINTER; | 
|  |  | 
|  | *nValue = SysStringLen(This->szValue[nIndex]); | 
|  | *pValue = This->szValue[nIndex]; | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxattributes_getValueFromName( | 
|  | ISAXAttributes* iface, | 
|  | const WCHAR *pUri, | 
|  | int nUri, | 
|  | const WCHAR *pLocalName, | 
|  | int nLocalName, | 
|  | const WCHAR **pValue, | 
|  | int *nValue) | 
|  | { | 
|  | HRESULT hr; | 
|  | int index; | 
|  | saxattributes *This = impl_from_ISAXAttributes( iface ); | 
|  | TRACE("(%p)->(%s, %d, %s, %d)\n", This, debugstr_w(pUri), nUri, | 
|  | debugstr_w(pLocalName), nLocalName); | 
|  |  | 
|  | hr = ISAXAttributes_getIndexFromName(iface, | 
|  | pUri, nUri, pLocalName, nLocalName, &index); | 
|  | if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue); | 
|  |  | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxattributes_getValueFromQName( | 
|  | ISAXAttributes* iface, | 
|  | const WCHAR *pQName, | 
|  | int nQName, | 
|  | const WCHAR **pValue, | 
|  | int *nValue) | 
|  | { | 
|  | HRESULT hr; | 
|  | int index; | 
|  | saxattributes *This = impl_from_ISAXAttributes( iface ); | 
|  | TRACE("(%p)->(%s, %d)\n", This, debugstr_w(pQName), nQName); | 
|  |  | 
|  | hr = ISAXAttributes_getIndexFromQName(iface, pQName, nQName, &index); | 
|  | if(hr==S_OK) hr = ISAXAttributes_getValue(iface, index, pValue, nValue); | 
|  |  | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | static const struct ISAXAttributesVtbl isaxattributes_vtbl = | 
|  | { | 
|  | isaxattributes_QueryInterface, | 
|  | isaxattributes_AddRef, | 
|  | isaxattributes_Release, | 
|  | isaxattributes_getLength, | 
|  | isaxattributes_getURI, | 
|  | isaxattributes_getLocalName, | 
|  | isaxattributes_getQName, | 
|  | isaxattributes_getName, | 
|  | isaxattributes_getIndexFromName, | 
|  | isaxattributes_getIndexFromQName, | 
|  | isaxattributes_getType, | 
|  | isaxattributes_getTypeFromName, | 
|  | isaxattributes_getTypeFromQName, | 
|  | isaxattributes_getValue, | 
|  | isaxattributes_getValueFromName, | 
|  | isaxattributes_getValueFromQName | 
|  | }; | 
|  |  | 
|  | static HRESULT SAXAttributes_create(saxattributes **attr, | 
|  | int nb_namespaces, const xmlChar **xmlNamespaces, | 
|  | int nb_attributes, const xmlChar **xmlAttributes) | 
|  | { | 
|  | saxattributes *attributes; | 
|  | int index; | 
|  | static const xmlChar xmlns[] = "xmlns"; | 
|  |  | 
|  | attributes = heap_alloc(sizeof(*attributes)); | 
|  | if(!attributes) | 
|  | return E_OUTOFMEMORY; | 
|  |  | 
|  | attributes->IVBSAXAttributes_iface.lpVtbl = &ivbsaxattributes_vtbl; | 
|  | attributes->ISAXAttributes_iface.lpVtbl = &isaxattributes_vtbl; | 
|  | attributes->ref = 1; | 
|  |  | 
|  | attributes->nb_attributes = nb_namespaces+nb_attributes; | 
|  |  | 
|  | attributes->szLocalname = heap_alloc(sizeof(BSTR)*attributes->nb_attributes); | 
|  | attributes->szURI = heap_alloc(sizeof(BSTR)*attributes->nb_attributes); | 
|  | attributes->szValue = heap_alloc(sizeof(BSTR)*attributes->nb_attributes); | 
|  | attributes->szQName = heap_alloc(sizeof(BSTR)*attributes->nb_attributes); | 
|  |  | 
|  | if(!attributes->szLocalname || !attributes->szURI | 
|  | || !attributes->szValue || !attributes->szQName) | 
|  | { | 
|  | heap_free(attributes->szLocalname); | 
|  | heap_free(attributes->szURI); | 
|  | heap_free(attributes->szValue); | 
|  | heap_free(attributes->szQName); | 
|  | heap_free(attributes); | 
|  | return E_FAIL; | 
|  | } | 
|  |  | 
|  | for(index=0; index<nb_namespaces; index++) | 
|  | { | 
|  | attributes->szLocalname[index] = SysAllocStringLen(NULL, 0); | 
|  | attributes->szURI[index] = SysAllocStringLen(NULL, 0); | 
|  | attributes->szValue[index] = bstr_from_xmlChar(xmlNamespaces[2*index+1]); | 
|  | attributes->szQName[index] = QName_from_xmlChar(xmlns, xmlNamespaces[2*index]); | 
|  | } | 
|  |  | 
|  | for(index=0; index<nb_attributes; index++) | 
|  | { | 
|  | attributes->szLocalname[nb_namespaces+index] = | 
|  | bstr_from_xmlChar(xmlAttributes[index*5]); | 
|  | attributes->szURI[nb_namespaces+index] = | 
|  | bstr_from_xmlChar(xmlAttributes[index*5+2]); | 
|  | attributes->szValue[nb_namespaces+index] = | 
|  | bstr_from_xmlCharN(xmlAttributes[index*5+3], | 
|  | xmlAttributes[index*5+4]-xmlAttributes[index*5+3]); | 
|  | attributes->szQName[nb_namespaces+index] = | 
|  | QName_from_xmlChar(xmlAttributes[index*5+1], xmlAttributes[index*5]); | 
|  | } | 
|  |  | 
|  | *attr = attributes; | 
|  |  | 
|  | TRACE("returning %p\n", *attr); | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | /*** LibXML callbacks ***/ | 
|  | static void libxmlStartDocument(void *ctx) | 
|  | { | 
|  | saxlocator *This = ctx; | 
|  | HRESULT hr; | 
|  |  | 
|  | if(has_content_handler(This)) | 
|  | { | 
|  | if(This->vbInterface) | 
|  | hr = IVBSAXContentHandler_startDocument(This->saxreader->vbcontentHandler); | 
|  | else | 
|  | hr = ISAXContentHandler_startDocument(This->saxreader->contentHandler); | 
|  |  | 
|  | if(hr != S_OK) | 
|  | format_error_message_from_id(This, hr); | 
|  | } | 
|  |  | 
|  | update_position(This, NULL); | 
|  | } | 
|  |  | 
|  | static void libxmlEndDocument(void *ctx) | 
|  | { | 
|  | saxlocator *This = ctx; | 
|  | HRESULT hr; | 
|  |  | 
|  | This->column = 0; | 
|  | This->line = 0; | 
|  |  | 
|  | if(This->ret != S_OK) return; | 
|  |  | 
|  | if(has_content_handler(This)) | 
|  | { | 
|  | if(This->vbInterface) | 
|  | hr = IVBSAXContentHandler_endDocument(This->saxreader->vbcontentHandler); | 
|  | else | 
|  | hr = ISAXContentHandler_endDocument(This->saxreader->contentHandler); | 
|  |  | 
|  | if(hr != S_OK) | 
|  | format_error_message_from_id(This, hr); | 
|  | } | 
|  | } | 
|  |  | 
|  | static void libxmlStartElementNS( | 
|  | void *ctx, | 
|  | const xmlChar *localname, | 
|  | const xmlChar *prefix, | 
|  | const xmlChar *URI, | 
|  | int nb_namespaces, | 
|  | const xmlChar **namespaces, | 
|  | int nb_attributes, | 
|  | int nb_defaulted, | 
|  | const xmlChar **attributes) | 
|  | { | 
|  | BSTR NamespaceUri, LocalName, QName, Prefix, Uri; | 
|  | saxlocator *This = ctx; | 
|  | HRESULT hr; | 
|  | saxattributes *attr; | 
|  | int index; | 
|  |  | 
|  | if(*(This->pParserCtxt->input->cur) == '/') | 
|  | update_position(This, (xmlChar*)This->pParserCtxt->input->cur+2); | 
|  | else | 
|  | update_position(This, (xmlChar*)This->pParserCtxt->input->cur+1); | 
|  |  | 
|  | hr = namespacePush(This, nb_namespaces); | 
|  | if(hr==S_OK && has_content_handler(This)) | 
|  | { | 
|  | for(index=0; index<nb_namespaces; index++) | 
|  | { | 
|  | Prefix = pooled_bstr_from_xmlChar(&This->saxreader->pool, namespaces[2*index]); | 
|  | Uri = pooled_bstr_from_xmlChar(&This->saxreader->pool, namespaces[2*index+1]); | 
|  |  | 
|  | if(This->vbInterface) | 
|  | hr = IVBSAXContentHandler_startPrefixMapping( | 
|  | This->saxreader->vbcontentHandler, | 
|  | &Prefix, &Uri); | 
|  | else | 
|  | hr = ISAXContentHandler_startPrefixMapping( | 
|  | This->saxreader->contentHandler, | 
|  | Prefix, SysStringLen(Prefix), | 
|  | Uri, SysStringLen(Uri)); | 
|  |  | 
|  | if(hr != S_OK) | 
|  | { | 
|  | format_error_message_from_id(This, hr); | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | NamespaceUri = pooled_bstr_from_xmlChar(&This->saxreader->pool, URI); | 
|  | LocalName = pooled_bstr_from_xmlChar(&This->saxreader->pool, localname); | 
|  | QName = pooled_QName_from_xmlChar(&This->saxreader->pool, prefix, localname); | 
|  |  | 
|  | hr = SAXAttributes_create(&attr, nb_namespaces, namespaces, nb_attributes, attributes); | 
|  | if(hr == S_OK) | 
|  | { | 
|  | if(This->vbInterface) | 
|  | hr = IVBSAXContentHandler_startElement(This->saxreader->vbcontentHandler, | 
|  | &NamespaceUri, &LocalName, &QName, &attr->IVBSAXAttributes_iface); | 
|  | else | 
|  | hr = ISAXContentHandler_startElement(This->saxreader->contentHandler, NamespaceUri, | 
|  | SysStringLen(NamespaceUri), LocalName, SysStringLen(LocalName), QName, | 
|  | SysStringLen(QName), &attr->ISAXAttributes_iface); | 
|  |  | 
|  | ISAXAttributes_Release(&attr->ISAXAttributes_iface); | 
|  | } | 
|  | } | 
|  |  | 
|  | if(hr != S_OK) | 
|  | format_error_message_from_id(This, hr); | 
|  | } | 
|  |  | 
|  | static void libxmlEndElementNS( | 
|  | void *ctx, | 
|  | const xmlChar *localname, | 
|  | const xmlChar *prefix, | 
|  | const xmlChar *URI) | 
|  | { | 
|  | BSTR NamespaceUri, LocalName, QName, Prefix; | 
|  | saxlocator *This = ctx; | 
|  | HRESULT hr; | 
|  | xmlChar *end; | 
|  | int nsNr, index; | 
|  |  | 
|  | end = (xmlChar*)This->pParserCtxt->input->cur; | 
|  | if(*(end-1) != '>' || *(end-2) != '/') | 
|  | while(end-2>=This->pParserCtxt->input->base | 
|  | && *(end-2)!='<' && *(end-1)!='/') end--; | 
|  |  | 
|  | update_position(This, end); | 
|  |  | 
|  | nsNr = namespacePop(This); | 
|  |  | 
|  | if(has_content_handler(This)) | 
|  | { | 
|  | NamespaceUri = pooled_bstr_from_xmlChar(&This->saxreader->pool, URI); | 
|  | LocalName = pooled_bstr_from_xmlChar(&This->saxreader->pool, localname); | 
|  | QName = pooled_QName_from_xmlChar(&This->saxreader->pool, prefix, localname); | 
|  |  | 
|  | if(This->vbInterface) | 
|  | hr = IVBSAXContentHandler_endElement( | 
|  | This->saxreader->vbcontentHandler, | 
|  | &NamespaceUri, &LocalName, &QName); | 
|  | else | 
|  | hr = ISAXContentHandler_endElement( | 
|  | This->saxreader->contentHandler, | 
|  | NamespaceUri, SysStringLen(NamespaceUri), | 
|  | LocalName, SysStringLen(LocalName), | 
|  | QName, SysStringLen(QName)); | 
|  |  | 
|  | if(hr != S_OK) | 
|  | { | 
|  | format_error_message_from_id(This, hr); | 
|  | return; | 
|  | } | 
|  |  | 
|  | for(index=This->pParserCtxt->nsNr-2; | 
|  | index>=This->pParserCtxt->nsNr-nsNr*2; index-=2) | 
|  | { | 
|  | Prefix = pooled_bstr_from_xmlChar(&This->saxreader->pool, This->pParserCtxt->nsTab[index]); | 
|  |  | 
|  | if(This->vbInterface) | 
|  | hr = IVBSAXContentHandler_endPrefixMapping( | 
|  | This->saxreader->vbcontentHandler, &Prefix); | 
|  | else | 
|  | hr = ISAXContentHandler_endPrefixMapping( | 
|  | This->saxreader->contentHandler, | 
|  | Prefix, SysStringLen(Prefix)); | 
|  |  | 
|  | if(hr != S_OK) | 
|  | { | 
|  | format_error_message_from_id(This, hr); | 
|  | return; | 
|  | } | 
|  |  | 
|  | } | 
|  | } | 
|  |  | 
|  | update_position(This, NULL); | 
|  | } | 
|  |  | 
|  | static void libxmlCharacters( | 
|  | void *ctx, | 
|  | const xmlChar *ch, | 
|  | int len) | 
|  | { | 
|  | saxlocator *This = ctx; | 
|  | BSTR Chars; | 
|  | HRESULT hr; | 
|  | xmlChar *cur; | 
|  | xmlChar *end; | 
|  | BOOL lastEvent = FALSE; | 
|  |  | 
|  | if(!(has_content_handler(This))) return; | 
|  |  | 
|  | cur = (xmlChar*)ch; | 
|  | if(*(ch-1)=='\r') cur--; | 
|  | end = cur; | 
|  |  | 
|  | if(ch<This->pParserCtxt->input->base || ch>This->pParserCtxt->input->end) | 
|  | This->column++; | 
|  |  | 
|  | while(1) | 
|  | { | 
|  | while(end-ch<len && *end!='\r') end++; | 
|  | if(end-ch==len) | 
|  | { | 
|  | end--; | 
|  | lastEvent = TRUE; | 
|  | } | 
|  |  | 
|  | if(!lastEvent) *end = '\n'; | 
|  |  | 
|  | Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur+1); | 
|  | if(This->vbInterface) | 
|  | hr = IVBSAXContentHandler_characters( | 
|  | This->saxreader->vbcontentHandler, &Chars); | 
|  | else | 
|  | hr = ISAXContentHandler_characters( | 
|  | This->saxreader->contentHandler, | 
|  | Chars, SysStringLen(Chars)); | 
|  |  | 
|  | if(hr != S_OK) | 
|  | { | 
|  | format_error_message_from_id(This, hr); | 
|  | return; | 
|  | } | 
|  |  | 
|  | This->column += end-cur+1; | 
|  |  | 
|  | if(lastEvent) | 
|  | break; | 
|  |  | 
|  | *end = '\r'; | 
|  | end++; | 
|  | if(*end == '\n') | 
|  | { | 
|  | end++; | 
|  | This->column++; | 
|  | } | 
|  | cur = end; | 
|  |  | 
|  | if(end-ch == len) break; | 
|  | } | 
|  |  | 
|  | if(ch<This->pParserCtxt->input->base || ch>This->pParserCtxt->input->end) | 
|  | This->column = This->realColumn | 
|  | +This->pParserCtxt->input->cur-This->lastCur; | 
|  | } | 
|  |  | 
|  | static void libxmlSetDocumentLocator( | 
|  | void *ctx, | 
|  | xmlSAXLocatorPtr loc) | 
|  | { | 
|  | saxlocator *This = ctx; | 
|  | HRESULT hr = S_OK; | 
|  |  | 
|  | if(has_content_handler(This)) | 
|  | { | 
|  | if(This->vbInterface) | 
|  | hr = IVBSAXContentHandler_putref_documentLocator(This->saxreader->vbcontentHandler, | 
|  | &This->IVBSAXLocator_iface); | 
|  | else | 
|  | hr = ISAXContentHandler_putDocumentLocator(This->saxreader->contentHandler, | 
|  | &This->ISAXLocator_iface); | 
|  | } | 
|  |  | 
|  | if(FAILED(hr)) | 
|  | format_error_message_from_id(This, hr); | 
|  | } | 
|  |  | 
|  | static void libxmlComment(void *ctx, const xmlChar *value) | 
|  | { | 
|  | saxlocator *This = ctx; | 
|  | BSTR bValue; | 
|  | HRESULT hr; | 
|  | xmlChar *beg = (xmlChar*)This->pParserCtxt->input->cur; | 
|  |  | 
|  | while(beg-4>=This->pParserCtxt->input->base | 
|  | && memcmp(beg-4, "<!--", sizeof(char[4]))) beg--; | 
|  | update_position(This, beg); | 
|  |  | 
|  | if(!This->vbInterface && !This->saxreader->lexicalHandler) return; | 
|  | if(This->vbInterface && !This->saxreader->vblexicalHandler) return; | 
|  |  | 
|  | bValue = pooled_bstr_from_xmlChar(&This->saxreader->pool, value); | 
|  |  | 
|  | if(This->vbInterface) | 
|  | hr = IVBSAXLexicalHandler_comment( | 
|  | This->saxreader->vblexicalHandler, &bValue); | 
|  | else | 
|  | hr = ISAXLexicalHandler_comment( | 
|  | This->saxreader->lexicalHandler, | 
|  | bValue, SysStringLen(bValue)); | 
|  |  | 
|  | if(FAILED(hr)) | 
|  | format_error_message_from_id(This, hr); | 
|  |  | 
|  | update_position(This, NULL); | 
|  | } | 
|  |  | 
|  | static void libxmlFatalError(void *ctx, const char *msg, ...) | 
|  | { | 
|  | saxlocator *This = ctx; | 
|  | char message[1024]; | 
|  | WCHAR *error; | 
|  | DWORD len; | 
|  | va_list args; | 
|  |  | 
|  | va_start(args, msg); | 
|  | vsprintf(message, msg, args); | 
|  | va_end(args); | 
|  |  | 
|  | len = MultiByteToWideChar(CP_UNIXCP, 0, message, -1, NULL, 0); | 
|  | error = heap_alloc(sizeof(WCHAR)*len); | 
|  | if(error) | 
|  | { | 
|  | MultiByteToWideChar(CP_UNIXCP, 0, message, -1, error, len); | 
|  | TRACE("fatal error for %p: %s\n", This, debugstr_w(error)); | 
|  | } | 
|  |  | 
|  | if(!has_error_handler(This)) | 
|  | { | 
|  | xmlStopParser(This->pParserCtxt); | 
|  | This->ret = E_FAIL; | 
|  | heap_free(error); | 
|  | return; | 
|  | } | 
|  |  | 
|  | FIXME("Error handling is not compatible.\n"); | 
|  |  | 
|  | if(This->vbInterface) | 
|  | { | 
|  | BSTR bstrError = SysAllocString(error); | 
|  | IVBSAXErrorHandler_fatalError(This->saxreader->vberrorHandler, &This->IVBSAXLocator_iface, | 
|  | &bstrError, E_FAIL); | 
|  | SysFreeString(bstrError); | 
|  | } | 
|  | else | 
|  | ISAXErrorHandler_fatalError(This->saxreader->errorHandler, &This->ISAXLocator_iface, | 
|  | error, E_FAIL); | 
|  |  | 
|  | heap_free(error); | 
|  |  | 
|  | xmlStopParser(This->pParserCtxt); | 
|  | This->ret = E_FAIL; | 
|  | } | 
|  |  | 
|  | static void libxmlCDataBlock(void *ctx, const xmlChar *value, int len) | 
|  | { | 
|  | saxlocator *This = ctx; | 
|  | HRESULT hr = S_OK; | 
|  | xmlChar *beg = (xmlChar*)This->pParserCtxt->input->cur-len; | 
|  | xmlChar *cur, *end; | 
|  | int realLen; | 
|  | BSTR Chars; | 
|  | BOOL lastEvent = FALSE, change; | 
|  |  | 
|  | while(beg-9>=This->pParserCtxt->input->base | 
|  | && memcmp(beg-9, "<![CDATA[", sizeof(char[9]))) beg--; | 
|  | update_position(This, beg); | 
|  |  | 
|  | if(This->vbInterface && This->saxreader->vblexicalHandler) | 
|  | hr = IVBSAXLexicalHandler_startCDATA(This->saxreader->vblexicalHandler); | 
|  | if(!This->vbInterface && This->saxreader->lexicalHandler) | 
|  | hr = ISAXLexicalHandler_startCDATA(This->saxreader->lexicalHandler); | 
|  |  | 
|  | if(FAILED(hr)) | 
|  | { | 
|  | format_error_message_from_id(This, hr); | 
|  | return; | 
|  | } | 
|  |  | 
|  | realLen = This->pParserCtxt->input->cur-beg-3; | 
|  | cur = beg; | 
|  | end = beg; | 
|  |  | 
|  | while(1) | 
|  | { | 
|  | while(end-beg<realLen && *end!='\r') end++; | 
|  | if(end-beg==realLen) | 
|  | { | 
|  | end--; | 
|  | lastEvent = TRUE; | 
|  | } | 
|  | else if(end-beg==realLen-1 && *end=='\r' && *(end+1)=='\n') | 
|  | lastEvent = TRUE; | 
|  |  | 
|  | if(*end == '\r') change = TRUE; | 
|  | else change = FALSE; | 
|  |  | 
|  | if(change) *end = '\n'; | 
|  |  | 
|  | if(has_content_handler(This)) | 
|  | { | 
|  | Chars = pooled_bstr_from_xmlCharN(&This->saxreader->pool, cur, end-cur+1); | 
|  | if(This->vbInterface) | 
|  | hr = IVBSAXContentHandler_characters( | 
|  | This->saxreader->vbcontentHandler, &Chars); | 
|  | else | 
|  | hr = ISAXContentHandler_characters( | 
|  | This->saxreader->contentHandler, | 
|  | Chars, SysStringLen(Chars)); | 
|  | } | 
|  |  | 
|  | if(change) *end = '\r'; | 
|  |  | 
|  | if(lastEvent) | 
|  | break; | 
|  |  | 
|  | This->column += end-cur+2; | 
|  | end += 2; | 
|  | cur = end; | 
|  | } | 
|  |  | 
|  | if(This->vbInterface && This->saxreader->vblexicalHandler) | 
|  | hr = IVBSAXLexicalHandler_endCDATA(This->saxreader->vblexicalHandler); | 
|  | if(!This->vbInterface && This->saxreader->lexicalHandler) | 
|  | hr = ISAXLexicalHandler_endCDATA(This->saxreader->lexicalHandler); | 
|  |  | 
|  | if(FAILED(hr)) | 
|  | format_error_message_from_id(This, hr); | 
|  |  | 
|  | This->column += 4+end-cur; | 
|  | } | 
|  |  | 
|  | /*** IVBSAXLocator interface ***/ | 
|  | /*** IUnknown methods ***/ | 
|  | static HRESULT WINAPI ivbsaxlocator_QueryInterface(IVBSAXLocator* iface, REFIID riid, void **ppvObject) | 
|  | { | 
|  | saxlocator *This = impl_from_IVBSAXLocator( iface ); | 
|  |  | 
|  | TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject); | 
|  |  | 
|  | *ppvObject = NULL; | 
|  |  | 
|  | if ( IsEqualGUID( riid, &IID_IUnknown ) || | 
|  | IsEqualGUID( riid, &IID_IDispatch) || | 
|  | IsEqualGUID( riid, &IID_IVBSAXLocator )) | 
|  | { | 
|  | *ppvObject = iface; | 
|  | } | 
|  | else | 
|  | { | 
|  | FIXME("interface %s not implemented\n", debugstr_guid(riid)); | 
|  | return E_NOINTERFACE; | 
|  | } | 
|  |  | 
|  | IVBSAXLocator_AddRef( iface ); | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI ivbsaxlocator_AddRef(IVBSAXLocator* iface) | 
|  | { | 
|  | saxlocator *This = impl_from_IVBSAXLocator( iface ); | 
|  | TRACE("%p\n", This ); | 
|  | return InterlockedIncrement( &This->ref ); | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI ivbsaxlocator_Release( | 
|  | IVBSAXLocator* iface) | 
|  | { | 
|  | saxlocator *This = impl_from_IVBSAXLocator( iface ); | 
|  | return ISAXLocator_Release((ISAXLocator*)&This->IVBSAXLocator_iface); | 
|  | } | 
|  |  | 
|  | /*** IDispatch methods ***/ | 
|  | static HRESULT WINAPI ivbsaxlocator_GetTypeInfoCount( IVBSAXLocator *iface, UINT* pctinfo ) | 
|  | { | 
|  | saxlocator *This = impl_from_IVBSAXLocator( iface ); | 
|  |  | 
|  | TRACE("(%p)->(%p)\n", This, pctinfo); | 
|  |  | 
|  | *pctinfo = 1; | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxlocator_GetTypeInfo( | 
|  | IVBSAXLocator *iface, | 
|  | UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo ) | 
|  | { | 
|  | saxlocator *This = impl_from_IVBSAXLocator( iface ); | 
|  | HRESULT hr; | 
|  |  | 
|  | TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); | 
|  |  | 
|  | hr = get_typeinfo(IVBSAXLocator_tid, ppTInfo); | 
|  |  | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxlocator_GetIDsOfNames( | 
|  | IVBSAXLocator *iface, | 
|  | REFIID riid, | 
|  | LPOLESTR* rgszNames, | 
|  | UINT cNames, | 
|  | LCID lcid, | 
|  | DISPID* rgDispId) | 
|  | { | 
|  | saxlocator *This = impl_from_IVBSAXLocator( iface ); | 
|  | ITypeInfo *typeinfo; | 
|  | HRESULT hr; | 
|  |  | 
|  | TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, | 
|  | lcid, rgDispId); | 
|  |  | 
|  | if(!rgszNames || cNames == 0 || !rgDispId) | 
|  | return E_INVALIDARG; | 
|  |  | 
|  | hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo); | 
|  | if(SUCCEEDED(hr)) | 
|  | { | 
|  | hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); | 
|  | ITypeInfo_Release(typeinfo); | 
|  | } | 
|  |  | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxlocator_Invoke( | 
|  | IVBSAXLocator *iface, | 
|  | DISPID dispIdMember, | 
|  | REFIID riid, | 
|  | LCID lcid, | 
|  | WORD wFlags, | 
|  | DISPPARAMS* pDispParams, | 
|  | VARIANT* pVarResult, | 
|  | EXCEPINFO* pExcepInfo, | 
|  | UINT* puArgErr) | 
|  | { | 
|  | saxlocator *This = impl_from_IVBSAXLocator( iface ); | 
|  | ITypeInfo *typeinfo; | 
|  | HRESULT hr; | 
|  |  | 
|  | TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), | 
|  | lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); | 
|  |  | 
|  | hr = get_typeinfo(IVBSAXLocator_tid, &typeinfo); | 
|  | if(SUCCEEDED(hr)) | 
|  | { | 
|  | hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXLocator_iface, dispIdMember, wFlags, | 
|  | pDispParams, pVarResult, pExcepInfo, puArgErr); | 
|  | ITypeInfo_Release(typeinfo); | 
|  | } | 
|  |  | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | /*** IVBSAXLocator methods ***/ | 
|  | static HRESULT WINAPI ivbsaxlocator_get_columnNumber( | 
|  | IVBSAXLocator* iface, | 
|  | int *pnColumn) | 
|  | { | 
|  | saxlocator *This = impl_from_IVBSAXLocator( iface ); | 
|  | return ISAXLocator_getColumnNumber((ISAXLocator*)&This->IVBSAXLocator_iface, pnColumn); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxlocator_get_lineNumber( | 
|  | IVBSAXLocator* iface, | 
|  | int *pnLine) | 
|  | { | 
|  | saxlocator *This = impl_from_IVBSAXLocator( iface ); | 
|  | return ISAXLocator_getLineNumber((ISAXLocator*)&This->IVBSAXLocator_iface, pnLine); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxlocator_get_publicId( | 
|  | IVBSAXLocator* iface, | 
|  | BSTR* publicId) | 
|  | { | 
|  | saxlocator *This = impl_from_IVBSAXLocator( iface ); | 
|  | return ISAXLocator_getPublicId((ISAXLocator*)&This->IVBSAXLocator_iface, | 
|  | (const WCHAR**)publicId); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI ivbsaxlocator_get_systemId( | 
|  | IVBSAXLocator* iface, | 
|  | BSTR* systemId) | 
|  | { | 
|  | saxlocator *This = impl_from_IVBSAXLocator( iface ); | 
|  | return ISAXLocator_getSystemId((ISAXLocator*)&This->IVBSAXLocator_iface, | 
|  | (const WCHAR**)systemId); | 
|  | } | 
|  |  | 
|  | static const struct IVBSAXLocatorVtbl ivbsaxlocator_vtbl = | 
|  | { | 
|  | ivbsaxlocator_QueryInterface, | 
|  | ivbsaxlocator_AddRef, | 
|  | ivbsaxlocator_Release, | 
|  | ivbsaxlocator_GetTypeInfoCount, | 
|  | ivbsaxlocator_GetTypeInfo, | 
|  | ivbsaxlocator_GetIDsOfNames, | 
|  | ivbsaxlocator_Invoke, | 
|  | ivbsaxlocator_get_columnNumber, | 
|  | ivbsaxlocator_get_lineNumber, | 
|  | ivbsaxlocator_get_publicId, | 
|  | ivbsaxlocator_get_systemId | 
|  | }; | 
|  |  | 
|  | /*** ISAXLocator interface ***/ | 
|  | /*** IUnknown methods ***/ | 
|  | static HRESULT WINAPI isaxlocator_QueryInterface(ISAXLocator* iface, REFIID riid, void **ppvObject) | 
|  | { | 
|  | saxlocator *This = impl_from_ISAXLocator( iface ); | 
|  |  | 
|  | TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); | 
|  |  | 
|  | *ppvObject = NULL; | 
|  |  | 
|  | if ( IsEqualGUID( riid, &IID_IUnknown ) || | 
|  | IsEqualGUID( riid, &IID_ISAXLocator )) | 
|  | { | 
|  | *ppvObject = iface; | 
|  | } | 
|  | else | 
|  | { | 
|  | FIXME("interface %s not implemented\n", debugstr_guid(riid)); | 
|  | return E_NOINTERFACE; | 
|  | } | 
|  |  | 
|  | ISAXLocator_AddRef( iface ); | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI isaxlocator_AddRef(ISAXLocator* iface) | 
|  | { | 
|  | saxlocator *This = impl_from_ISAXLocator( iface ); | 
|  | TRACE("%p\n", This ); | 
|  | return InterlockedIncrement( &This->ref ); | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI isaxlocator_Release( | 
|  | ISAXLocator* iface) | 
|  | { | 
|  | saxlocator *This = impl_from_ISAXLocator( iface ); | 
|  | LONG ref; | 
|  |  | 
|  | TRACE("%p\n", This ); | 
|  |  | 
|  | ref = InterlockedDecrement( &This->ref ); | 
|  | if ( ref == 0 ) | 
|  | { | 
|  | SysFreeString(This->publicId); | 
|  | SysFreeString(This->systemId); | 
|  | heap_free(This->nsStack); | 
|  |  | 
|  | ISAXXMLReader_Release(&This->saxreader->ISAXXMLReader_iface); | 
|  | heap_free( This ); | 
|  | } | 
|  |  | 
|  | return ref; | 
|  | } | 
|  |  | 
|  | /*** ISAXLocator methods ***/ | 
|  | static HRESULT WINAPI isaxlocator_getColumnNumber( | 
|  | ISAXLocator* iface, | 
|  | int *pnColumn) | 
|  | { | 
|  | saxlocator *This = impl_from_ISAXLocator( iface ); | 
|  |  | 
|  | *pnColumn = This->column; | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxlocator_getLineNumber( | 
|  | ISAXLocator* iface, | 
|  | int *pnLine) | 
|  | { | 
|  | saxlocator *This = impl_from_ISAXLocator( iface ); | 
|  |  | 
|  | *pnLine = This->line; | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxlocator_getPublicId( | 
|  | ISAXLocator* iface, | 
|  | const WCHAR ** ppwchPublicId) | 
|  | { | 
|  | BSTR publicId; | 
|  | saxlocator *This = impl_from_ISAXLocator( iface ); | 
|  |  | 
|  | SysFreeString(This->publicId); | 
|  |  | 
|  | publicId = bstr_from_xmlChar(xmlSAX2GetPublicId(This->pParserCtxt)); | 
|  | if(SysStringLen(publicId)) | 
|  | This->publicId = (WCHAR*)&publicId; | 
|  | else | 
|  | { | 
|  | SysFreeString(publicId); | 
|  | This->publicId = NULL; | 
|  | } | 
|  |  | 
|  | *ppwchPublicId = This->publicId; | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxlocator_getSystemId( | 
|  | ISAXLocator* iface, | 
|  | const WCHAR ** ppwchSystemId) | 
|  | { | 
|  | BSTR systemId; | 
|  | saxlocator *This = impl_from_ISAXLocator( iface ); | 
|  |  | 
|  | SysFreeString(This->systemId); | 
|  |  | 
|  | systemId = bstr_from_xmlChar(xmlSAX2GetSystemId(This->pParserCtxt)); | 
|  | if(SysStringLen(systemId)) | 
|  | This->systemId = (WCHAR*)&systemId; | 
|  | else | 
|  | { | 
|  | SysFreeString(systemId); | 
|  | This->systemId = NULL; | 
|  | } | 
|  |  | 
|  | *ppwchSystemId = This->systemId; | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static const struct ISAXLocatorVtbl isaxlocator_vtbl = | 
|  | { | 
|  | isaxlocator_QueryInterface, | 
|  | isaxlocator_AddRef, | 
|  | isaxlocator_Release, | 
|  | isaxlocator_getColumnNumber, | 
|  | isaxlocator_getLineNumber, | 
|  | isaxlocator_getPublicId, | 
|  | isaxlocator_getSystemId | 
|  | }; | 
|  |  | 
|  | static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator, BOOL vbInterface) | 
|  | { | 
|  | saxlocator *locator; | 
|  |  | 
|  | locator = heap_alloc( sizeof (*locator) ); | 
|  | if( !locator ) | 
|  | return E_OUTOFMEMORY; | 
|  |  | 
|  | locator->IVBSAXLocator_iface.lpVtbl = &ivbsaxlocator_vtbl; | 
|  | locator->ISAXLocator_iface.lpVtbl = &isaxlocator_vtbl; | 
|  | locator->ref = 1; | 
|  | locator->vbInterface = vbInterface; | 
|  |  | 
|  | locator->saxreader = reader; | 
|  | ISAXXMLReader_AddRef(&reader->ISAXXMLReader_iface); | 
|  |  | 
|  | locator->pParserCtxt = NULL; | 
|  | locator->publicId = NULL; | 
|  | locator->systemId = NULL; | 
|  | locator->lastCur = NULL; | 
|  | locator->line = 0; | 
|  | locator->column = 0; | 
|  | locator->ret = S_OK; | 
|  | locator->nsStackSize = 8; | 
|  | locator->nsStackLast = 0; | 
|  | locator->nsStack = heap_alloc(sizeof(int)*locator->nsStackSize); | 
|  | if(!locator->nsStack) | 
|  | { | 
|  | ISAXXMLReader_Release(&reader->ISAXXMLReader_iface); | 
|  | heap_free(locator); | 
|  | return E_OUTOFMEMORY; | 
|  | } | 
|  |  | 
|  | *ppsaxlocator = locator; | 
|  |  | 
|  | TRACE("returning %p\n", *ppsaxlocator); | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | /*** SAXXMLReader internal functions ***/ | 
|  | static HRESULT internal_parseBuffer(saxreader *This, const char *buffer, int size, BOOL vbInterface) | 
|  | { | 
|  | xmlCharEncoding encoding = XML_CHAR_ENCODING_NONE; | 
|  | xmlChar *enc_name = NULL; | 
|  | saxlocator *locator; | 
|  | HRESULT hr; | 
|  |  | 
|  | hr = SAXLocator_create(This, &locator, vbInterface); | 
|  | if(FAILED(hr)) | 
|  | return hr; | 
|  |  | 
|  | if (size >= 4) | 
|  | { | 
|  | const unsigned char *buff = (unsigned char*)buffer; | 
|  |  | 
|  | encoding = xmlDetectCharEncoding((xmlChar*)buffer, 4); | 
|  | enc_name = (xmlChar*)xmlGetCharEncodingName(encoding); | 
|  | TRACE("detected encoding: %s\n", enc_name); | 
|  | /* skip BOM, parser won't switch encodings and so won't skip it on its own */ | 
|  | if ((encoding == XML_CHAR_ENCODING_UTF8) && | 
|  | buff[0] == 0xEF && buff[1] == 0xBB && buff[2] == 0xBF) | 
|  | { | 
|  | buffer += 3; | 
|  | size -= 3; | 
|  | } | 
|  | } | 
|  |  | 
|  | locator->pParserCtxt = xmlCreateMemoryParserCtxt(buffer, size); | 
|  | if(!locator->pParserCtxt) | 
|  | { | 
|  | ISAXLocator_Release(&locator->ISAXLocator_iface); | 
|  | return E_FAIL; | 
|  | } | 
|  |  | 
|  | if (encoding == XML_CHAR_ENCODING_UTF8) | 
|  | locator->pParserCtxt->encoding = xmlStrdup(enc_name); | 
|  |  | 
|  | xmlFree(locator->pParserCtxt->sax); | 
|  | locator->pParserCtxt->sax = &locator->saxreader->sax; | 
|  | locator->pParserCtxt->userData = locator; | 
|  |  | 
|  | This->isParsing = TRUE; | 
|  | if(xmlParseDocument(locator->pParserCtxt) == -1) hr = E_FAIL; | 
|  | else hr = locator->ret; | 
|  | This->isParsing = FALSE; | 
|  |  | 
|  | if(locator->pParserCtxt) | 
|  | { | 
|  | locator->pParserCtxt->sax = NULL; | 
|  | xmlFreeParserCtxt(locator->pParserCtxt); | 
|  | locator->pParserCtxt = NULL; | 
|  | } | 
|  |  | 
|  | ISAXLocator_Release(&locator->ISAXLocator_iface); | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | static HRESULT internal_parseStream(saxreader *This, IStream *stream, BOOL vbInterface) | 
|  | { | 
|  | saxlocator *locator; | 
|  | HRESULT hr; | 
|  | ULONG dataRead; | 
|  | char data[1024]; | 
|  |  | 
|  | hr = IStream_Read(stream, data, sizeof(data), &dataRead); | 
|  | if(hr != S_OK) | 
|  | return hr; | 
|  |  | 
|  | hr = SAXLocator_create(This, &locator, vbInterface); | 
|  | if(FAILED(hr)) | 
|  | return hr; | 
|  |  | 
|  | locator->pParserCtxt = xmlCreatePushParserCtxt( | 
|  | &locator->saxreader->sax, locator, | 
|  | data, dataRead, NULL); | 
|  | if(!locator->pParserCtxt) | 
|  | { | 
|  | ISAXLocator_Release(&locator->ISAXLocator_iface); | 
|  | return E_FAIL; | 
|  | } | 
|  |  | 
|  | This->isParsing = TRUE; | 
|  | while(1) | 
|  | { | 
|  | hr = IStream_Read(stream, data, sizeof(data), &dataRead); | 
|  | if(hr != S_OK) | 
|  | break; | 
|  |  | 
|  | if(xmlParseChunk(locator->pParserCtxt, data, dataRead, 0) != XML_ERR_OK) hr = E_FAIL; | 
|  | else hr = locator->ret; | 
|  |  | 
|  | if(hr != S_OK) break; | 
|  |  | 
|  | if(dataRead != sizeof(data)) | 
|  | { | 
|  | if(xmlParseChunk(locator->pParserCtxt, data, 0, 1) != XML_ERR_OK) hr = E_FAIL; | 
|  | else hr = locator->ret; | 
|  |  | 
|  | break; | 
|  | } | 
|  | } | 
|  | This->isParsing = FALSE; | 
|  |  | 
|  | xmlFreeParserCtxt(locator->pParserCtxt); | 
|  | locator->pParserCtxt = NULL; | 
|  | ISAXLocator_Release(&locator->ISAXLocator_iface); | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | static HRESULT internal_getEntityResolver( | 
|  | saxreader *This, | 
|  | void *pEntityResolver, | 
|  | BOOL vbInterface) | 
|  | { | 
|  | FIXME("(%p)->(%p) stub\n", This, pEntityResolver); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | static HRESULT internal_putEntityResolver( | 
|  | saxreader *This, | 
|  | void *pEntityResolver, | 
|  | BOOL vbInterface) | 
|  | { | 
|  | FIXME("(%p)->(%p) stub\n", This, pEntityResolver); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | static HRESULT internal_getContentHandler( | 
|  | saxreader* This, | 
|  | void *pContentHandler, | 
|  | BOOL vbInterface) | 
|  | { | 
|  | TRACE("(%p)->(%p)\n", This, pContentHandler); | 
|  | if(pContentHandler == NULL) | 
|  | return E_POINTER; | 
|  | if((vbInterface && This->vbcontentHandler) | 
|  | || (!vbInterface && This->contentHandler)) | 
|  | { | 
|  | if(vbInterface) | 
|  | IVBSAXContentHandler_AddRef(This->vbcontentHandler); | 
|  | else | 
|  | ISAXContentHandler_AddRef(This->contentHandler); | 
|  | } | 
|  | if(vbInterface) *(IVBSAXContentHandler**)pContentHandler = | 
|  | This->vbcontentHandler; | 
|  | else *(ISAXContentHandler**)pContentHandler = This->contentHandler; | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT internal_putContentHandler( | 
|  | saxreader* This, | 
|  | void *contentHandler, | 
|  | BOOL vbInterface) | 
|  | { | 
|  | TRACE("(%p)->(%p)\n", This, contentHandler); | 
|  | if(contentHandler) | 
|  | { | 
|  | if(vbInterface) | 
|  | IVBSAXContentHandler_AddRef((IVBSAXContentHandler*)contentHandler); | 
|  | else | 
|  | ISAXContentHandler_AddRef((ISAXContentHandler*)contentHandler); | 
|  | } | 
|  | if((vbInterface && This->vbcontentHandler) | 
|  | || (!vbInterface && This->contentHandler)) | 
|  | { | 
|  | if(vbInterface) | 
|  | IVBSAXContentHandler_Release(This->vbcontentHandler); | 
|  | else | 
|  | ISAXContentHandler_Release(This->contentHandler); | 
|  | } | 
|  | if(vbInterface) | 
|  | This->vbcontentHandler = contentHandler; | 
|  | else | 
|  | This->contentHandler = contentHandler; | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT internal_getDTDHandler( | 
|  | saxreader* This, | 
|  | void *pDTDHandler, | 
|  | BOOL vbInterface) | 
|  | { | 
|  | FIXME("(%p)->(%p) stub\n", This, pDTDHandler); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | static HRESULT internal_putDTDHandler( | 
|  | saxreader* This, | 
|  | void *pDTDHandler, | 
|  | BOOL vbInterface) | 
|  | { | 
|  | FIXME("(%p)->(%p) stub\n", This, pDTDHandler); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | static HRESULT internal_getErrorHandler( | 
|  | saxreader* This, | 
|  | void *pErrorHandler, | 
|  | BOOL vbInterface) | 
|  | { | 
|  | TRACE("(%p)->(%p)\n", This, pErrorHandler); | 
|  | if(pErrorHandler == NULL) | 
|  | return E_POINTER; | 
|  |  | 
|  | if(vbInterface && This->vberrorHandler) | 
|  | IVBSAXErrorHandler_AddRef(This->vberrorHandler); | 
|  | else if(!vbInterface && This->errorHandler) | 
|  | ISAXErrorHandler_AddRef(This->errorHandler); | 
|  |  | 
|  | if(vbInterface) | 
|  | *(IVBSAXErrorHandler**)pErrorHandler = This->vberrorHandler; | 
|  | else | 
|  | *(ISAXErrorHandler**)pErrorHandler = This->errorHandler; | 
|  |  | 
|  | return S_OK; | 
|  |  | 
|  | } | 
|  |  | 
|  | static HRESULT internal_putErrorHandler( | 
|  | saxreader* This, | 
|  | void *errorHandler, | 
|  | BOOL vbInterface) | 
|  | { | 
|  | TRACE("(%p)->(%p)\n", This, errorHandler); | 
|  | if(errorHandler) | 
|  | { | 
|  | if(vbInterface) | 
|  | IVBSAXErrorHandler_AddRef((IVBSAXErrorHandler*)errorHandler); | 
|  | else | 
|  | ISAXErrorHandler_AddRef((ISAXErrorHandler*)errorHandler); | 
|  | } | 
|  |  | 
|  | if(vbInterface && This->vberrorHandler) | 
|  | IVBSAXErrorHandler_Release(This->vberrorHandler); | 
|  | else if(!vbInterface && This->errorHandler) | 
|  | ISAXErrorHandler_Release(This->errorHandler); | 
|  |  | 
|  | if(vbInterface) | 
|  | This->vberrorHandler = errorHandler; | 
|  | else | 
|  | This->errorHandler = errorHandler; | 
|  |  | 
|  | return S_OK; | 
|  |  | 
|  | } | 
|  |  | 
|  | static HRESULT internal_parse( | 
|  | saxreader* This, | 
|  | VARIANT varInput, | 
|  | BOOL vbInterface) | 
|  | { | 
|  | HRESULT hr; | 
|  |  | 
|  | TRACE("(%p)->(%s)\n", This, debugstr_variant(&varInput)); | 
|  |  | 
|  | /* Dispose of the BSTRs in the pool from a prior run, if any. */ | 
|  | free_bstr_pool(&This->pool); | 
|  |  | 
|  | switch(V_VT(&varInput)) | 
|  | { | 
|  | case VT_BSTR: | 
|  | hr = internal_parseBuffer(This, (const char*)V_BSTR(&varInput), | 
|  | SysStringByteLen(V_BSTR(&varInput)), vbInterface); | 
|  | break; | 
|  | case VT_ARRAY|VT_UI1: { | 
|  | void *pSAData; | 
|  | LONG lBound, uBound; | 
|  | ULONG dataRead; | 
|  |  | 
|  | hr = SafeArrayGetLBound(V_ARRAY(&varInput), 1, &lBound); | 
|  | if(hr != S_OK) break; | 
|  | hr = SafeArrayGetUBound(V_ARRAY(&varInput), 1, &uBound); | 
|  | if(hr != S_OK) break; | 
|  | dataRead = (uBound-lBound)*SafeArrayGetElemsize(V_ARRAY(&varInput)); | 
|  | hr = SafeArrayAccessData(V_ARRAY(&varInput), &pSAData); | 
|  | if(hr != S_OK) break; | 
|  | hr = internal_parseBuffer(This, pSAData, dataRead, vbInterface); | 
|  | SafeArrayUnaccessData(V_ARRAY(&varInput)); | 
|  | break; | 
|  | } | 
|  | case VT_UNKNOWN: | 
|  | case VT_DISPATCH: { | 
|  | IPersistStream *persistStream; | 
|  | IStream *stream = NULL; | 
|  | IXMLDOMDocument *xmlDoc; | 
|  |  | 
|  | if(IUnknown_QueryInterface(V_UNKNOWN(&varInput), | 
|  | &IID_IXMLDOMDocument, (void**)&xmlDoc) == S_OK) | 
|  | { | 
|  | BSTR bstrData; | 
|  |  | 
|  | IXMLDOMDocument_get_xml(xmlDoc, &bstrData); | 
|  | hr = internal_parseBuffer(This, (const char*)bstrData, | 
|  | SysStringByteLen(bstrData), vbInterface); | 
|  | IXMLDOMDocument_Release(xmlDoc); | 
|  | SysFreeString(bstrData); | 
|  | break; | 
|  | } | 
|  |  | 
|  | if(IUnknown_QueryInterface(V_UNKNOWN(&varInput), | 
|  | &IID_IPersistStream, (void**)&persistStream) == S_OK) | 
|  | { | 
|  | hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); | 
|  | if(hr != S_OK) | 
|  | { | 
|  | IPersistStream_Release(persistStream); | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | hr = IPersistStream_Save(persistStream, stream, TRUE); | 
|  | IPersistStream_Release(persistStream); | 
|  | if(hr != S_OK) | 
|  | { | 
|  | IStream_Release(stream); | 
|  | break; | 
|  | } | 
|  | } | 
|  | if(stream || IUnknown_QueryInterface(V_UNKNOWN(&varInput), | 
|  | &IID_IStream, (void**)&stream) == S_OK) | 
|  | { | 
|  | hr = internal_parseStream(This, stream, vbInterface); | 
|  | IStream_Release(stream); | 
|  | break; | 
|  | } | 
|  | } | 
|  | default: | 
|  | WARN("vt %d not implemented\n", V_VT(&varInput)); | 
|  | hr = E_INVALIDARG; | 
|  | } | 
|  |  | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | static HRESULT internal_vbonDataAvailable(void *obj, char *ptr, DWORD len) | 
|  | { | 
|  | saxreader *This = obj; | 
|  |  | 
|  | return internal_parseBuffer(This, ptr, len, TRUE); | 
|  | } | 
|  |  | 
|  | static HRESULT internal_onDataAvailable(void *obj, char *ptr, DWORD len) | 
|  | { | 
|  | saxreader *This = obj; | 
|  |  | 
|  | return internal_parseBuffer(This, ptr, len, FALSE); | 
|  | } | 
|  |  | 
|  | static HRESULT internal_parseURL( | 
|  | saxreader* This, | 
|  | const WCHAR *url, | 
|  | BOOL vbInterface) | 
|  | { | 
|  | bsc_t *bsc; | 
|  | HRESULT hr; | 
|  |  | 
|  | TRACE("(%p)->(%s)\n", This, debugstr_w(url)); | 
|  |  | 
|  | if(vbInterface) hr = bind_url(url, internal_vbonDataAvailable, This, &bsc); | 
|  | else hr = bind_url(url, internal_onDataAvailable, This, &bsc); | 
|  |  | 
|  | if(FAILED(hr)) | 
|  | return hr; | 
|  |  | 
|  | detach_bsc(bsc); | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT internal_putProperty( | 
|  | saxreader* This, | 
|  | const WCHAR *pProp, | 
|  | VARIANT value, | 
|  | BOOL vbInterface) | 
|  | { | 
|  | static const WCHAR wszCharset[] = { | 
|  | 'c','h','a','r','s','e','t',0 | 
|  | }; | 
|  | static const WCHAR wszDeclarationHandler[] = { | 
|  | 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/', | 
|  | 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/', | 
|  | 'd','e','c','l','a','r','a','t','i','o','n', | 
|  | '-','h','a','n','d','l','e','r',0 | 
|  | }; | 
|  | static const WCHAR wszDomNode[] = { | 
|  | 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/', | 
|  | 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/', | 
|  | 'd','o','m','-','n','o','d','e',0 | 
|  | }; | 
|  | static const WCHAR wszInputSource[] = { | 
|  | 'i','n','p','u','t','-','s','o','u','r','c','e',0 | 
|  | }; | 
|  | static const WCHAR wszLexicalHandler[] = { | 
|  | 'h','t','t','p',':','/','/','x','m','l','.','o','r','g','/', | 
|  | 's','a','x','/','p','r','o','p','e','r','t','i','e','s','/', | 
|  | 'l','e','x','i','c','a','l','-','h','a','n','d','l','e','r',0 | 
|  | }; | 
|  | static const WCHAR wszMaxElementDepth[] = { | 
|  | 'm','a','x','-','e','l','e','m','e','n','t','-','d','e','p','t','h',0 | 
|  | }; | 
|  | static const WCHAR wszMaxXMLSize[] = { | 
|  | 'm','a','x','-','x','m','l','-','s','i','z','e',0 | 
|  | }; | 
|  | static const WCHAR wszSchemaDeclarationHandler[] = { | 
|  | 's','c','h','e','m','a','-', | 
|  | 'd','e','c','l','a','r','a','t','i','o','n','-', | 
|  | 'h','a','n','d','l','e','r',0 | 
|  | }; | 
|  | static const WCHAR wszXMLDeclEncoding[] = { | 
|  | 'x','m','l','d','e','c','l','-','e','n','c','o','d','i','n','g',0 | 
|  | }; | 
|  | static const WCHAR wszXMLDeclStandalone[] = { | 
|  | 'x','m','l','d','e','c','l', | 
|  | '-','s','t','a','n','d','a','l','o','n','e',0 | 
|  | }; | 
|  | static const WCHAR wszXMLDeclVersion[] = { | 
|  | 'x','m','l','d','e','c','l','-','v','e','r','s','i','o','n',0 | 
|  | }; | 
|  |  | 
|  | TRACE("(%p)->(%s %s)\n", This, debugstr_w(pProp), debugstr_variant(&value)); | 
|  |  | 
|  | if(!memcmp(pProp, wszDeclarationHandler, sizeof(wszDeclarationHandler))) | 
|  | { | 
|  | if(This->isParsing) return E_FAIL; | 
|  |  | 
|  | if(V_UNKNOWN(&value)) | 
|  | { | 
|  | if(vbInterface) | 
|  | IVBSAXDeclHandler_AddRef((IVBSAXDeclHandler*)V_UNKNOWN(&value)); | 
|  | else | 
|  | ISAXDeclHandler_AddRef((ISAXDeclHandler*)V_UNKNOWN(&value)); | 
|  | } | 
|  | if((vbInterface && This->vbdeclHandler) | 
|  | || (!vbInterface && This->declHandler)) | 
|  | { | 
|  | if(vbInterface) | 
|  | IVBSAXDeclHandler_Release(This->vbdeclHandler); | 
|  | else | 
|  | ISAXDeclHandler_Release(This->declHandler); | 
|  | } | 
|  | if(vbInterface) | 
|  | This->vbdeclHandler = (IVBSAXDeclHandler*)V_UNKNOWN(&value); | 
|  | else | 
|  | This->declHandler = (ISAXDeclHandler*)V_UNKNOWN(&value); | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | if(!memcmp(pProp, wszLexicalHandler, sizeof(wszLexicalHandler))) | 
|  | { | 
|  | if(This->isParsing) return E_FAIL; | 
|  |  | 
|  | if(V_UNKNOWN(&value)) | 
|  | { | 
|  | if(vbInterface) | 
|  | IVBSAXLexicalHandler_AddRef( | 
|  | (IVBSAXLexicalHandler*)V_UNKNOWN(&value)); | 
|  | else | 
|  | ISAXLexicalHandler_AddRef( | 
|  | (ISAXLexicalHandler*)V_UNKNOWN(&value)); | 
|  | } | 
|  | if((vbInterface && This->vblexicalHandler) | 
|  | || (!vbInterface && This->lexicalHandler)) | 
|  | { | 
|  | if(vbInterface) | 
|  | IVBSAXLexicalHandler_Release(This->vblexicalHandler); | 
|  | else | 
|  | ISAXLexicalHandler_Release(This->lexicalHandler); | 
|  | } | 
|  | if(vbInterface) | 
|  | This->vblexicalHandler = (IVBSAXLexicalHandler*)V_UNKNOWN(&value); | 
|  | else | 
|  | This->lexicalHandler = (ISAXLexicalHandler*)V_UNKNOWN(&value); | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | FIXME("(%p)->(%s): unsupported property\n", This, debugstr_w(pProp)); | 
|  |  | 
|  | if(!memcmp(pProp, wszCharset, sizeof(wszCharset))) | 
|  | return E_NOTIMPL; | 
|  |  | 
|  | if(!memcmp(pProp, wszDomNode, sizeof(wszDomNode))) | 
|  | return E_FAIL; | 
|  |  | 
|  | if(!memcmp(pProp, wszInputSource, sizeof(wszInputSource))) | 
|  | return E_NOTIMPL; | 
|  |  | 
|  | if(!memcmp(pProp, wszMaxElementDepth, sizeof(wszMaxElementDepth))) | 
|  | return E_NOTIMPL; | 
|  |  | 
|  | if(!memcmp(pProp, wszMaxXMLSize, sizeof(wszMaxXMLSize))) | 
|  | return E_NOTIMPL; | 
|  |  | 
|  | if(!memcmp(pProp, wszSchemaDeclarationHandler, | 
|  | sizeof(wszSchemaDeclarationHandler))) | 
|  | return E_NOTIMPL; | 
|  |  | 
|  | if(!memcmp(pProp, wszXMLDeclEncoding, sizeof(wszXMLDeclEncoding))) | 
|  | return E_FAIL; | 
|  |  | 
|  | if(!memcmp(pProp, wszXMLDeclStandalone, sizeof(wszXMLDeclStandalone))) | 
|  | return E_FAIL; | 
|  |  | 
|  | if(!memcmp(pProp, wszXMLDeclVersion, sizeof(wszXMLDeclVersion))) | 
|  | return E_FAIL; | 
|  |  | 
|  | return E_INVALIDARG; | 
|  | } | 
|  |  | 
|  | /*** IVBSAXXMLReader interface ***/ | 
|  | /*** IUnknown methods ***/ | 
|  | static HRESULT WINAPI saxxmlreader_QueryInterface(IVBSAXXMLReader* iface, REFIID riid, void **ppvObject) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  |  | 
|  | TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppvObject ); | 
|  |  | 
|  | *ppvObject = NULL; | 
|  |  | 
|  | if ( IsEqualGUID( riid, &IID_IUnknown ) || | 
|  | IsEqualGUID( riid, &IID_IDispatch ) || | 
|  | IsEqualGUID( riid, &IID_IVBSAXXMLReader )) | 
|  | { | 
|  | *ppvObject = iface; | 
|  | } | 
|  | else if( IsEqualGUID( riid, &IID_ISAXXMLReader )) | 
|  | { | 
|  | *ppvObject = &This->ISAXXMLReader_iface; | 
|  | } | 
|  | else | 
|  | { | 
|  | FIXME("interface %s not implemented\n", debugstr_guid(riid)); | 
|  | return E_NOINTERFACE; | 
|  | } | 
|  |  | 
|  | IVBSAXXMLReader_AddRef( iface ); | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI saxxmlreader_AddRef(IVBSAXXMLReader* iface) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | TRACE("%p\n", This ); | 
|  | return InterlockedIncrement( &This->ref ); | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI saxxmlreader_Release( | 
|  | IVBSAXXMLReader* iface) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | LONG ref; | 
|  |  | 
|  | TRACE("%p\n", This ); | 
|  |  | 
|  | ref = InterlockedDecrement( &This->ref ); | 
|  | if ( ref == 0 ) | 
|  | { | 
|  | if(This->contentHandler) | 
|  | ISAXContentHandler_Release(This->contentHandler); | 
|  |  | 
|  | if(This->vbcontentHandler) | 
|  | IVBSAXContentHandler_Release(This->vbcontentHandler); | 
|  |  | 
|  | if(This->errorHandler) | 
|  | ISAXErrorHandler_Release(This->errorHandler); | 
|  |  | 
|  | if(This->vberrorHandler) | 
|  | IVBSAXErrorHandler_Release(This->vberrorHandler); | 
|  |  | 
|  | if(This->lexicalHandler) | 
|  | ISAXLexicalHandler_Release(This->lexicalHandler); | 
|  |  | 
|  | if(This->vblexicalHandler) | 
|  | IVBSAXLexicalHandler_Release(This->vblexicalHandler); | 
|  |  | 
|  | if(This->declHandler) | 
|  | ISAXDeclHandler_Release(This->declHandler); | 
|  |  | 
|  | if(This->vbdeclHandler) | 
|  | IVBSAXDeclHandler_Release(This->vbdeclHandler); | 
|  |  | 
|  | free_bstr_pool(&This->pool); | 
|  |  | 
|  | heap_free( This ); | 
|  | } | 
|  |  | 
|  | return ref; | 
|  | } | 
|  | /*** IDispatch ***/ | 
|  | static HRESULT WINAPI saxxmlreader_GetTypeInfoCount( IVBSAXXMLReader *iface, UINT* pctinfo ) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  |  | 
|  | TRACE("(%p)->(%p)\n", This, pctinfo); | 
|  |  | 
|  | *pctinfo = 1; | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_GetTypeInfo( | 
|  | IVBSAXXMLReader *iface, | 
|  | UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo ) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | HRESULT hr; | 
|  |  | 
|  | TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); | 
|  |  | 
|  | hr = get_typeinfo(IVBSAXXMLReader_tid, ppTInfo); | 
|  |  | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_GetIDsOfNames( | 
|  | IVBSAXXMLReader *iface, | 
|  | REFIID riid, | 
|  | LPOLESTR* rgszNames, | 
|  | UINT cNames, | 
|  | LCID lcid, | 
|  | DISPID* rgDispId) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | ITypeInfo *typeinfo; | 
|  | HRESULT hr; | 
|  |  | 
|  | TRACE("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, | 
|  | lcid, rgDispId); | 
|  |  | 
|  | if(!rgszNames || cNames == 0 || !rgDispId) | 
|  | return E_INVALIDARG; | 
|  |  | 
|  | hr = get_typeinfo(IVBSAXXMLReader_tid, &typeinfo); | 
|  | if(SUCCEEDED(hr)) | 
|  | { | 
|  | hr = ITypeInfo_GetIDsOfNames(typeinfo, rgszNames, cNames, rgDispId); | 
|  | ITypeInfo_Release(typeinfo); | 
|  | } | 
|  |  | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_Invoke( | 
|  | IVBSAXXMLReader *iface, | 
|  | DISPID dispIdMember, | 
|  | REFIID riid, | 
|  | LCID lcid, | 
|  | WORD wFlags, | 
|  | DISPPARAMS* pDispParams, | 
|  | VARIANT* pVarResult, | 
|  | EXCEPINFO* pExcepInfo, | 
|  | UINT* puArgErr) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | ITypeInfo *typeinfo; | 
|  | HRESULT hr; | 
|  |  | 
|  | TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), | 
|  | lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); | 
|  |  | 
|  | hr = get_typeinfo(IVBSAXXMLReader_tid, &typeinfo); | 
|  | if(SUCCEEDED(hr)) | 
|  | { | 
|  | hr = ITypeInfo_Invoke(typeinfo, &This->IVBSAXXMLReader_iface, dispIdMember, wFlags, | 
|  | pDispParams, pVarResult, pExcepInfo, puArgErr); | 
|  | ITypeInfo_Release(typeinfo); | 
|  | } | 
|  |  | 
|  | return hr; | 
|  | } | 
|  |  | 
|  | /*** IVBSAXXMLReader methods ***/ | 
|  | static HRESULT WINAPI saxxmlreader_getFeature( | 
|  | IVBSAXXMLReader* iface, | 
|  | const WCHAR *pFeature, | 
|  | VARIANT_BOOL *pValue) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  |  | 
|  | FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pFeature), pValue); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_putFeature( | 
|  | IVBSAXXMLReader* iface, | 
|  | const WCHAR *pFeature, | 
|  | VARIANT_BOOL vfValue) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  |  | 
|  | FIXME("(%p)->(%s %x) stub\n", This, debugstr_w(pFeature), vfValue); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_getProperty( | 
|  | IVBSAXXMLReader* iface, | 
|  | const WCHAR *pProp, | 
|  | VARIANT *pValue) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  |  | 
|  | FIXME("(%p)->(%s %p) stub\n", This, debugstr_w(pProp), pValue); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_putProperty( | 
|  | IVBSAXXMLReader* iface, | 
|  | const WCHAR *pProp, | 
|  | VARIANT value) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | return internal_putProperty(This, pProp, value, TRUE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_get_entityResolver( | 
|  | IVBSAXXMLReader* iface, | 
|  | IVBSAXEntityResolver **pEntityResolver) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | return internal_getEntityResolver(This, pEntityResolver, TRUE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_put_entityResolver( | 
|  | IVBSAXXMLReader* iface, | 
|  | IVBSAXEntityResolver *pEntityResolver) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | return internal_putEntityResolver(This, pEntityResolver, TRUE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_get_contentHandler( | 
|  | IVBSAXXMLReader* iface, | 
|  | IVBSAXContentHandler **ppContentHandler) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | return internal_getContentHandler(This, ppContentHandler, TRUE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_put_contentHandler( | 
|  | IVBSAXXMLReader* iface, | 
|  | IVBSAXContentHandler *contentHandler) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | return internal_putContentHandler(This, contentHandler, TRUE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_get_dtdHandler( | 
|  | IVBSAXXMLReader* iface, | 
|  | IVBSAXDTDHandler **pDTDHandler) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | return internal_getDTDHandler(This, pDTDHandler, TRUE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_put_dtdHandler( | 
|  | IVBSAXXMLReader* iface, | 
|  | IVBSAXDTDHandler *pDTDHandler) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | return internal_putDTDHandler(This, pDTDHandler, TRUE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_get_errorHandler( | 
|  | IVBSAXXMLReader* iface, | 
|  | IVBSAXErrorHandler **pErrorHandler) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | return internal_getErrorHandler(This, pErrorHandler, TRUE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_put_errorHandler( | 
|  | IVBSAXXMLReader* iface, | 
|  | IVBSAXErrorHandler *errorHandler) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | return internal_putErrorHandler(This, errorHandler, TRUE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_get_baseURL( | 
|  | IVBSAXXMLReader* iface, | 
|  | const WCHAR **pBaseUrl) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  |  | 
|  | FIXME("(%p)->(%p) stub\n", This, pBaseUrl); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_put_baseURL( | 
|  | IVBSAXXMLReader* iface, | 
|  | const WCHAR *pBaseUrl) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  |  | 
|  | FIXME("(%p)->(%s) stub\n", This, debugstr_w(pBaseUrl)); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_get_secureBaseURL( | 
|  | IVBSAXXMLReader* iface, | 
|  | const WCHAR **pSecureBaseUrl) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  |  | 
|  | FIXME("(%p)->(%p) stub\n", This, pSecureBaseUrl); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_put_secureBaseURL( | 
|  | IVBSAXXMLReader* iface, | 
|  | const WCHAR *secureBaseUrl) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  |  | 
|  | FIXME("(%p)->(%s) stub\n", This, debugstr_w(secureBaseUrl)); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_parse( | 
|  | IVBSAXXMLReader* iface, | 
|  | VARIANT varInput) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | return internal_parse(This, varInput, TRUE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI saxxmlreader_parseURL( | 
|  | IVBSAXXMLReader* iface, | 
|  | const WCHAR *url) | 
|  | { | 
|  | saxreader *This = impl_from_IVBSAXXMLReader( iface ); | 
|  | return internal_parseURL(This, url, TRUE); | 
|  | } | 
|  |  | 
|  | static const struct IVBSAXXMLReaderVtbl saxreader_vtbl = | 
|  | { | 
|  | saxxmlreader_QueryInterface, | 
|  | saxxmlreader_AddRef, | 
|  | saxxmlreader_Release, | 
|  | saxxmlreader_GetTypeInfoCount, | 
|  | saxxmlreader_GetTypeInfo, | 
|  | saxxmlreader_GetIDsOfNames, | 
|  | saxxmlreader_Invoke, | 
|  | saxxmlreader_getFeature, | 
|  | saxxmlreader_putFeature, | 
|  | saxxmlreader_getProperty, | 
|  | saxxmlreader_putProperty, | 
|  | saxxmlreader_get_entityResolver, | 
|  | saxxmlreader_put_entityResolver, | 
|  | saxxmlreader_get_contentHandler, | 
|  | saxxmlreader_put_contentHandler, | 
|  | saxxmlreader_get_dtdHandler, | 
|  | saxxmlreader_put_dtdHandler, | 
|  | saxxmlreader_get_errorHandler, | 
|  | saxxmlreader_put_errorHandler, | 
|  | saxxmlreader_get_baseURL, | 
|  | saxxmlreader_put_baseURL, | 
|  | saxxmlreader_get_secureBaseURL, | 
|  | saxxmlreader_put_secureBaseURL, | 
|  | saxxmlreader_parse, | 
|  | saxxmlreader_parseURL | 
|  | }; | 
|  |  | 
|  | /*** ISAXXMLReader interface ***/ | 
|  | /*** IUnknown methods ***/ | 
|  | static HRESULT WINAPI isaxxmlreader_QueryInterface(ISAXXMLReader* iface, REFIID riid, void **ppvObject) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return saxxmlreader_QueryInterface(&This->IVBSAXXMLReader_iface, riid, ppvObject); | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI isaxxmlreader_AddRef(ISAXXMLReader* iface) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return saxxmlreader_AddRef(&This->IVBSAXXMLReader_iface); | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI isaxxmlreader_Release(ISAXXMLReader* iface) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return saxxmlreader_Release(&This->IVBSAXXMLReader_iface); | 
|  | } | 
|  |  | 
|  | /*** ISAXXMLReader methods ***/ | 
|  | static HRESULT WINAPI isaxxmlreader_getFeature( | 
|  | ISAXXMLReader* iface, | 
|  | const WCHAR *pFeature, | 
|  | VARIANT_BOOL *pValue) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return IVBSAXXMLReader_getFeature(&This->IVBSAXXMLReader_iface, pFeature, pValue); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_putFeature( | 
|  | ISAXXMLReader* iface, | 
|  | const WCHAR *pFeature, | 
|  | VARIANT_BOOL vfValue) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return IVBSAXXMLReader_putFeature(&This->IVBSAXXMLReader_iface, pFeature, vfValue); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_getProperty( | 
|  | ISAXXMLReader* iface, | 
|  | const WCHAR *pProp, | 
|  | VARIANT *pValue) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return IVBSAXXMLReader_getProperty(&This->IVBSAXXMLReader_iface, pProp, pValue); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_putProperty( | 
|  | ISAXXMLReader* iface, | 
|  | const WCHAR *pProp, | 
|  | VARIANT value) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return internal_putProperty(This, pProp, value, FALSE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_getEntityResolver( | 
|  | ISAXXMLReader* iface, | 
|  | ISAXEntityResolver **ppEntityResolver) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return internal_getEntityResolver(This, ppEntityResolver, FALSE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_putEntityResolver( | 
|  | ISAXXMLReader* iface, | 
|  | ISAXEntityResolver *pEntityResolver) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return internal_putEntityResolver(This, pEntityResolver, FALSE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_getContentHandler( | 
|  | ISAXXMLReader* iface, | 
|  | ISAXContentHandler **pContentHandler) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return internal_getContentHandler(This, pContentHandler, FALSE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_putContentHandler( | 
|  | ISAXXMLReader* iface, | 
|  | ISAXContentHandler *contentHandler) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return internal_putContentHandler(This, contentHandler, FALSE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_getDTDHandler( | 
|  | ISAXXMLReader* iface, | 
|  | ISAXDTDHandler **pDTDHandler) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return internal_getDTDHandler(This, pDTDHandler, FALSE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_putDTDHandler( | 
|  | ISAXXMLReader* iface, | 
|  | ISAXDTDHandler *pDTDHandler) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return internal_putDTDHandler(This, pDTDHandler, FALSE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_getErrorHandler( | 
|  | ISAXXMLReader* iface, | 
|  | ISAXErrorHandler **pErrorHandler) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return internal_getErrorHandler(This, pErrorHandler, FALSE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_putErrorHandler( | 
|  | ISAXXMLReader* iface, | 
|  | ISAXErrorHandler *errorHandler) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return internal_putErrorHandler(This, errorHandler, FALSE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_getBaseURL( | 
|  | ISAXXMLReader* iface, | 
|  | const WCHAR **pBaseUrl) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return IVBSAXXMLReader_get_baseURL(&This->IVBSAXXMLReader_iface, pBaseUrl); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_putBaseURL( | 
|  | ISAXXMLReader* iface, | 
|  | const WCHAR *pBaseUrl) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return IVBSAXXMLReader_put_baseURL(&This->IVBSAXXMLReader_iface, pBaseUrl); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_getSecureBaseURL( | 
|  | ISAXXMLReader* iface, | 
|  | const WCHAR **pSecureBaseUrl) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return IVBSAXXMLReader_get_secureBaseURL(&This->IVBSAXXMLReader_iface, pSecureBaseUrl); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_putSecureBaseURL( | 
|  | ISAXXMLReader* iface, | 
|  | const WCHAR *secureBaseUrl) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return IVBSAXXMLReader_put_secureBaseURL(&This->IVBSAXXMLReader_iface, secureBaseUrl); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_parse( | 
|  | ISAXXMLReader* iface, | 
|  | VARIANT varInput) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return internal_parse(This, varInput, FALSE); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI isaxxmlreader_parseURL( | 
|  | ISAXXMLReader* iface, | 
|  | const WCHAR *url) | 
|  | { | 
|  | saxreader *This = impl_from_ISAXXMLReader( iface ); | 
|  | return internal_parseURL(This, url, FALSE); | 
|  | } | 
|  |  | 
|  | static const struct ISAXXMLReaderVtbl isaxreader_vtbl = | 
|  | { | 
|  | isaxxmlreader_QueryInterface, | 
|  | isaxxmlreader_AddRef, | 
|  | isaxxmlreader_Release, | 
|  | isaxxmlreader_getFeature, | 
|  | isaxxmlreader_putFeature, | 
|  | isaxxmlreader_getProperty, | 
|  | isaxxmlreader_putProperty, | 
|  | isaxxmlreader_getEntityResolver, | 
|  | isaxxmlreader_putEntityResolver, | 
|  | isaxxmlreader_getContentHandler, | 
|  | isaxxmlreader_putContentHandler, | 
|  | isaxxmlreader_getDTDHandler, | 
|  | isaxxmlreader_putDTDHandler, | 
|  | isaxxmlreader_getErrorHandler, | 
|  | isaxxmlreader_putErrorHandler, | 
|  | isaxxmlreader_getBaseURL, | 
|  | isaxxmlreader_putBaseURL, | 
|  | isaxxmlreader_getSecureBaseURL, | 
|  | isaxxmlreader_putSecureBaseURL, | 
|  | isaxxmlreader_parse, | 
|  | isaxxmlreader_parseURL | 
|  | }; | 
|  |  | 
|  | HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj) | 
|  | { | 
|  | saxreader *reader; | 
|  |  | 
|  | TRACE("(%p,%p)\n", pUnkOuter, ppObj); | 
|  |  | 
|  | reader = heap_alloc( sizeof (*reader) ); | 
|  | if( !reader ) | 
|  | return E_OUTOFMEMORY; | 
|  |  | 
|  | reader->IVBSAXXMLReader_iface.lpVtbl = &saxreader_vtbl; | 
|  | reader->ISAXXMLReader_iface.lpVtbl = &isaxreader_vtbl; | 
|  | reader->ref = 1; | 
|  | reader->contentHandler = NULL; | 
|  | reader->vbcontentHandler = NULL; | 
|  | reader->errorHandler = NULL; | 
|  | reader->vberrorHandler = NULL; | 
|  | reader->lexicalHandler = NULL; | 
|  | reader->vblexicalHandler = NULL; | 
|  | reader->declHandler = NULL; | 
|  | reader->vbdeclHandler = NULL; | 
|  | reader->isParsing = FALSE; | 
|  | reader->pool.pool = NULL; | 
|  | reader->pool.index = 0; | 
|  | reader->pool.len = 0; | 
|  |  | 
|  | memset(&reader->sax, 0, sizeof(xmlSAXHandler)); | 
|  | reader->sax.initialized = XML_SAX2_MAGIC; | 
|  | reader->sax.startDocument = libxmlStartDocument; | 
|  | reader->sax.endDocument = libxmlEndDocument; | 
|  | reader->sax.startElementNs = libxmlStartElementNS; | 
|  | reader->sax.endElementNs = libxmlEndElementNS; | 
|  | reader->sax.characters = libxmlCharacters; | 
|  | reader->sax.setDocumentLocator = libxmlSetDocumentLocator; | 
|  | reader->sax.comment = libxmlComment; | 
|  | reader->sax.error = libxmlFatalError; | 
|  | reader->sax.fatalError = libxmlFatalError; | 
|  | reader->sax.cdataBlock = libxmlCDataBlock; | 
|  |  | 
|  | *ppObj = &reader->IVBSAXXMLReader_iface; | 
|  |  | 
|  | TRACE("returning iface %p\n", *ppObj); | 
|  |  | 
|  | return S_OK; | 
|  | } | 
|  |  | 
|  | #else | 
|  |  | 
|  | HRESULT SAXXMLReader_create(IUnknown *pUnkOuter, LPVOID *ppObj) | 
|  | { | 
|  | MESSAGE("This program tried to use a SAX XML Reader object, but\n" | 
|  | "libxml2 support was not present at compile time.\n"); | 
|  | return E_NOTIMPL; | 
|  | } | 
|  |  | 
|  | #endif |