[PATCH] Implement IPersistStream

denver stalk smokeydfatty at gmail.com
Fri Feb 26 04:35:49 CST 2010


---

 dlls/msxml3/domdoc.c        |  193
++++++++++++++++++++++++++++++++++++++++++-

 dlls/msxml3/msxml_private.h |    2 +

 dlls/msxml3/xmldoc.c        |    9 +-

 3 files changed, 199 insertions(+), 5 deletions(-)

 

diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c

index b4b8962..7edeb9b 100644

--- a/dlls/msxml3/domdoc.c

+++ b/dlls/msxml3/domdoc.c

@@ -168,6 +168,7 @@ static bsc domdoc_bsc = { &bsc_vtbl };

 typedef struct _domdoc

 {

     const struct IXMLDOMDocument2Vtbl *lpVtbl;

+    const struct IPersistStreamVtbl   *lpvtblIPersistStream;

     LONG ref;

     VARIANT_BOOL async;

     VARIANT_BOOL validating;

@@ -178,6 +179,9 @@ typedef struct _domdoc

     IXMLDOMNode *node;

     IXMLDOMSchemaCollection *schema;

     HRESULT error;

+

+     /* IPersistStream */

+     IStream *stream;

 } domdoc;

 

 LONG xmldoc_add_ref(xmlDocPtr doc)

@@ -210,6 +214,131 @@ static inline xmlDocPtr get_doc( domdoc *This )

     return (xmlDocPtr) xmlNodePtr_from_domnode( This->node,
XML_DOCUMENT_NODE );

 }

 

+static inline domdoc *impl_from_IPersistStream(IPersistStream *iface)

+{

+    return (domdoc *)((char*)iface - FIELD_OFFSET(domdoc,
lpvtblIPersistStream));

+}

+

+/************************************************************************

+ * xmldoc implementation of IPersistStream.

+ */

+static HRESULT WINAPI xmldoc_IPersistStream_QueryInterface(

+    IPersistStream *iface, REFIID riid, LPVOID *ppvObj)

+{

+    domdoc *this = impl_from_IPersistStream(iface);

+    return IXMLDocument_QueryInterface((IXMLDocument *)this, riid, ppvObj);

+}

+

+static ULONG WINAPI xmldoc_IPersistStream_AddRef(

+    IPersistStream *iface)

+{

+    domdoc *this = impl_from_IPersistStream(iface);

+    return IXMLDocument_AddRef((IXMLDocument *)this);

+}

+

+static ULONG WINAPI xmldoc_IPersistStream_Release(

+    IPersistStream *iface)

+{

+    domdoc *this = impl_from_IPersistStream(iface);

+    return IXMLDocument_Release((IXMLDocument *)this);

+}

+

+static HRESULT WINAPI xmldoc_IPersistStream_GetClassID(

+    IPersistStream *iface, CLSID *classid)

+{

+    FIXME("(%p,%p): stub!\n", iface, classid);

+    return E_NOTIMPL;

+}

+

+static HRESULT WINAPI xmldoc_IPersistStream_IsDirty(

+    IPersistStream *iface)

+{

+    domdoc *This = impl_from_IPersistStream(iface);

+

+    FIXME("(%p->%p): stub!\n", iface, This);

+

+    return S_FALSE;

+}

+

+static HRESULT WINAPI xmldoc_IPersistStream_Load(

+    IPersistStream *iface, LPSTREAM pStm)

+{

+    domdoc *This = impl_from_IPersistStream(iface);

+    HRESULT hr;

+    HGLOBAL hglobal;

+    DWORD read, written, len;

+    BYTE buf[4096];

+    char *ptr;

+    xmlDocPtr xmldoc = NULL;

+

+    TRACE("(%p, %p)\n", iface, pStm);

+

+    if (!pStm)

+        return E_INVALIDARG;

+

+    hr = CreateStreamOnHGlobal(NULL, TRUE, &This->stream);

+    if (FAILED(hr))

+        return hr;

+

+    do

+    {

+        IStream_Read(pStm, buf, sizeof(buf), &read);

+        hr = IStream_Write(This->stream, buf, read, &written);

+    } while(SUCCEEDED(hr) && written != 0 && read != 0);

+

+    if (FAILED(hr))

+    {

+        ERR("Failed to copy stream\n");

+        return hr;

+    }

+

+    hr = GetHGlobalFromStream(This->stream, &hglobal);

+    if (FAILED(hr))

+        return hr;

+

+    len = GlobalSize(hglobal);

+    ptr = GlobalLock(hglobal);

+    if (len != 0)

+        xmldoc = parse_xml(ptr, len);

+    GlobalUnlock(hglobal);

+

+    if (!xmldoc)

+    {

+        ERR("Failed to parse xml\n");

+        return E_FAIL;

+    }

+

+    attach_xmlnode( This->node, (xmlNodePtr)xmldoc );

+

+    return S_OK;

+}

