Add new getResponseBuffer method in nsIXMLHttpRequest.

Add a new method to nsIXMLHttpRequest that transfers the buffer contents
of gecko's ArrayBuffer response into an arbitrary buffer for wine. If
buffer is NULL, it only returns the size without transferring anything,
which allows wine to allocate the buffer. This will allow wine to implement
the response prop.

Calling it frees gecko's buffer, but of course it has to be cached on
wine side anyway because it must return reference to the same object on
subsequent calls.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
Gabriel Ivăncescu 2022-07-03 19:53:29 +03:00
parent 0018fc6db4
commit 57f5269bfc
No known key found for this signature in database
GPG Key ID: 4CEE4FF41CC69382
3 changed files with 34 additions and 0 deletions

View File

@ -325,6 +325,15 @@ interface nsIXMLHttpRequest : nsISupports
* If true, the same origin policy will not be enforced on the request.
*/
readonly attribute boolean mozSystem;
/**
* Wine Gecko:
* Transfers the buffer of an ArrayBuffer response, returns the required size.
* If buffer is non-NULL, buffer_size must be large enough to contain all the
* data, and the buffer gets transferred. This invalidates Gecko's data.
* This must always be used instead of `response` for such cases!
*/
[noscript] uint32_t getResponseBuffer(in voidPtr buffer, in uint32_t buffer_size);
};
[uuid(840d0d00-e83e-4a29-b3c7-67e96e90a499)]

View File

@ -991,6 +991,21 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx,
aResponse.setNull();
}
NS_IMETHODIMP
nsXMLHttpRequest::GetResponseBuffer(void *buffer, uint32_t buffer_size, uint32_t *ret_size)
{
if (mResponseType != XML_HTTP_RESPONSE_TYPE_ARRAYBUFFER || !(mState & XML_HTTP_REQUEST_DONE) || mResultArrayBuffer)
return NS_ERROR_DOM_INVALID_STATE_ERR;
*ret_size = mArrayBufferBuilder.length();
if (buffer) {
if (!mArrayBufferBuilder.copy_buffer(buffer, buffer_size))
return NS_ERROR_INVALID_ARG;
mArrayBufferBuilder.reset();
}
return NS_OK;
}
bool
nsXMLHttpRequest::IsCrossSiteCORSRequest()
{
@ -3892,4 +3907,13 @@ ArrayBufferBuilder::areOverlappingRegions(const uint8_t* aStart1,
return max_start < min_end;
}
bool
ArrayBufferBuilder::copy_buffer(void *buffer, uint32_t buffer_size)
{
if (buffer_size < mLength)
return false;
memcpy(buffer, mMapPtr ? mMapPtr : mDataPtr, mLength);
return true;
}
} // namespace mozilla

View File

@ -91,6 +91,7 @@ public:
uint32_t capacity() { return mCapacity; }
JSObject* getArrayBuffer(JSContext* aCx);
bool copy_buffer(void *buffer, uint32_t buffer_size);
// Memory mapping to starting position of file(aFile) in the zip
// package(aJarFile).