summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2021-12-13 22:07:04 +0000
committerAndreas Kling <kling@serenityos.org>2021-12-14 09:01:06 +0100
commit5e06d5e9e587139bfa4a583a51bbd5d567cb954b (patch)
tree8134240b6a1c8a74e4dc59a35973b24d4c1de96d /Userland/Libraries/LibWeb
parent976ab23b9c075647bc32d0b7453c30d481d7a661 (diff)
downloadserenity-5e06d5e9e587139bfa4a583a51bbd5d567cb954b.zip
LibWeb: Implement "get a copy of the bytes held by the buffer source"
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r--Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.cpp73
-rw-r--r--Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.h3
2 files changed, 76 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.cpp b/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.cpp
index f87ea04f61..34c7dc3da9 100644
--- a/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.cpp
+++ b/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.cpp
@@ -1,12 +1,17 @@
/*
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
+ * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
+#include <AK/ByteBuffer.h>
#include <AK/NumericLimits.h>
#include <LibJS/Runtime/AbstractOperations.h>
+#include <LibJS/Runtime/ArrayBuffer.h>
+#include <LibJS/Runtime/DataView.h>
#include <LibJS/Runtime/PropertyKey.h>
+#include <LibJS/Runtime/TypedArray.h>
#include <LibWeb/Bindings/IDLAbstractOperations.h>
namespace Web::Bindings::IDL {
@@ -50,4 +55,72 @@ bool is_an_array_index(JS::GlobalObject& global_object, JS::PropertyKey const& p
return true;
}
+// https://webidl.spec.whatwg.org/#dfn-get-buffer-source-copy
+Optional<ByteBuffer> get_buffer_source_copy(JS::Object const& buffer_source)
+{
+ // 1. Let esBufferSource be the result of converting bufferSource to an ECMAScript value.
+
+ // 2. Let esArrayBuffer be esBufferSource.
+ JS::ArrayBuffer* es_array_buffer;
+
+ // 3. Let offset be 0.
+ u32 offset = 0;
+
+ // 4. Let length be 0.
+ u32 length = 0;
+
+ // 5. If esBufferSource has a [[ViewedArrayBuffer]] internal slot, then:
+ if (is<JS::TypedArrayBase>(buffer_source)) {
+ auto const& es_buffer_source = static_cast<JS::TypedArrayBase const&>(buffer_source);
+
+ // 1. Set esArrayBuffer to esBufferSource.[[ViewedArrayBuffer]].
+ es_array_buffer = es_buffer_source.viewed_array_buffer();
+
+ // 2. Set offset to esBufferSource.[[ByteOffset]].
+ offset = es_buffer_source.byte_offset();
+
+ // 3. Set length to esBufferSource.[[ByteLength]].
+ length = es_buffer_source.byte_length();
+ } else if (is<JS::DataView>(buffer_source)) {
+ auto const& es_buffer_source = static_cast<JS::DataView const&>(buffer_source);
+
+ // 1. Set esArrayBuffer to esBufferSource.[[ViewedArrayBuffer]].
+ es_array_buffer = es_buffer_source.viewed_array_buffer();
+
+ // 2. Set offset to esBufferSource.[[ByteOffset]].
+ offset = es_buffer_source.byte_offset();
+
+ // 3. Set length to esBufferSource.[[ByteLength]].
+ length = es_buffer_source.byte_length();
+ }
+ // 6. Otherwise:
+ else {
+ // 1. Assert: esBufferSource is an ArrayBuffer or SharedArrayBuffer object.
+ auto const& es_buffer_source = static_cast<JS::ArrayBuffer const&>(buffer_source);
+ es_array_buffer = &const_cast<JS ::ArrayBuffer&>(es_buffer_source);
+
+ // 2. Set length to esBufferSource.[[ArrayBufferByteLength]].
+ length = es_buffer_source.byte_length();
+ }
+
+ // 7. If ! IsDetachedBuffer(esArrayBuffer) is true, then return the empty byte sequence.
+ if (es_array_buffer->is_detached())
+ return {};
+
+ // 8. Let bytes be a new byte sequence of length equal to length.
+ auto bytes = ByteBuffer::create_zeroed(length);
+ if (!bytes.has_value())
+ return {};
+
+ // 9. For i in the range offset to offset + length − 1, inclusive, set bytes[i − offset] to ! GetValueFromBuffer(esArrayBuffer, i, Uint8, true, Unordered).
+ for (u64 i = offset; i <= offset + length - 1; ++i) {
+ auto value = es_array_buffer->get_value<u8>(i, true, JS::ArrayBuffer::Unordered);
+ dbgln("value at i = {} is {}", i, value);
+ (*bytes)[i - offset] = (u8)value.as_u32();
+ }
+
+ // 10. Return bytes.
+ return bytes;
+}
+
}
diff --git a/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.h b/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.h
index b3157b5eba..c6940d6989 100644
--- a/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.h
+++ b/Userland/Libraries/LibWeb/Bindings/IDLAbstractOperations.h
@@ -1,15 +1,18 @@
/*
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
+ * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
+#include <AK/Forward.h>
#include <LibJS/Forward.h>
namespace Web::Bindings::IDL {
bool is_an_array_index(JS::GlobalObject&, JS::PropertyKey const&);
+Optional<ByteBuffer> get_buffer_source_copy(JS::Object const& buffer_source);
}