+

+static HRESULT WINAPI xmldoc_IPersistStream_Save(

+    IPersistStream *iface, LPSTREAM pStm, BOOL fClearDirty)

+{

+    FIXME("(%p, %p, %d): stub!\n", iface, pStm, fClearDirty);

+    return E_NOTIMPL;

+}

+

+static HRESULT WINAPI xmldoc_IPersistStream_GetSizeMax(

+    IPersistStream *iface, ULARGE_INTEGER *pcbSize)

+{

+    TRACE("(%p, %p): stub!\n", iface, pcbSize);

+    return E_NOTIMPL;

+}

+

+static const IPersistStreamVtbl xmldoc_IPersistStream_VTable =

+{

+    xmldoc_IPersistStream_QueryInterface,

+    xmldoc_IPersistStream_AddRef,

+    xmldoc_IPersistStream_Release,

+    xmldoc_IPersistStream_GetClassID,

+    xmldoc_IPersistStream_IsDirty,

+    xmldoc_IPersistStream_Load,

+    xmldoc_IPersistStream_Save,

+    xmldoc_IPersistStream_GetSizeMax,

+};

+

 static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface,
REFIID riid, void** ppvObject )

 {

     domdoc *This = impl_from_IXMLDOMDocument2( iface );

@@ -227,6 +356,10 @@ static HRESULT WINAPI domdoc_QueryInterface(
IXMLDOMDocument2 *iface, REFIID rii

     {

         return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);

     }

+    else if (IsEqualGUID(&IID_IPersistStream, riid))

+    {

+        *ppvObject = (IPersistStream*)&(This->lpvtblIPersistStream);

+    }

     else

     {

         FIXME("interface %s not implemented\n", debugstr_guid(riid));

@@ -1023,6 +1156,8 @@ static HRESULT WINAPI domdoc_load(

     LPWSTR filename = NULL;

     xmlDocPtr xmldoc = NULL;

     HRESULT hr = S_FALSE;

+    IXMLDOMDocument2 *pNewDoc = NULL;

+    IStream *pStream = NULL;

 

     TRACE("type %d\n", V_VT(&xmlSource) );

 

@@ -1036,7 +1171,59 @@ static HRESULT WINAPI domdoc_load(

     {

     case VT_BSTR:

         filename = V_BSTR(&xmlSource);

-    }

+        break;

+    case VT_UNKNOWN:

+        hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource),
&IID_IXMLDOMDocument2, (void**)&pNewDoc);

+        if(hr == S_OK)

+        {

+            if(pNewDoc)

+            {

+                domdoc *newDoc = impl_from_IXMLDOMDocument2( pNewDoc );

+                xmldoc = xmlCopyDoc(get_doc(newDoc), 1);

+                attach_xmlnode(This->node, (xmlNodePtr) xmldoc);

+

+                *isSuccessful = VARIANT_TRUE;

+

+                return S_OK;

+            }

+        }

+        hr = IUnknown_QueryInterface(V_UNKNOWN(&xmlSource), &IID_IStream,
(void**)&pStream);

+        if(hr == S_OK)

+        {

+            IPersistStream *pDocStream;

+            hr = IUnknown_QueryInterface(iface, &IID_IPersistStream,
(void**)&pDocStream);

+            if(hr == S_OK)

+            {

+                hr = xmldoc_IPersistStream_Load(pDocStream, pStream);

+                IStream_Release(pStream);

+                if(hr == S_OK)

+                {

+                    *isSuccessful = VARIANT_TRUE;

+

+                    TRACE("Using ID_IStream to load Document\n");

+                    return S_OK;

+                }

+                else

+                {

+                    ERR("xmldoc_IPersistStream_Load failed (%d)\n", hr);

+                }

+            }

+            else

+            {

+                ERR("QueryInterface IID_IPersistStream failed (%d)\n", hr);

+            }

+        }

+        else

+        {

+            /* ISequentialStream */

+            FIXME("Unknown type not supported (%d) (%p)(%p)\n", hr,
pNewDoc, V_UNKNOWN(&xmlSource)->lpVtbl);

+        }

+        break;

+     default:

+            FIXME("VT type not supported (%d)\n", V_VT(&xmlSource));

+     }

+ 

+    TRACE("filename (%s)\n", debugstr_w(filename));

 

     if ( filename )

     {

@@ -1057,6 +1244,8 @@ static HRESULT WINAPI domdoc_load(

     xmldoc->_private = 0;

     attach_xmlnode(This->node, (xmlNodePtr) xmldoc);

 

+    TRACE("ret (%d)\n", hr);

+

     return hr;

 }

 

@@ -1562,6 +1751,7 @@ HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID
*ppObj)

         return E_OUTOFMEMORY;

 

     doc->lpVtbl = &domdoc_vtbl;

+    doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;

     doc->ref = 1;

     doc->async = 0;

     doc->validating = 0;

@@ -1570,6 +1760,7 @@ HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID
*ppObj)

     doc->bUseXPath = FALSE;

     doc->error = S_OK;

     doc->schema = NULL;

