>From a9c1db525a4b6b52cfeac049451ada700cfe1dbf Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Tue, 30 Aug 2011 20:13:11 +1000
Subject: [PATCH] Support creating IXMLParser Interface
To: wine-patches <wine-patches@winehq.org>

---
 dlls/msxml3/Makefile.in       |    3 +-
 dlls/msxml3/factory.c         |    8 +
 dlls/msxml3/msxml_private.h   |    1 +
 dlls/msxml3/tests/Makefile.in |    3 +-
 dlls/msxml3/tests/xmlparser.c |   60 ++++++
 dlls/msxml3/xmlparser.c       |  422 +++++++++++++++++++++++++++++++++++++++++
 6 files changed, 495 insertions(+), 2 deletions(-)
 create mode 100644 dlls/msxml3/tests/xmlparser.c
 create mode 100644 dlls/msxml3/xmlparser.c

diff --git a/dlls/msxml3/Makefile.in b/dlls/msxml3/Makefile.in
index 889ef64..f544222 100644
--- a/dlls/msxml3/Makefile.in
+++ b/dlls/msxml3/Makefile.in
@@ -34,7 +34,8 @@ C_SRCS = \
 	uuid.c \
 	xdr.c \
 	xmldoc.c \
-	xmlelem.c
+	xmlelem.c \
+	xmlparser.c
 
 LEX_SRCS = xslpattern.l
 
diff --git a/dlls/msxml3/factory.c b/dlls/msxml3/factory.c
index 2d1a42f..0452ef7 100644
--- a/dlls/msxml3/factory.c
+++ b/dlls/msxml3/factory.c
@@ -35,6 +35,7 @@
 #include "ole2.h"
 #include "msxml.h"
 #include "msxml2.h"
+#include "xmlparser.h"
 
 /* undef the #define in msxml2 so that we can access the v.2 version
    independent CLSID as well as the v.3 one. */
@@ -270,6 +271,7 @@ static ClassFactory saxreadcf = { { &ClassFactoryVtbl }, SAXXMLReader_create };
 static ClassFactory httpreqcf = { { &ClassFactoryVtbl }, XMLHTTPRequest_create };
 static ClassFactory xsltemplatecf = { { &ClassFactoryVtbl }, XSLTemplate_create };
 static ClassFactory mxnsmanagercf = { {&ClassFactoryVtbl }, MXNamespaceManager_create };
