Piotr Caban : msxml3: Use OnDataAvailable for reading stream.
Alexandre Julliard
julliard at winehq.org
Wed Jul 9 06:10:25 CDT 2008
Module: wine
Branch: master
Commit: d8b22b9fb58406ec4eda6cb9eed8cdfc6f153cae
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d8b22b9fb58406ec4eda6cb9eed8cdfc6f153cae
Author: Piotr Caban <piotr.caban at gmail.com>
Date: Tue Jul 8 20:55:10 2008 +0200
msxml3: Use OnDataAvailable for reading stream.
---
dlls/msxml3/domdoc.c | 132 +++++++++++++++++++++++++++----------------------
1 files changed, 73 insertions(+), 59 deletions(-)
diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index 9327330..fca096c 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -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 )
-{
-#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 )
+static HRESULT 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);
More information about the wine-cvs
mailing list