[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