+static ClassFactory xmlparsercf = { { &ClassFactoryVtbl }, XMLParser_create };
 
 /******************************************************************
  *		DllGetClassObject (MSXML3.@)
@@ -347,6 +349,12 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv )
     {
         cf = &mxnsmanagercf.IClassFactory_iface;
     }
+    else if( IsEqualCLSID( rclsid, &CLSID_XMLParser )  ||
+             IsEqualCLSID( rclsid, &CLSID_XMLParser26 ) ||
+             IsEqualCLSID( rclsid, &CLSID_XMLParser30 )  )
+    {
+        cf = &xmlparsercf.IClassFactory_iface;
+    }
 
     if ( !cf )
         return CLASS_E_CLASSNOTAVAILABLE;
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index e7f82ea..8d6bcc0 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -437,6 +437,7 @@ extern HRESULT XMLHTTPRequest_create(IUnknown*, void **) DECLSPEC_HIDDEN;
 extern HRESULT XSLTemplate_create(IUnknown*, void**) DECLSPEC_HIDDEN;
 extern HRESULT MXWriter_create(MSXML_VERSION, IUnknown*, void**) DECLSPEC_HIDDEN;
 extern HRESULT MXNamespaceManager_create(IUnknown*,void**) DECLSPEC_HIDDEN;
+extern HRESULT XMLParser_create(IUnknown*,void**) DECLSPEC_HIDDEN;
 
 static inline const CLSID* DOMDocument_version(MSXML_VERSION v)
 {
diff --git a/dlls/msxml3/tests/Makefile.in b/dlls/msxml3/tests/Makefile.in
index 71c76e8..1fead89 100644
--- a/dlls/msxml3/tests/Makefile.in
+++ b/dlls/msxml3/tests/Makefile.in
@@ -5,6 +5,7 @@ C_SRCS = \
 	domdoc.c \
 	saxreader.c \
 	schema.c \
-	xmldoc.c
+	xmldoc.c \
+	xmlparser.c 
 
 @MAKE_TEST_RULES@
diff --git a/dlls/msxml3/tests/xmlparser.c b/dlls/msxml3/tests/xmlparser.c
new file mode 100644
index 0000000..d02e4fe
--- /dev/null
+++ b/dlls/msxml3/tests/xmlparser.c
@@ -0,0 +1,60 @@
+/*
+ * XML Parser implementation
+ *
+ * Copyright 2011 Alistair Leslie-Hughes
+ *
+ * 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
+#define CONST_VTABLE
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "windows.h"
+#include "ole2.h"
+#include "initguid.h"
+#include "xmlparser.h"
+
+#include "wine/test.h"
+
+static void create_test(void)
+{
+    HRESULT hr;
+    IXMLParser *parser;
+
+    hr = CoCreateInstance(&CLSID_XMLParser, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLParser, (void**)&parser);
+    if (FAILED(hr))
+    {
+        win_skip("IXMLParser is not available (0x%08x)\n", hr);
+        return;
+    }
+    
+    IXMLParser_Release(parser);
+}
+
+START_TEST(xmlparser)
+{
+    HRESULT hr;
+
+    hr = CoInitialize( NULL );
+    ok( hr == S_OK, "failed to init com\n");
+    if (hr != S_OK)
+        return;
+
+    create_test();
+
+    CoUninitialize();
+}
diff --git a/dlls/msxml3/xmlparser.c b/dlls/msxml3/xmlparser.c
new file mode 100644
index 0000000..13299de
--- /dev/null
+++ b/dlls/msxml3/xmlparser.c
@@ -0,0 +1,422 @@
+/*
+ * XML Parser implementation
+ *
+ * Copyright 2011 Alistair Leslie-Hughes
+ *
+ * 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/HTMLtree.h>
+#endif
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "ole2.h"
+#include "msxml6.h"
+
+#include "msxml_private.h"
+
+#include "initguid.h"
+#include "xmlparser.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msxml);
+
+typedef struct _xmlparser
+{
+    IXMLParser IXMLParser_iface;
+    LONG ref;
+} xmlparser;
+
+static inline xmlparser *impl_from_IXMLParser( IXMLParser *iface )
+{
+    return CONTAINING_RECORD(iface, xmlparser, IXMLParser_iface);
+}
+
+/*** IUnknown methods ***/
+static HRESULT WINAPI xmlparser_QueryInterface(IXMLParser* iface, REFIID riid, void **ppvObject)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
+
+    if ( IsEqualGUID( riid, &IID_IXMLParser ) ||
+         IsEqualGUID( riid, &IID_IXMLNodeSource ) ||
+         IsEqualGUID( riid, &IID_IUnknown ) )
+    {
+        *ppvObject = iface;
+    }    
+    else
+    {
+        TRACE("Unsupported interface %s\n", debugstr_guid(riid));
+        *ppvObject = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IXMLParser_AddRef((IUnknown*)*ppvObject);
+    return S_OK;
+}
+
+static ULONG WINAPI xmlparser_AddRef(IXMLParser* iface)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+    ULONG ref = InterlockedIncrement( &This->ref );
+    TRACE("(%p)->(%d)\n", This, ref);
+    return ref;
+}
+
+static ULONG WINAPI xmlparser_Release(IXMLParser* iface)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+    ULONG ref = InterlockedDecrement( &This->ref );
+
+    TRACE("(%p)->(%d)\n", This, ref);
+    if ( ref == 0 )
+    {
+        heap_free( This );
+    }
+
+    return ref;
+}
+
+/*** IXMLNodeSource methods ***/
+static HRESULT WINAPI xmlparser_SetFactory(IXMLParser *iface, IXMLNodeFactory *pNodeFactory)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %p)\n", This, pNodeFactory);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_GetFactory(IXMLParser *iface, IXMLNodeFactory **ppNodeFactory)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p, %p)\n", This, ppNodeFactory);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_Abort(IXMLParser *iface, BSTR bstrErrorInfo)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p, %s)\n", This, debugstr_w(bstrErrorInfo));
+
+    return E_NOTIMPL;
+}
+
+static ULONG WINAPI xmlparser_GetLineNumber(IXMLParser *iface)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p)\n", This);
+
+    return 0;
+}
+
+static ULONG WINAPI xmlparser_GetLinePosition(IXMLParser *iface)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p)\n", This);
+
+    return 0;
+}
+
+static ULONG WINAPI xmlparser_GetAbsolutePosition(IXMLParser *iface)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p)\n", This);
+
+    return 0;
+}
+
+static HRESULT WINAPI xmlparser_GetLineBuffer(IXMLParser *iface, const WCHAR **ppBuf,
+                ULONG *len, ULONG *startPos)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %p %p %p)\n", This, ppBuf, len, startPos);
+
+    return 0;
+}
+
+static HRESULT WINAPI xmlparser_GetLastError(IXMLParser *iface)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p)\n", This);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_GetErrorInfo(IXMLParser *iface, BSTR *pErrorInfo)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %p)\n", This, pErrorInfo);
+
+    return E_NOTIMPL;
+}
+
+static ULONG WINAPI xmlparser_GetFlags(IXMLParser *iface)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p)\n", This);
+
+    return 0;
+}
+
+static HRESULT WINAPI xmlparser_GetURL(IXMLParser *iface, const WCHAR **ppBuf)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %p)\n", This, ppBuf);
+
+    return E_NOTIMPL;
+}
+
+/*** IXMLParser methods ***/
+static HRESULT WINAPI xmlparser_SetURL(IXMLParser *iface,const WCHAR *pszBaseUrl,
+                const WCHAR *relativeUrl, BOOL async)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %s %s %d)\n", This, debugstr_w(pszBaseUrl), debugstr_w(relativeUrl), async);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_Load(IXMLParser *iface, BOOL bFullyAvailable,
+                IMoniker *pMon, LPBC pBC, DWORD dwMode)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %d %p %p %d)\n", This, bFullyAvailable, pMon, pBC, dwMode);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_SetInput(IXMLParser *iface, IUnknown *pStm)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %p)\n", This, pStm);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_PushData(IXMLParser *iface, const char *pData,
+                ULONG nChars, BOOL fLastBuffer)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %s %d %d)\n", This, debugstr_a(pData), nChars, fLastBuffer);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_LoadDTD(IXMLParser *iface, const WCHAR *baseUrl,
+                const WCHAR *relativeUrl)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %s %s)\n", This, debugstr_w(baseUrl), debugstr_w(relativeUrl));
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_LoadEntity(IXMLParser *iface, const WCHAR *baseUrl,
+                const WCHAR *relativeUrl, BOOL fpe)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %s %s %d)\n", This, debugstr_w(baseUrl), debugstr_w(relativeUrl), fpe);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_ParseEntity(IXMLParser *iface, const WCHAR *text,
+                ULONG len, BOOL fpe)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %s %d %d)\n", This, debugstr_w(text), len, fpe);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_ExpandEntity(IXMLParser *iface, const WCHAR *text,
+                ULONG len)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %s %d)\n", This, debugstr_w(text), len);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_SetRoot(IXMLParser *iface, PVOID pRoot)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %p)\n", This, pRoot);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_GetRoot( IXMLParser *iface, PVOID *ppRoot)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %p)\n", This, ppRoot);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_Run(IXMLParser *iface, LONG chars)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %d)\n", This, chars);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_GetParserState(IXMLParser *iface)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p)\n", This);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_Suspend(IXMLParser *iface)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p)\n", This);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_Reset(IXMLParser *iface)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p)\n", This);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_SetFlags(IXMLParser *iface, ULONG flags)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %d)\n", This, flags);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_SetSecureBaseURL(IXMLParser *iface, const WCHAR *baseUrl)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %s)\n", This, debugstr_w(baseUrl));
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI xmlparser_GetSecureBaseURL( IXMLParser *iface, const WCHAR **ppBuf)
+{
+    xmlparser *This = impl_from_IXMLParser( iface );
+
+    FIXME("(%p %p)\n", This, ppBuf);
+
+    return E_NOTIMPL;
+}
+
+
+static const struct IXMLParserVtbl xmlparser_vtbl =
+{
+    xmlparser_QueryInterface,
+    xmlparser_AddRef,
+    xmlparser_Release,
+    xmlparser_SetFactory,
+    xmlparser_GetFactory,
+    xmlparser_Abort,
+    xmlparser_GetLineNumber,
+    xmlparser_GetLinePosition,
+    xmlparser_GetAbsolutePosition,
+    xmlparser_GetLineBuffer,
+    xmlparser_GetLastError,
+    xmlparser_GetErrorInfo,
+    xmlparser_GetFlags,
+    xmlparser_GetURL,
+    xmlparser_SetURL,
+    xmlparser_Load,
+    xmlparser_SetInput,
+    xmlparser_PushData,
+    xmlparser_LoadDTD,
+    xmlparser_LoadEntity,
+    xmlparser_ParseEntity,
+    xmlparser_ExpandEntity,
+    xmlparser_SetRoot,
+    xmlparser_GetRoot,
+    xmlparser_Run,
+    xmlparser_GetParserState,
+    xmlparser_Suspend,
+    xmlparser_Reset,
+    xmlparser_SetFlags,
+    xmlparser_SetSecureBaseURL,
+    xmlparser_GetSecureBaseURL
+};
+
+HRESULT XMLParser_create(IUnknown* pUnkOuter, void**ppObj)
+{
+    xmlparser *This;
+
+    TRACE("(%p,%p)\n", pUnkOuter, ppObj);
+
+    if (pUnkOuter)
+        FIXME("support aggregation, outer\n");
+
+    This = heap_alloc( sizeof *This );
+    if(!This)
+        return E_OUTOFMEMORY;
+
+    This->IXMLParser_iface.lpVtbl = &xmlparser_vtbl;
+    This->ref = 1;
+
+    *ppObj = &This->IXMLParser_iface;
+
+    TRACE("returning iface %p\n", *ppObj);
+
+    return S_OK;
+}
+
-- 
1.7.4.1

