msxml3: Add support for IStream destination in save().

This commit is contained in:
Nikolay Sivov 2010-10-20 02:29:43 +04:00 committed by Alexandre Julliard
parent 4a1379d804
commit 657f64dd06
1 changed files with 58 additions and 25 deletions

View File

@ -2056,8 +2056,7 @@ static HRESULT WINAPI domdoc_loadXML(
return hr; return hr;
} }
static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer, static int XMLCALL domdoc_save_writecallback(void *ctx, const char *buffer, int len)
int len)
{ {
DWORD written = -1; DWORD written = -1;
@ -2075,13 +2074,33 @@ static int XMLCALL domdoc_save_closecallback(void *ctx)
return CloseHandle(ctx) ? 0 : -1; return CloseHandle(ctx) ? 0 : -1;
} }
static int XMLCALL domdoc_stream_save_writecallback(void *ctx, const char *buffer, int len)
{
ULONG written = 0;
HRESULT hr;
hr = IStream_Write((IStream*)ctx, buffer, len, &written);
if (hr != S_OK)
{
WARN("stream write error: 0x%08x\n", hr);
return -1;
}
else
return written;
}
static int XMLCALL domdoc_stream_save_closecallback(void *ctx)
{
IStream_Release((IStream*)ctx);
return 0;
}
static HRESULT WINAPI domdoc_save( static HRESULT WINAPI domdoc_save(
IXMLDOMDocument3 *iface, IXMLDOMDocument3 *iface,
VARIANT destination ) VARIANT destination )
{ {
domdoc *This = impl_from_IXMLDOMDocument3( iface ); domdoc *This = impl_from_IXMLDOMDocument3( iface );
HANDLE handle; xmlSaveCtxtPtr ctx = NULL;
xmlSaveCtxtPtr ctx;
xmlNodePtr xmldecl; xmlNodePtr xmldecl;
HRESULT ret = S_OK; HRESULT ret = S_OK;
@ -2097,9 +2116,10 @@ static HRESULT WINAPI domdoc_save(
if(V_VT(&destination) == VT_UNKNOWN) if(V_VT(&destination) == VT_UNKNOWN)
{ {
IUnknown *pUnk = V_UNKNOWN(&destination); IUnknown *pUnk = V_UNKNOWN(&destination);
IXMLDOMDocument2 *pDocument; IXMLDOMDocument2 *document;
IStream *stream;
ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument3, (void**)&pDocument); ret = IUnknown_QueryInterface(pUnk, &IID_IXMLDOMDocument3, (void**)&document);
if(ret == S_OK) if(ret == S_OK)
{ {
VARIANT_BOOL success; VARIANT_BOOL success;
@ -2108,40 +2128,53 @@ static HRESULT WINAPI domdoc_save(
ret = IXMLDOMDocument3_get_xml(iface, &xml); ret = IXMLDOMDocument3_get_xml(iface, &xml);
if(ret == S_OK) if(ret == S_OK)
{ {
ret = IXMLDOMDocument3_loadXML(pDocument, xml, &success); ret = IXMLDOMDocument3_loadXML(document, xml, &success);
SysFreeString(xml); SysFreeString(xml);
} }
IXMLDOMDocument3_Release(pDocument); IXMLDOMDocument3_Release(document);
return ret;
} }
TRACE("ret %d\n", ret); ret = IUnknown_QueryInterface(pUnk, &IID_IStream, (void**)&stream);
if(ret == S_OK)
{
ctx = xmlSaveToIO(domdoc_stream_save_writecallback,
domdoc_stream_save_closecallback, stream, NULL, XML_SAVE_NO_DECL);
return ret; if(!ctx)
{
IStream_Release(stream);
return E_FAIL;
}
}
} }
else
handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( handle == INVALID_HANDLE_VALUE )
{ {
WARN("failed to create file\n"); /* save with file path */
return S_FALSE; HANDLE handle = CreateFileW( V_BSTR(&destination), GENERIC_WRITE, 0,
} NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( handle == INVALID_HANDLE_VALUE )
{
WARN("failed to create file\n");
return E_FAIL;
}
/* disable top XML declaration */ /* disable top XML declaration */
ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback, ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback,
handle, NULL, XML_SAVE_NO_DECL); handle, NULL, XML_SAVE_NO_DECL);
if (!ctx) if (!ctx)
{ {
CloseHandle(handle); CloseHandle(handle);
return S_FALSE; return E_FAIL;
}
} }
xmldecl = xmldoc_unlink_xmldecl(get_doc(This)); xmldecl = xmldoc_unlink_xmldecl(get_doc(This));
if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE; if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE;
xmldoc_link_xmldecl(get_doc(This), xmldecl); xmldoc_link_xmldecl(get_doc(This), xmldecl);
/* will close file through close callback */ /* will release resources through close callback */
xmlSaveClose(ctx); xmlSaveClose(ctx);
return ret; return ret;