From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/arraybuf.c | 14 ++++++++++++++ dlls/jscript/jscript.c | 7 +++++++ dlls/jscript/jscript.h | 1 + dlls/jscript/jsdisp.idl | 1 + dlls/mshtml/tests/xhr.js | 14 ++++++++++++++ dlls/mshtml/xmlhttprequest.c | 31 +++++++++++++++++++++++++++++-- 6 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/arraybuf.c b/dlls/jscript/arraybuf.c index 7135034c482..c99b96e5cad 100644 --- a/dlls/jscript/arraybuf.c +++ b/dlls/jscript/arraybuf.c @@ -177,6 +177,20 @@ static HRESULT create_arraybuf(script_ctx_t *ctx, DWORD size, ArrayBufferInstanc return S_OK; }
+HRESULT create_arraybuffer(script_ctx_t *ctx, DWORD size, IWineJSDispatch **ret, void **data) +{ + ArrayBufferInstance *buf; + HRESULT hres; + + hres = create_arraybuf(ctx, size, &buf); + if(FAILED(hres)) + return hres; + + *ret = &buf->dispex.IWineJSDispatch_iface; + *data = buf->buf; + return S_OK; +} + static HRESULT ArrayBufferConstr_isView(script_ctx_t *ctx, jsval_t vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index b65b95b1e0f..30727a5ab2b 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -1477,6 +1477,12 @@ static HRESULT WINAPI WineJScript_CreateObject(IWineJScript *iface, IWineJSDispa return hres; }
+static HRESULT WINAPI WineJScript_CreateArrayBuffer(IWineJScript *iface, DWORD size, IWineJSDispatch **arraybuf, void **data) +{ + JScript *This = impl_from_IWineJScript(iface); + return create_arraybuffer(This->ctx, size, arraybuf, data); +} + static HRESULT WINAPI WineJScript_FillGlobals(IWineJScript *iface, IWineJSDispatchHost *script_global) { JScript *This = impl_from_IWineJScript(iface); @@ -1490,6 +1496,7 @@ static const IWineJScriptVtbl WineJScriptVtbl = { WineJScript_InitHostObject, WineJScript_InitHostConstructor, WineJScript_CreateObject, + WineJScript_CreateArrayBuffer, WineJScript_FillGlobals, };
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index af36dd8568c..b0b65c37c72 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -297,6 +297,7 @@ void handle_dispatch_exception(script_ctx_t *ctx, EXCEPINFO *ei); HRESULT create_object(script_ctx_t*,jsdisp_t*,jsdisp_t**); HRESULT create_math(script_ctx_t*,jsdisp_t**); HRESULT create_array(script_ctx_t*,DWORD,jsdisp_t**); +HRESULT create_arraybuffer(script_ctx_t*,DWORD,IWineJSDispatch**,void**); HRESULT create_regexp(script_ctx_t*,jsstr_t*,DWORD,jsdisp_t**); HRESULT create_regexp_var(script_ctx_t*,jsval_t,jsval_t*,jsdisp_t**); HRESULT create_string(script_ctx_t*,jsstr_t*,jsdisp_t**); diff --git a/dlls/jscript/jsdisp.idl b/dlls/jscript/jsdisp.idl index 5252e68a63d..b0d881509c4 100644 --- a/dlls/jscript/jsdisp.idl +++ b/dlls/jscript/jsdisp.idl @@ -94,5 +94,6 @@ interface IWineJScript : IUnknown HRESULT InitHostObject(IWineJSDispatchHost *host_obj, IWineJSDispatch *prototype, UINT32 flags, IWineJSDispatch **ret); HRESULT InitHostConstructor(IWineJSDispatchHost *constr, const WCHAR *method_name, IWineJSDispatch **ret); HRESULT CreateObject(IWineJSDispatch **ret); + HRESULT CreateArrayBuffer(DWORD size, IWineJSDispatch **ret, void **data); HRESULT FillGlobals(IWineJSDispatchHost *script_global); } diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index 8de2b01545d..ca79bab1358 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -455,6 +455,20 @@ async_test("response", function() { [ "arraybuffer", "image/png", function() { if(xhr.readyState < 4) ok(xhr.response === undefined, "response for arraybuffer with state " + state + " = " + xhr.response); + else { + var buf = xhr.response; + ok(buf instanceof ArrayBuffer, "response for arraybuffer not instanceof ArrayBuffer"); + ok(buf.byteLength === xml.length, "response for arraybuffer byteLength = " + buf.byteLength); + buf = new Uint8Array(buf); + for(var i = 0; i < buf.length; i++) { + if(buf[i] !== xml.charCodeAt(i)) { + var a = new Array(buf.length); + for(var j = 0; j < a.length; j++) a[j] = buf[j]; + ok(false, "response for arraybuffer is wrong (first bad char at pos " + i + "): " + a); + break; + } + } + } }], [ "blob", "wine/test", function() { if(xhr.readyState < 4) diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 6c95088b59e..0aadf00aaa0 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -140,6 +140,7 @@ struct xhr { BOOLEAN synchronous; DWORD magic; DWORD pending_events_magic; + IDispatch *response_obj; HTMLInnerWindow *window; nsIXMLHttpRequest *nsxhr; XMLHttpReqEventListener *event_listener; @@ -1082,9 +1083,19 @@ static HRESULT WINAPI HTMLXMLHttpRequest_private_get_response(IWineXMLHttpReques { HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface); HRESULT hres = S_OK; + UINT32 buf_size; + nsresult nsres; + void *buf;
TRACE("(%p)->(%p)\n", This, p);
+ if(This->xhr.response_obj) { + V_VT(p) = VT_DISPATCH; + V_DISPATCH(p) = This->xhr.response_obj; + IDispatch_AddRef(This->xhr.response_obj); + return S_OK; + } + switch(This->xhr.response_type) { case response_type_empty: case response_type_text: @@ -1103,10 +1114,18 @@ static HRESULT WINAPI HTMLXMLHttpRequest_private_get_response(IWineXMLHttpReques V_VT(p) = VT_EMPTY; break; } + nsres = nsIXMLHttpRequest_GetResponseBuffer(This->xhr.nsxhr, NULL, 0, &buf_size); + assert(nsres == NS_OK); + if(This->xhr.response_type == response_type_arraybuf) { - FIXME("response_type_arraybuf\n"); - return E_NOTIMPL; + hres = IWineJScript_CreateArrayBuffer(This->xhr.window->jscript, buf_size, (IWineJSDispatch**)&This->xhr.response_obj, &buf); + if(SUCCEEDED(hres)) { + nsres = nsIXMLHttpRequest_GetResponseBuffer(This->xhr.nsxhr, buf, buf_size, &buf_size); + assert(nsres == NS_OK); + } + break; } + FIXME("response_type_blob\n"); return E_NOTIMPL;
@@ -1118,6 +1137,11 @@ static HRESULT WINAPI HTMLXMLHttpRequest_private_get_response(IWineXMLHttpReques assert(0); }
+ if(SUCCEEDED(hres) && This->xhr.response_obj) { + V_VT(p) = VT_DISPATCH; + V_DISPATCH(p) = This->xhr.response_obj; + IDispatch_AddRef(This->xhr.response_obj); + } return hres; }
@@ -1439,6 +1463,8 @@ static void xhr_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback note_cc_edge((nsISupports*)&xhr->window->base.IHTMLWindow2_iface, "window", cb); if(xhr->pending_progress_event) note_cc_edge((nsISupports*)&xhr->pending_progress_event->IDOMEvent_iface, "pending_progress_event", cb); + if(xhr->response_obj) + note_cc_edge((nsISupports*)xhr->response_obj, "response_obj", cb); if(xhr->nsxhr) note_cc_edge((nsISupports*)xhr->nsxhr, "nsxhr", cb); traverse_event_target(&xhr->event_target, cb); @@ -1462,6 +1488,7 @@ static void xhr_unlink(DispatchEx *dispex) xhr->pending_progress_event = NULL; IDOMEvent_Release(&pending_progress_event->IDOMEvent_iface); } + unlink_ref(&xhr->response_obj); unlink_ref(&xhr->nsxhr); release_event_target(&xhr->event_target); }