msxml3: Implement IPersistStream.
This commit is contained in:
parent
00ef4e5829
commit
7ec06c8442
|
@ -168,6 +168,7 @@ static bsc domdoc_bsc = { &bsc_vtbl };
|
||||||
typedef struct _domdoc
|
typedef struct _domdoc
|
||||||
{
|
{
|
||||||
const struct IXMLDOMDocument2Vtbl *lpVtbl;
|
const struct IXMLDOMDocument2Vtbl *lpVtbl;
|
||||||
|
const struct IPersistStreamVtbl *lpvtblIPersistStream;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
VARIANT_BOOL async;
|
VARIANT_BOOL async;
|
||||||
VARIANT_BOOL validating;
|
VARIANT_BOOL validating;
|
||||||
|
@ -178,6 +179,9 @@ typedef struct _domdoc
|
||||||
IXMLDOMNode *node;
|
IXMLDOMNode *node;
|
||||||
IXMLDOMSchemaCollection *schema;
|
IXMLDOMSchemaCollection *schema;
|
||||||
HRESULT error;
|
HRESULT error;
|
||||||
|
|
||||||
|
/* IPersistStream */
|
||||||
|
IStream *stream;
|
||||||
} domdoc;
|
} domdoc;
|
||||||
|
|
||||||
LONG xmldoc_add_ref(xmlDocPtr doc)
|
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 );
|
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 )
|
static HRESULT WINAPI domdoc_QueryInterface( IXMLDOMDocument2 *iface, REFIID riid, void** ppvObject )
|
||||||
{
|
{
|
||||||
domdoc *This = impl_from_IXMLDOMDocument2( iface );
|
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);
|
return IUnknown_QueryInterface(This->node_unk, riid, ppvObject);
|
||||||
}
|
}
|
||||||
|
else if (IsEqualGUID(&IID_IPersistStream, riid))
|
||||||
|
{
|
||||||
|
*ppvObject = (IPersistStream*)&(This->lpvtblIPersistStream);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FIXME("interface %s not implemented\n", debugstr_guid(riid));
|
FIXME("interface %s not implemented\n", debugstr_guid(riid));
|
||||||
|
@ -261,6 +394,7 @@ static ULONG WINAPI domdoc_Release(
|
||||||
{
|
{
|
||||||
IUnknown_Release( This->node_unk );
|
IUnknown_Release( This->node_unk );
|
||||||
if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
|
if(This->schema) IXMLDOMSchemaCollection_Release( This->schema );
|
||||||
|
if (This->stream) IStream_Release(This->stream);
|
||||||
HeapFree( GetProcessHeap(), 0, This );
|
HeapFree( GetProcessHeap(), 0, This );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1023,6 +1157,8 @@ static HRESULT WINAPI domdoc_load(
|
||||||
LPWSTR filename = NULL;
|
LPWSTR filename = NULL;
|
||||||
xmlDocPtr xmldoc = NULL;
|
xmlDocPtr xmldoc = NULL;
|
||||||
HRESULT hr = S_FALSE;
|
HRESULT hr = S_FALSE;
|
||||||
|
IXMLDOMDocument2 *pNewDoc = NULL;
|
||||||
|
IStream *pStream = NULL;
|
||||||
|
|
||||||
TRACE("type %d\n", V_VT(&xmlSource) );
|
TRACE("type %d\n", V_VT(&xmlSource) );
|
||||||
|
|
||||||
|
@ -1036,7 +1172,59 @@ static HRESULT WINAPI domdoc_load(
|
||||||
{
|
{
|
||||||
case VT_BSTR:
|
case VT_BSTR:
|
||||||
filename = V_BSTR(&xmlSource);
|
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 )
|
if ( filename )
|
||||||
{
|
{
|
||||||
|
@ -1057,6 +1245,8 @@ static HRESULT WINAPI domdoc_load(
|
||||||
xmldoc->_private = 0;
|
xmldoc->_private = 0;
|
||||||
attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
|
attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
|
||||||
|
|
||||||
|
TRACE("ret (%d)\n", hr);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1562,6 +1752,7 @@ HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
doc->lpVtbl = &domdoc_vtbl;
|
doc->lpVtbl = &domdoc_vtbl;
|
||||||
|
doc->lpvtblIPersistStream = &xmldoc_IPersistStream_VTable;
|
||||||
doc->ref = 1;
|
doc->ref = 1;
|
||||||
doc->async = 0;
|
doc->async = 0;
|
||||||
doc->validating = 0;
|
doc->validating = 0;
|
||||||
|
@ -1570,6 +1761,7 @@ HRESULT DOMDocument_create(IUnknown *pUnkOuter, LPVOID *ppObj)
|
||||||
doc->bUseXPath = FALSE;
|
doc->bUseXPath = FALSE;
|
||||||
doc->error = S_OK;
|
doc->error = S_OK;
|
||||||
doc->schema = NULL;
|
doc->schema = NULL;
|
||||||
|
doc->stream = NULL;
|
||||||
|
|
||||||
xmldoc = xmlNewDoc(NULL);
|
xmldoc = xmlNewDoc(NULL);
|
||||||
if(!xmldoc)
|
if(!xmldoc)
|
||||||
|
|
|
@ -61,6 +61,8 @@ extern LONG xmldoc_release( xmlDocPtr doc );
|
||||||
extern HRESULT XMLElement_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj );
|
extern HRESULT XMLElement_create( IUnknown *pUnkOuter, xmlNodePtr node, LPVOID *ppObj );
|
||||||
extern HRESULT XMLElementCollection_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
|
#endif
|
||||||
|
|
||||||
extern IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR reason, BSTR srcText,
|
extern IXMLDOMParseError *create_parseError( LONG code, BSTR url, BSTR reason, BSTR srcText,
|
||||||
|
|
|
@ -44,7 +44,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
|
||||||
/* FIXME: IXMLDocument needs to implement
|
/* FIXME: IXMLDocument needs to implement
|
||||||
* - IXMLError
|
* - IXMLError
|
||||||
* - IPersistMoniker
|
* - IPersistMoniker
|
||||||
* - IPersistStream
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct _xmldoc
|
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);
|
TRACE("%p %s %p\n", This, debugstr_guid(riid), ppvObject);
|
||||||
|
|
||||||
if (IsEqualGUID(riid, &IID_IUnknown) ||
|
if (IsEqualGUID(riid, &IID_IUnknown) ||
|
||||||
IsEqualGUID(riid, &IID_IXMLDocument))
|
IsEqualGUID(riid, &IID_IXMLDocument) ||
|
||||||
|
IsEqualGUID(riid, &IID_IXMLDOMDocument))
|
||||||
{
|
{
|
||||||
*ppvObject = iface;
|
*ppvObject = iface;
|
||||||
}
|
}
|
||||||
else if (IsEqualGUID(&IID_IPersistStreamInit, riid))
|
else if (IsEqualGUID(&IID_IPersistStreamInit, riid) ||
|
||||||
|
IsEqualGUID(&IID_IPersistStream, riid))
|
||||||
{
|
{
|
||||||
*ppvObject = (IPersistStreamInit *)&(This->lpvtblIPersistStreamInit);
|
*ppvObject = (IPersistStreamInit *)&(This->lpvtblIPersistStreamInit);
|
||||||
}
|
}
|
||||||
|
@ -522,7 +523,7 @@ static HRESULT WINAPI xmldoc_IPersistStreamInit_IsDirty(
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static xmlDocPtr parse_xml(char *ptr, int len)
|
xmlDocPtr parse_xml(char *ptr, int len)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_XMLREADMEMORY
|
#ifdef HAVE_XMLREADMEMORY
|
||||||
return xmlReadMemory(ptr, len, NULL, NULL,
|
return xmlReadMemory(ptr, len, NULL, NULL,
|
||||||
|
|
Loading…
Reference in New Issue