msxml3: Use OnDataAvailable for reading stream.

This commit is contained in:
Piotr Caban 2008-07-08 20:55:10 +02:00 committed by Alexandre Julliard
parent a08962d41c
commit d8b22b9fb5
1 changed files with 73 additions and 59 deletions

View File

@ -86,6 +86,7 @@ struct bsc_t {
domdoc *doc;
IBinding *binding;
IStream *memstream;
};
static inline bsc_t *impl_from_IBindStatusCallback( IBindStatusCallback *iface )
@ -93,6 +94,20 @@ static inline bsc_t *impl_from_IBindStatusCallback( IBindStatusCallback *iface )
return (bsc_t *)((char*)iface - FIELD_OFFSET(bsc_t, lpVtbl));
}
static xmlDocPtr doparse( char *ptr, int len )
{
#ifdef HAVE_XMLREADMEMORY
/*
* use xmlReadMemory if possible so we can suppress
* writing errors to stderr
*/
return xmlReadMemory( ptr, len, NULL, NULL,
XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
#else
return xmlParseMemory( ptr, len );
#endif
}
static HRESULT WINAPI bsc_QueryInterface(
IBindStatusCallback *iface,
REFIID riid,
@ -134,6 +149,8 @@ static ULONG WINAPI bsc_Release(
IBinding_Release(This->binding);
if(This->doc && This->doc->bsc == This)
This->doc->bsc = NULL;
if(This->memstream)
IStream_Release(This->memstream);
HeapFree(GetProcessHeap(), 0, This);
}
@ -146,12 +163,17 @@ static HRESULT WINAPI bsc_OnStartBinding(
IBinding* pib)
{
bsc_t *This = impl_from_IBindStatusCallback(iface);
HRESULT hr;
TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
This->binding = pib;
IBindStatusCallback_AddRef(pib);
hr = CreateStreamOnHGlobal(NULL, TRUE, &This->memstream);
if(FAILED(hr))
return hr;
return S_OK;
}
@ -185,6 +207,7 @@ static HRESULT WINAPI bsc_OnStopBinding(
LPCWSTR szError)
{
bsc_t *This = impl_from_IBindStatusCallback(iface);
HRESULT hr;
TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
@ -193,6 +216,25 @@ static HRESULT WINAPI bsc_OnStopBinding(
This->binding = NULL;
}
if(This->doc && SUCCEEDED(hresult)) {
HGLOBAL hglobal;
hr = GetHGlobalFromStream(This->memstream, &hglobal);
if(SUCCEEDED(hr))
{
DWORD len = GlobalSize(hglobal);
char *ptr = GlobalLock(hglobal);
xmlDocPtr xmldoc;
if(len != 0) {
xmldoc = doparse( ptr, len );
if(xmldoc) {
xmldoc->_private = 0;
attach_xmlnode(This->doc->node, (xmlNodePtr) xmldoc);
}
}
GlobalUnlock(hglobal);
}
}
return S_OK;
}
@ -213,6 +255,22 @@ static HRESULT WINAPI bsc_OnDataAvailable(
FORMATETC* pformatetc,
STGMEDIUM* pstgmed)
{
bsc_t *This = impl_from_IBindStatusCallback(iface);
BYTE buf[4096];
DWORD read, written;
HRESULT hr;
TRACE("(%p)->(%x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
do
{
hr = IStream_Read(pstgmed->pstm, buf, sizeof(buf), &read);
if(FAILED(hr))
break;
hr = IStream_Write(This->memstream, buf, read, &written);
} while(SUCCEEDED(hr) && written != 0 && read != 0);
return S_OK;
}
@ -1335,29 +1393,11 @@ static HRESULT WINAPI domdoc_nodeFromID(
return E_NOTIMPL;
}
static xmlDocPtr doparse( char *ptr, int len )
static HRESULT doread( domdoc *This, LPWSTR filename )
{
#ifdef HAVE_XMLREADMEMORY
/*
* use xmlReadMemory if possible so we can suppress
* writing errors to stderr
*/
return xmlReadMemory( ptr, len, NULL, NULL,
XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
#else
return xmlParseMemory( ptr, len );
#endif
}
static xmlDocPtr doread( domdoc *This, LPWSTR filename )
{
xmlDocPtr xmldoc = NULL;
HRESULT hr;
IBindCtx *pbc;
IStream *stream, *memstream;
WCHAR url[INTERNET_MAX_URL_LENGTH];
BYTE buf[4096];
DWORD read, written;
TRACE("%s\n", debugstr_w( filename ));
@ -1369,13 +1409,13 @@ static xmlDocPtr doread( domdoc *This, LPWSTR filename )
if(!PathSearchAndQualifyW(filename, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
{
WARN("can't find path\n");
return NULL;
return E_FAIL;
}
if(FAILED(UrlCreateFromPathW(fullpath, url, &needed, 0)))
{
ERR("can't create url from path\n");
return NULL;
return E_FAIL;
}
filename = url;
}
@ -1399,44 +1439,17 @@ static xmlDocPtr doread( domdoc *This, LPWSTR filename )
hr = CreateURLMoniker(NULL, filename, &moniker);
if(SUCCEEDED(hr))
{
IStream *stream;
hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
IMoniker_Release(moniker);
if(stream)
IStream_Release(stream);
}
}
IBindCtx_Release(pbc);
}
if(FAILED(hr))
return NULL;
hr = CreateStreamOnHGlobal(NULL, TRUE, &memstream);
if(FAILED(hr))
{
IStream_Release(stream);
return NULL;
}
do
{
IStream_Read(stream, buf, sizeof(buf), &read);
hr = IStream_Write(memstream, buf, read, &written);
} while(SUCCEEDED(hr) && written != 0 && read != 0);
if(SUCCEEDED(hr))
{
HGLOBAL hglobal;
hr = GetHGlobalFromStream(memstream, &hglobal);
if(SUCCEEDED(hr))
{
DWORD len = GlobalSize(hglobal);
char *ptr = GlobalLock(hglobal);
if(len != 0)
xmldoc = doparse( ptr, len );
GlobalUnlock(hglobal);
}
}
IStream_Release(memstream);
IStream_Release(stream);
return xmldoc;
return hr;
}
static HRESULT WINAPI domdoc_load(
@ -1446,10 +1459,10 @@ static HRESULT WINAPI domdoc_load(
{
domdoc *This = impl_from_IXMLDOMDocument2( iface );
LPWSTR filename = NULL;
xmlDocPtr xmldoc = NULL;
HRESULT hr = S_FALSE;
IXMLDOMDocument2 *pNewDoc = NULL;
IStream *pStream = NULL;
xmlDocPtr xmldoc;
TRACE("type %d\n", V_VT(&xmlSource) );
@ -1519,9 +1532,9 @@ static HRESULT WINAPI domdoc_load(
if ( filename )
{
xmldoc = doread( This, filename );
hr = doread( This, filename );
if ( !xmldoc )
if ( FAILED(hr) )
This->error = E_FAIL;
else
{
@ -1530,11 +1543,12 @@ static HRESULT WINAPI domdoc_load(
}
}
if(!xmldoc)
if(!filename || FAILED(hr)) {
xmldoc = xmlNewDoc(NULL);
xmldoc->_private = 0;
attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
xmldoc->_private = 0;
attach_xmlnode(This->node, (xmlNodePtr) xmldoc);
hr = S_FALSE;
}
TRACE("ret (%d)\n", hr);