+    doc->stream = NULL;

 

     xmldoc = xmlNewDoc(NULL);

     if(!xmldoc)

diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h

index 2d574ff..4914a58 100644

--- a/dlls/msxml3/msxml_private.h

+++ b/dlls/msxml3/msxml_private.h

@@ -61,6 +61,8 @@ extern LONG xmldoc_release( xmlDocPtr doc );

 extern HRESULT XMLElement_create( IUnknown *pUnkOuter, xmlNodePtr node,
LPVOID *ppObj );

 extern HRESULT XMLElementCollection_create( IUnknown *pUnkOuter, xmlNodePtr
node, LPVOID *ppObj );

 

+extern xmlDocPtr parse_xml(char *ptr, int len);

+

 #endif

 

 extern IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR
reason, BSTR srcText,

diff --git a/dlls/msxml3/xmldoc.c b/dlls/msxml3/xmldoc.c

index 6d44c78..a4c0850 100644

--- a/dlls/msxml3/xmldoc.c

+++ b/dlls/msxml3/xmldoc.c

@@ -44,7 +44,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);

 /* FIXME: IXMLDocument needs to implement

  *   - IXMLError

  *   - IPersistMoniker

- *   - IPersistStream

  */

 

 typedef struct _xmldoc

@@ -79,11 +78,13 @@ static HRESULT WINAPI xmldoc_QueryInterface(IXMLDocument
*iface, REFIID riid, vo

     TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);

 

     if (IsEqualGUID(riid, &IID_IUnknown) ||

-        IsEqualGUID(riid, &IID_IXMLDocument))

+        IsEqualGUID(riid, &IID_IXMLDocument) ||

+        IsEqualGUID(riid, &IID_IXMLDOMDocument))

     {

         *ppvObject = iface;

     }

-    else if (IsEqualGUID(&IID_IPersistStreamInit, riid))

+    else if (IsEqualGUID(&IID_IPersistStreamInit, riid) ||

+             IsEqualGUID(&IID_IPersistStream, riid))

     {

         *ppvObject = (IPersistStreamInit
*)&(This->lpvtblIPersistStreamInit);

     }

@@ -522,7 +523,7 @@ static HRESULT WINAPI xmldoc_IPersistStreamInit_IsDirty(

     return E_NOTIMPL;

 }

 

-static xmlDocPtr parse_xml(char *ptr, int len)

+xmlDocPtr parse_xml(char *ptr, int len)

 {

 #ifdef HAVE_XMLREADMEMORY

     return xmlReadMemory(ptr, len, NULL, NULL,

-- 

1.5.3.3

 

 

--------------070707030108030101010000--

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20100226/5253a901/attachment-0001.htm>


More information about the wine-patches mailing list