/* * Copyright (c) 2021, Luke Wilde * Copyright (c) 2021, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #include #include namespace Web::Bindings::IDL { // https://webidl.spec.whatwg.org/#dfn-get-buffer-source-copy Optional 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(buffer_source)) { auto const& es_buffer_source = static_cast(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(buffer_source)) { auto const& es_buffer_source = static_cast(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(buffer_source); es_array_buffer = &const_cast(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 ByteBuffer {}; // 8. Let bytes be a new byte sequence of length equal to length. auto bytes = ByteBuffer::create_zeroed(length); if (bytes.is_error()) 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(i, true, JS::ArrayBuffer::Unordered); bytes.value()[i - offset] = (u8)value.as_u32(); } // 10. Return bytes. return bytes.release_value(); } }