Skip to content

Specification unclear on type of byobRequest.view #1366

Description

@cinderflash

What is the issue with the Streams Standard?

To implement a readable byte stream, an underlying source fulfills BYOB requests. The request provides a .view property as a space to write data into. The specification in various places indicates this is an ArrayBufferView or TypedArray or Uint8Array. Is it possible to get some clarification on this?

FWIW my preference would be that it's always Uint8Array. That would make it simpler and easier to implement byte streams. I think it's rare for a source of binary data to provide something other than octets, so in virtually all cases you'll be converting to Uint8Array internally if you receive anything else.

Details of what I'm seeing in the spec.

The Web IDL definition of ReadableStreamBYOBRequest says .view is an ArrayBufferView. This means TypedArray or DataView.

readonly attribute ArrayBufferView? view;

The .view property exposes the internal slot [[view]].

The `view` getter steps are:
  1. Return this.[[view]].

The description of [[view]] says it contains a TypedArray (but never a DataView).

A typed array representing the destination region to which the controller can write generated data, or null after the BYOB request has been invalidated.

The only place [[view]] is set is in ReadableByteStreamControllerGetBYOBRequest (no direct link available). This logic sets it to a value that is always a Uint8Array (never a DataView or any other type of TypedArray).

  1. Let view be ! Construct(%Uint8Array%, « firstDescriptor’s buffer, firstDescriptor’s byte offset + firstDescriptor’s bytes filled, firstDescriptor’s byte length − firstDescriptor’s bytes filled »).
    ..
  2. Set byobRequest.[[view]] to view.

This is all about the internal view provided to the underlying source. There is another view constructed and provided in response to a byobReader.read(view) call. This output view can be any ArrayBufferView. Maybe these internal and external views just got muddled up a little while writing the spec.

The algorithm ReadableByteStreamControllerPullInto takes the view passed to .read() and stores its constructor into a pull-into descriptor.

Set ctor to the constructor specified in the typed array constructors table for view.[[TypedArrayName]].

Let pullIntoDescriptor be a new pull-into descriptor with

  • view constructor ctor

After a BYOB request is fulfilled, ReadableByteStreamControllerConvertPullIntoDescriptor constructs the output view using the stored constructor. This makes the output view the same type as the view the user provided to .read().

Return ! Construct(pullIntoDescriptor’s view constructor, « buffer, pullIntoDescriptor’s byte offset, bytesFilled ÷ elementSize »).

The description of "view constructor" says it's used to construct the internal view, which seems to be wrong. The internal view is always Uint8Array and the stored "view constructor" is used to construct the output view.

view constructor
A typed array constructor or %DataView%, which will be used for constructing a view with which to write into the buffer

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions