mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 09:04:59 +00:00
LibWeb: Use ArrayBufferView for ReadableStreamBYOBReader
Which means that we now have support for DataViews. Using the ArrayBufferView class also seems to make this read a whole bunch nicer as well.
This commit is contained in:
parent
eab20129b9
commit
673329e1bd
7 changed files with 41 additions and 37 deletions
|
@ -1,3 +1,6 @@
|
|||
About to read! [object ReadableStreamBYOBReader]
|
||||
About to read into Uint8Array with [object ReadableStreamBYOBReader]
|
||||
Total bytes: 34
|
||||
'This is some data to be read! 🦬'
|
||||
About to read into DataView with [object ReadableStreamBYOBReader]
|
||||
Total bytes: 34
|
||||
'This is some data to be read! 🦬'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script src="../include.js"></script>
|
||||
<script>
|
||||
asyncTest(async done => {
|
||||
async function testByobRead(type) {
|
||||
const array = ['This is some data to be read! 🦬'];
|
||||
let blob = new Blob(array);
|
||||
|
||||
|
@ -11,15 +11,14 @@
|
|||
let bytesReceived = 0;
|
||||
let offset = 0;
|
||||
|
||||
println(`About to read! ${reader}`);
|
||||
println(`About to read into ${type.prototype.constructor.name} with ${reader}`);
|
||||
|
||||
while (true) {
|
||||
let result = await reader.read(new Uint8Array(buffer, offset, buffer.byteLength - offset));
|
||||
let result = await reader.read(new type(buffer, offset, buffer.byteLength - offset));
|
||||
|
||||
if (result.done) {
|
||||
println(`Total bytes: ${bytesReceived}`);
|
||||
println(`'${new TextDecoder().decode(result.value.buffer.slice(0, bytesReceived))}'`);
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -27,5 +26,11 @@
|
|||
offset += result.value.byteLength;
|
||||
bytesReceived += result.value.byteLength;
|
||||
}
|
||||
}
|
||||
|
||||
asyncTest(async done => {
|
||||
await testByobRead(Uint8Array);
|
||||
await testByobRead(DataView);
|
||||
done();
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <LibWeb/Streams/WritableStreamDefaultController.h>
|
||||
#include <LibWeb/Streams/WritableStreamDefaultWriter.h>
|
||||
#include <LibWeb/WebIDL/AbstractOperations.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
#include <LibWeb/WebIDL/Promise.h>
|
||||
|
||||
|
@ -659,15 +660,11 @@ JS::Value readable_byte_stream_controller_convert_pull_into_descriptor(JS::Realm
|
|||
}
|
||||
|
||||
// https://streams.spec.whatwg.org/#readable-byte-stream-controller-pull-into
|
||||
void readable_byte_stream_controller_pull_into(ReadableByteStreamController& controller, JS::Value view_value, ReadIntoRequest& read_into_request)
|
||||
void readable_byte_stream_controller_pull_into(ReadableByteStreamController& controller, WebIDL::ArrayBufferView& view, ReadIntoRequest& read_into_request)
|
||||
{
|
||||
auto& vm = controller.vm();
|
||||
auto& realm = controller.realm();
|
||||
|
||||
// FIXME: Support DataView
|
||||
auto& view_object = view_value.as_object();
|
||||
auto const& view = verify_cast<JS::TypedArrayBase>(view_object);
|
||||
|
||||
// 1. Let stream be controller.[[stream]].
|
||||
auto stream = controller.stream();
|
||||
|
||||
|
@ -678,32 +675,34 @@ void readable_byte_stream_controller_pull_into(ReadableByteStreamController& con
|
|||
JS::NativeFunction* ctor = realm.intrinsics().data_view_constructor();
|
||||
|
||||
// 4. If view has a [[TypedArrayName]] internal slot (i.e., it is not a DataView),
|
||||
if (!is<JS::DataView>(view_object)) {
|
||||
if (view.bufferable_object().has<JS::NonnullGCPtr<JS::TypedArrayBase>>()) {
|
||||
auto const& typed_array = view.bufferable_object().get<JS::NonnullGCPtr<JS::TypedArrayBase>>();
|
||||
|
||||
// 1. Set elementSize to the element size specified in the typed array constructors table for view.[[TypedArrayName]].
|
||||
element_size = view.element_size();
|
||||
element_size = typed_array->element_size();
|
||||
|
||||
// 2. Set ctor to the constructor specified in the typed array constructors table for view.[[TypedArrayName]].
|
||||
if (is<JS::Int16Array>(view_object))
|
||||
if (is<JS::Int16Array>(*typed_array))
|
||||
ctor = realm.intrinsics().int16_array_constructor();
|
||||
else if (is<JS::Int32Array>(view_object))
|
||||
else if (is<JS::Int32Array>(*typed_array))
|
||||
ctor = realm.intrinsics().int32_array_constructor();
|
||||
else if (is<JS::Int8Array>(view_object))
|
||||
else if (is<JS::Int8Array>(*typed_array))
|
||||
ctor = realm.intrinsics().int8_array_constructor();
|
||||
else if (is<JS::Uint8Array>(view_object))
|
||||
else if (is<JS::Uint8Array>(*typed_array))
|
||||
ctor = realm.intrinsics().uint8_array_constructor();
|
||||
else if (is<JS::Uint16Array>(view_object))
|
||||
else if (is<JS::Uint16Array>(*typed_array))
|
||||
ctor = realm.intrinsics().uint16_array_constructor();
|
||||
else if (is<JS::Uint32Array>(view_object))
|
||||
else if (is<JS::Uint32Array>(*typed_array))
|
||||
ctor = realm.intrinsics().uint32_array_constructor();
|
||||
else if (is<JS::Uint8ClampedArray>(view_object))
|
||||
else if (is<JS::Uint8ClampedArray>(*typed_array))
|
||||
ctor = realm.intrinsics().uint8_clamped_array_constructor();
|
||||
else if (is<JS::BigInt64Array>(view_object))
|
||||
else if (is<JS::BigInt64Array>(*typed_array))
|
||||
ctor = realm.intrinsics().big_int64_array_constructor();
|
||||
else if (is<JS::BigUint64Array>(view_object))
|
||||
else if (is<JS::BigUint64Array>(*typed_array))
|
||||
ctor = realm.intrinsics().big_uint64_array_constructor();
|
||||
else if (is<JS::Float32Array>(view_object))
|
||||
else if (is<JS::Float32Array>(*typed_array))
|
||||
ctor = realm.intrinsics().float32_array_constructor();
|
||||
else if (is<JS::Float64Array>(view_object))
|
||||
else if (is<JS::Float64Array>(*typed_array))
|
||||
ctor = realm.intrinsics().float64_array_constructor();
|
||||
else
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -812,7 +811,7 @@ void readable_byte_stream_controller_pull_into(ReadableByteStreamController& con
|
|||
}
|
||||
|
||||
// https://streams.spec.whatwg.org/#readable-stream-byob-reader-read
|
||||
void readable_stream_byob_reader_read(ReadableStreamBYOBReader& reader, JS::Value view, ReadIntoRequest& read_into_request)
|
||||
void readable_stream_byob_reader_read(ReadableStreamBYOBReader& reader, WebIDL::ArrayBufferView& view, ReadIntoRequest& read_into_request)
|
||||
{
|
||||
// 1. Let stream be reader.[[stream]].
|
||||
auto stream = reader.stream();
|
||||
|
|
|
@ -54,8 +54,8 @@ WebIDL::ExceptionOr<void> readable_stream_reader_generic_release(ReadableStreamG
|
|||
void readable_stream_default_reader_error_read_requests(ReadableStreamDefaultReader&, JS::Value error);
|
||||
void readable_stream_byob_reader_error_read_into_requests(ReadableStreamBYOBReader&, JS::Value error);
|
||||
JS::Value readable_byte_stream_controller_convert_pull_into_descriptor(JS::Realm&, PullIntoDescriptor const&);
|
||||
void readable_byte_stream_controller_pull_into(ReadableByteStreamController&, JS::Value view_value, ReadIntoRequest&);
|
||||
void readable_stream_byob_reader_read(ReadableStreamBYOBReader&, JS::Value view, ReadIntoRequest&);
|
||||
void readable_byte_stream_controller_pull_into(ReadableByteStreamController&, WebIDL::ArrayBufferView&, ReadIntoRequest&);
|
||||
void readable_stream_byob_reader_read(ReadableStreamBYOBReader&, WebIDL::ArrayBufferView&, ReadIntoRequest&);
|
||||
void readable_byte_stream_controller_fill_head_pull_into_descriptor(ReadableByteStreamController const&, u64 size, PullIntoDescriptor&);
|
||||
|
||||
WebIDL::ExceptionOr<void> readable_stream_default_reader_read(ReadableStreamDefaultReader&, ReadRequest&);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <LibWeb/Streams/AbstractOperations.h>
|
||||
#include <LibWeb/Streams/ReadableStream.h>
|
||||
#include <LibWeb/Streams/ReadableStreamBYOBReader.h>
|
||||
#include <LibWeb/WebIDL/Buffers.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
||||
namespace Web::Streams {
|
||||
|
@ -103,29 +104,26 @@ private:
|
|||
};
|
||||
|
||||
// https://streams.spec.whatwg.org/#byob-reader-read
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> ReadableStreamBYOBReader::read(JS::Value view_value)
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> ReadableStreamBYOBReader::read(JS::Handle<WebIDL::ArrayBufferView>& view)
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
|
||||
// FIXME: Support DataViews
|
||||
auto& view = verify_cast<JS::TypedArrayBase>(view_value.as_object());
|
||||
|
||||
// 1. If view.[[ByteLength]] is 0, return a promise rejected with a TypeError exception.
|
||||
if (view.byte_length() == 0) {
|
||||
if (view->byte_length() == 0) {
|
||||
auto exception = JS::TypeError::create(realm, "Cannot read in an empty buffer"sv);
|
||||
auto promise_capability = WebIDL::create_rejected_promise(realm, exception);
|
||||
return JS::NonnullGCPtr { verify_cast<JS::Promise>(*promise_capability->promise()) };
|
||||
}
|
||||
|
||||
// 2. If view.[[ViewedArrayBuffer]].[[ArrayBufferByteLength]] is 0, return a promise rejected with a TypeError exception.
|
||||
if (view.viewed_array_buffer()->byte_length() == 0) {
|
||||
if (view->viewed_array_buffer()->byte_length() == 0) {
|
||||
auto exception = JS::TypeError::create(realm, "Cannot read in an empty buffer"sv);
|
||||
auto promise_capability = WebIDL::create_rejected_promise(realm, exception);
|
||||
return JS::NonnullGCPtr { verify_cast<JS::Promise>(*promise_capability->promise()) };
|
||||
}
|
||||
|
||||
// 3. If ! IsDetachedBuffer(view.[[ViewedArrayBuffer]]) is true, return a promise rejected with a TypeError exception.
|
||||
if (view.viewed_array_buffer()->is_detached()) {
|
||||
if (view->viewed_array_buffer()->is_detached()) {
|
||||
auto exception = JS::TypeError::create(realm, "Cannot read in a detached buffer"sv);
|
||||
auto promise_capability = WebIDL::create_rejected_promise(realm, exception);
|
||||
return JS::NonnullGCPtr { verify_cast<JS::Promise>(*promise_capability->promise()) };
|
||||
|
@ -151,7 +149,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> ReadableStreamBYOBReader::rea
|
|||
auto read_into_request = heap().allocate_without_realm<BYOBReaderReadIntoRequest>(realm, promise_capability);
|
||||
|
||||
// 7. Perform ! ReadableStreamBYOBReaderRead(this, view, readIntoRequest).
|
||||
readable_stream_byob_reader_read(*this, view_value, *read_into_request);
|
||||
readable_stream_byob_reader_read(*this, *view, *read_into_request);
|
||||
|
||||
// 8. Return promise.
|
||||
return JS::NonnullGCPtr { verify_cast<JS::Promise>(*promise_capability->promise()) };
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
|
||||
virtual ~ReadableStreamBYOBReader() override = default;
|
||||
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> read(JS::Value);
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<JS::Promise>> read(JS::Handle<WebIDL::ArrayBufferView>&);
|
||||
|
||||
void release_lock();
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
interface ReadableStreamBYOBReader {
|
||||
constructor(ReadableStream stream);
|
||||
|
||||
// FIXME: This should accept an ArrayBufferView
|
||||
Promise<ReadableStreamReadResult> read(any view);
|
||||
Promise<ReadableStreamReadResult> read(ArrayBufferView view);
|
||||
|
||||
undefined releaseLock();
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue