mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 658683: Make xhr.response not create a new ArrayBuffer every time it is accessed. r=sicking. Additional fixes by sicking, r=peterv
This commit is contained in:
parent
8e10a6f050
commit
a19b1cf42c
@ -426,7 +426,8 @@ nsXMLHttpRequest::nsXMLHttpRequest()
|
||||
mErrorLoad(PR_FALSE), mTimerIsActive(PR_FALSE),
|
||||
mProgressEventWasDelayed(PR_FALSE),
|
||||
mLoadLengthComputable(PR_FALSE), mLoadTotal(0),
|
||||
mFirstStartRequestSeen(PR_FALSE)
|
||||
mFirstStartRequestSeen(PR_FALSE),
|
||||
mResultArrayBuffer(nsnull)
|
||||
{
|
||||
mResponseBodyUnicode.SetIsVoid(PR_TRUE);
|
||||
nsLayoutStatics::AddRef();
|
||||
@ -450,6 +451,12 @@ nsXMLHttpRequest::~nsXMLHttpRequest()
|
||||
nsLayoutStatics::Release();
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLHttpRequest::RootResultArrayBuffer()
|
||||
{
|
||||
nsContentUtils::PreserveWrapper(static_cast<nsPIDOMEventTarget*>(this), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This Init method is called from the factory constructor.
|
||||
*/
|
||||
@ -572,9 +579,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLHttpRequest,
|
||||
nsIXMLHttpRequestUpload)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXMLHttpRequest,
|
||||
nsXHREventTarget)
|
||||
tmp->mResultArrayBuffer = nsnull;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mReadRequest)
|
||||
@ -592,6 +599,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXMLHttpRequest,
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mUpload)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsXMLHttpRequest,
|
||||
nsXHREventTarget)
|
||||
if(tmp->mResultArrayBuffer) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(tmp->mResultArrayBuffer,
|
||||
"mResultArrayBuffer")
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
DOMCI_DATA(XMLHttpRequest, nsXMLHttpRequest)
|
||||
|
||||
// QueryInterface implementation for nsXMLHttpRequest
|
||||
@ -839,27 +854,20 @@ NS_IMETHODIMP nsXMLHttpRequest::GetResponseText(nsAString& aResponseText)
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsXMLHttpRequest::GetResponseArrayBuffer(jsval *aResult)
|
||||
nsresult nsXMLHttpRequest::CreateResponseArrayBuffer(JSContext *aCx)
|
||||
{
|
||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
||||
if (!cx)
|
||||
if (!aCx)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!(mState & (XML_HTTP_REQUEST_DONE |
|
||||
XML_HTTP_REQUEST_LOADING))) {
|
||||
*aResult = JSVAL_NULL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 dataLen = mResponseBody.Length();
|
||||
JSObject *obj = js_CreateArrayBuffer(cx, dataLen);
|
||||
if (!obj)
|
||||
RootResultArrayBuffer();
|
||||
mResultArrayBuffer = js_CreateArrayBuffer(aCx, dataLen);
|
||||
if (!mResultArrayBuffer) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*aResult = OBJECT_TO_JSVAL(obj);
|
||||
}
|
||||
|
||||
if (dataLen > 0) {
|
||||
js::ArrayBuffer *abuf = js::ArrayBuffer::fromJSObject(obj);
|
||||
js::ArrayBuffer *abuf = js::ArrayBuffer::fromJSObject(mResultArrayBuffer);
|
||||
NS_ASSERTION(abuf, "What happened?");
|
||||
memcpy(abuf->data, mResponseBody.BeginReading(), dataLen);
|
||||
}
|
||||
@ -954,7 +962,11 @@ NS_IMETHODIMP nsXMLHttpRequest::GetResponse(JSContext *aCx, jsval *aResult)
|
||||
|
||||
case XML_HTTP_RESPONSE_TYPE_ARRAYBUFFER:
|
||||
if (mState & XML_HTTP_REQUEST_DONE) {
|
||||
rv = GetResponseArrayBuffer(aResult);
|
||||
if (!mResultArrayBuffer) {
|
||||
rv = CreateResponseArrayBuffer(aCx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
*aResult = OBJECT_TO_JSVAL(mResultArrayBuffer);
|
||||
} else {
|
||||
*aResult = JSVAL_NULL;
|
||||
}
|
||||
@ -1073,7 +1085,8 @@ nsXMLHttpRequest::Abort()
|
||||
mResponseBodyUnicode.SetIsVoid(PR_TRUE);
|
||||
mResponseBlob = nsnull;
|
||||
mState |= XML_HTTP_REQUEST_ABORTED;
|
||||
|
||||
mResultArrayBuffer = nsnull;
|
||||
|
||||
if (!(mState & (XML_HTTP_REQUEST_UNSENT |
|
||||
XML_HTTP_REQUEST_OPENED |
|
||||
XML_HTTP_REQUEST_DONE))) {
|
||||
|
@ -208,11 +208,11 @@ public:
|
||||
|
||||
void SetRequestObserver(nsIRequestObserver* aObserver);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXMLHttpRequest,
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsXMLHttpRequest,
|
||||
nsXHREventTarget)
|
||||
|
||||
PRBool AllowUploadProgress();
|
||||
|
||||
void RootResultArrayBuffer();
|
||||
|
||||
protected:
|
||||
friend class nsMultipartProxyListener;
|
||||
|
||||
@ -224,7 +224,7 @@ protected:
|
||||
PRUint32 toOffset,
|
||||
PRUint32 count,
|
||||
PRUint32 *writeCount);
|
||||
nsresult GetResponseArrayBuffer(jsval *aResult);
|
||||
nsresult CreateResponseArrayBuffer(JSContext* aCx);
|
||||
void CreateResponseBlob(nsIRequest *request);
|
||||
// Change the state of the object with this. The broadcast argument
|
||||
// determines if the onreadystatechange listener should be called.
|
||||
@ -345,6 +345,8 @@ protected:
|
||||
|
||||
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
|
||||
nsCOMPtr<nsIChannel> mNewRedirectChannel;
|
||||
|
||||
JSObject* mResultArrayBuffer;
|
||||
};
|
||||
|
||||
// helper class to expose a progress DOM Event
|
||||
|
@ -134,6 +134,16 @@ ab = xhr.response;
|
||||
ok(ab != null, "should have a non-null arraybuffer");
|
||||
arraybuffer_equals_to(ab, "\xaa\xee\0\x03\xff\xff\xff\xff\xbb\xbb\xbb\xbb");
|
||||
|
||||
// test array buffer GetResult returns the same object
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", 'file_XHR_binary1.bin', false);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.send(null)
|
||||
is(xhr.status, 200, "wrong status");
|
||||
checkResponseTextAccessThrows(xhr);
|
||||
checkResponseXMLAccessThrows(xhr);
|
||||
is(xhr.response, xhr.response, "returns the same ArrayBuffer");
|
||||
|
||||
// test response (responseType='blob')
|
||||
var onloadCount = 0;
|
||||
function checkOnloadCount() {
|
||||
|
@ -436,6 +436,20 @@ public:
|
||||
"not the nsISupports pointer we expect"); \
|
||||
_class *tmp = Downcast(s);
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(_class, _base_class) \
|
||||
void \
|
||||
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Trace(void *p, \
|
||||
TraceCallback aCallback, \
|
||||
void *aClosure) \
|
||||
{ \
|
||||
nsISupports *s = static_cast<nsISupports*>(p); \
|
||||
NS_ASSERTION(CheckForRightISupports(s), \
|
||||
"not the nsISupports pointer we expect"); \
|
||||
_class *tmp = static_cast<_class*>(Downcast(s)); \
|
||||
NS_CYCLE_COLLECTION_CLASSNAME(_base_class)::Trace(s, \
|
||||
aCallback, \
|
||||
aClosure);
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(_class) \
|
||||
void \
|
||||
NS_CYCLE_COLLECTION_CLASSNAME(_class)::Trace(void *p, \
|
||||
|
Loading…
Reference in New Issue
Block a user