@@ -42,6 +42,7 @@ urlPrefix: https://tc39.es/ecma262/; spec: ECMASCRIPT
42
42
text: the typed array constructors table; url: #table-49
43
43
text: typed array; url: #sec-typedarray-objects
44
44
text: Number type; url: #sec-ecmascript-language-types-number-type
45
+ text: Data Block; url: #sec-data-blocks
45
46
type: abstract-op
46
47
text: CloneArrayBuffer; url: #sec-clonearraybuffer
47
48
text: CopyDataBlockBytes; url: #sec-copydatablockbytes
@@ -165,9 +166,9 @@ readable stream tee">branches</dfn>, which can be consumed independently.
165
166
For streams representing bytes, an extended version of the [=readable stream=] is provided to handle
166
167
bytes efficiently, in particular by minimizing copies. The [=underlying source=] for such a readable
167
168
stream is called an <dfn>underlying byte source</dfn> . A readable stream whose underlying source is
168
- an underlying byte source is sometimes called a <dfn>readable byte stream</dfn> . Consumers of a
169
- readable byte stream can acquire a [=BYOB reader=] using the stream's {{ReadableStream/getReader()}}
170
- method.
169
+ an underlying byte source is sometimes called a <dfn export >readable byte stream</dfn> . Consumers of
170
+ a readable byte stream can acquire a [=BYOB reader=] using the stream's
171
+ {{ReadableStream/getReader()}} method.
171
172
172
173
<h3 id="ws-model">Writable streams</h3>
173
174
@@ -309,11 +310,12 @@ object that allows direct reading of [=chunks=] from a [=readable stream=]. With
309
310
stream|canceling=] the stream, or [=piping=] the readable stream to a writable stream. A reader is
310
311
acquired via the stream's {{ReadableStream/getReader()}} method.
311
312
312
- A [=readable byte stream=] has the ability to vend two types of readers: <dfn>default readers</dfn>
313
- and <dfn>BYOB readers</dfn> . BYOB ("bring your own buffer") readers allow reading into a
314
- developer-supplied buffer, thus minimizing copies. A non-byte readable stream can only vend default
315
- readers. Default readers are instances of the {{ReadableStreamDefaultReader}} class, while BYOB
316
- readers are instances of {{ReadableStreamBYOBReader}} .
313
+ A [=readable byte stream=] has the ability to vend two types of readers: <dfn export lt="default
314
+ reader"> default readers</dfn> and <dfn export lt="BYOB reader">BYOB readers</dfn> . BYOB ("bring your
315
+ own buffer") readers allow reading into a developer-supplied buffer, thus minimizing copies. A
316
+ non-byte readable stream can only vend default readers. Default readers are instances of the
317
+ {{ReadableStreamDefaultReader}} class, while BYOB readers are instances of
318
+ {{ReadableStreamBYOBReader}} .
317
319
318
320
Similarly, a <dfn lt="writer|writable stream writer">writable stream writer</dfn> , or simply
319
321
writer, is an object that allows direct writing of [=chunks=] to a [=writable stream=] . Without a
@@ -3244,8 +3246,9 @@ The following abstract operations support the implementation of the
3244
3246
</div>
3245
3247
3246
3248
<div algorithm>
3247
- <dfn abstract-op lt="ReadableByteStreamControllerGetBYOBRequest">ReadableByteStreamControllerGetBYOBRequest(|controller|)</dfn>
3248
- performs the following steps:
3249
+ <dfn abstract-op
3250
+ lt="ReadableByteStreamControllerGetBYOBRequest"> ReadableByteStreamControllerGetBYOBRequest(|controller|)</dfn> performs
3251
+ the following steps:
3249
3252
3250
3253
1. If |controller|.[=ReadableByteStreamController/[[byobRequest]]=] is null and
3251
3254
|controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=] is not [=list/is empty|empty=] ,
@@ -6463,7 +6466,7 @@ to grow organically as needed.
6463
6466
{{ReadableStream}} object |stream|, given an optional algorithm <dfn export for="ReadableStream/set
6464
6467
up"><var> pullAlgorithm</var></dfn> , an optional algorithm <dfn export for="ReadableStream/set
6465
6468
up"><var> cancelAlgorithm</var></dfn> , an optional number <dfn export for="ReadableStream/set
6466
- up"><var> highWaterMark</var></dfn> (default 1), an optional algorithm <dfn export
6469
+ up"><var> highWaterMark</var></dfn> (default 1), and an optional algorithm <dfn export
6467
6470
for="ReadableStream/set up"><var> sizeAlgorithm</var></dfn> , perform the following steps. If
6468
6471
given, |pullAlgorithm| and |cancelAlgorithm| may return a promise. If given, |sizeAlgorithm| must
6469
6472
be an algorithm accepting [=chunk=] objects and returning a number; and if given, |highWaterMark|
@@ -6481,42 +6484,149 @@ to grow organically as needed.
6481
6484
1. If |result| is a {{Promise}} , then return |result|.
6482
6485
1. Return [=a promise resolved with=] undefined.
6483
6486
1. If |sizeAlgorithm| was not given, then set it to an algorithm that returns 1.
6484
- 1. Perform [$InitializeReadableStream$] (|stream|).
6487
+ 1. Perform ! [$InitializeReadableStream$] (|stream|).
6485
6488
1. Let |controller| be a [=new=] {{ReadableStreamDefaultController}} .
6486
6489
1. Perform ! [$SetUpReadableStreamDefaultController$] (|stream|, |controller|, |startAlgorithm|,
6487
6490
|pullAlgorithmWrapper|, |cancelAlgorithmWrapper|, |highWaterMark|, |sizeAlgorithm|).
6491
+ </div>
6488
6492
6489
- <div class="example" id="example-set-up-rs">
6490
- Creating a {{ReadableStream}} from other specifications is thus a two-step process, like so:
6493
+ <div algorithm="set up a byte-source ReadableStream">
6494
+ To <dfn export for="ReadableStream">set up with byte reading support</dfn> a
6495
+ newly-[=new|created-via-Web IDL=] {{ReadableStream}} object |stream|, given an optional algorithm
6496
+ <dfn export for="ReadableStream/set up with byte reading support"><var>pullAlgorithm</var></dfn> ,
6497
+ an optional algorithm <dfn export for="ReadableStream/set up with byte reading
6498
+ support"><var> cancelAlgorithm</var></dfn> , and an optional number <dfn export
6499
+ for="ReadableStream/set up with byte reading support"><var> highWaterMark</var></dfn> (default 0),
6500
+ perform the following steps. If given, |pullAlgorithm| and |cancelAlgorithm| may return a promise.
6501
+ If given, |highWaterMark| must be a non-negative, non-NaN number.
6491
6502
6492
- 1. Let |readableStream| be a [=new=] {{ReadableStream}} .
6493
- 1. [=ReadableStream/Set up=] |readableStream| given….
6494
- </div>
6503
+ 1. Let |startAlgorithm| be an algorithm that returns undefined.
6504
+ 1. Let |pullAlgorithmWrapper| be an algorithm that runs these steps:
6505
+ 1. Let |result| be the result of running |pullAlgorithm|, if |pullAlgorithm| was given, or null
6506
+ otherwise. If this throws an exception |e|, return [=a promise rejected with=] |e|.
6507
+ 1. If |result| is a {{Promise}} , then return |result|.
6508
+ 1. Return [=a promise resolved with=] undefined.
6509
+ 1. Let |cancelAlgorithmWrapper| be an algorithm that runs these steps:
6510
+ 1. Let |result| be the result of running |cancelAlgorithm|, if |cancelAlgorithm| was given, or
6511
+ null otherwise. If this throws an exception |e|, return [=a promise rejected with=] |e|.
6512
+ 1. If |result| is a {{Promise}} , then return |result|.
6513
+ 1. Return [=a promise resolved with=] undefined.
6514
+ 1. Perform ! [$InitializeReadableStream$] (|stream|).
6515
+ 1. Let |controller| be a [=new=] {{ReadableByteStreamController}} .
6516
+ 1. Perform ! [$SetUpReadableByteStreamController$] (|stream|, |controller|, |startAlgorithm|,
6517
+ |pullAlgorithmWrapper|, |cancelAlgorithmWrapper|, |highWaterMark|, undefined).
6518
+ </div>
6495
6519
6496
- <p class="note"> Subclasses of {{ReadableStream}} will use the [=ReadableStream/set up=] operation
6497
- directly on the [=this=] value inside their constructor steps.</p>
6520
+ <div class="example" id="example-set-up-rs">
6521
+ Creating a {{ReadableStream}} from other specifications is thus a two-step process, like so:
6522
+
6523
+ 1. Let |readableStream| be a [=new=] {{ReadableStream}} .
6524
+ 1. [=ReadableStream/Set up=] |readableStream| given….
6498
6525
</div>
6499
6526
6527
+ <p class="note"> Subclasses of {{ReadableStream}} will use the [=ReadableStream/set up=] or
6528
+ [=ReadableStream/set up with byte reading support=] operations directly on the [=this=] value inside
6529
+ their constructor steps.
6530
+
6500
6531
<hr>
6501
6532
6502
6533
The following algorithms must only be used on {{ReadableStream}} instances initialized via the above
6503
- [=ReadableStream/set up=] algorithm:
6534
+ [=ReadableStream/set up=] or [=ReadableStream/set up with byte reading support=] algorithms (not,
6535
+ e.g., on web-developer-created instances):
6536
+
6537
+ <div algorithm>
6538
+ A {{ReadableStream}} |stream|'s <dfn export for="ReadableStream">desired size to fill up to the
6539
+ high water mark</dfn> is the result of running the following steps:
6540
+
6541
+ 1. If |stream| is not [=ReadableStream/readable=] , then return 0.
6542
+ 1. If |stream|.[=ReadableStream/[[controller]]=] [=implements=] {{ReadableByteStreamController}} ,
6543
+ then return !
6544
+ [$ReadableByteStreamControllerGetDesiredSize$] (|stream|.[=ReadableStream/[[controller]]=] ).
6545
+ 1. Return !
6546
+ [$ReadableStreamDefaultControllerGetDesiredSize$] (|stream|.[=ReadableStream/[[controller]]=] ).
6547
+ </div>
6548
+
6549
+ <p algorithm> A {{ReadableStream}} <dfn export for="ReadableStream" lt="need more data|needs
6550
+ more data"> needs more data</dfn> if its [=ReadableStream/desired size to fill up to the high water
6551
+ mark=] is greater than zero.
6504
6552
6505
- <p algorithm> A {{ReadableStream}} |stream| <dfn export for="ReadableStream" lt="need more
6506
- data|needs more data"> needs more data</dfn> if |stream| is [=ReadableStream/readable=] and !
6507
- [$ReadableStreamDefaultControllerGetDesiredSize$] (|stream|.[=ReadableStream/[[controller]]=] )
6508
- returns a positive number.
6553
+ <div algorithm>
6554
+ To <dfn export for="ReadableStream">close</dfn> a {{ReadableStream}} |stream|:
6555
+
6556
+ 1. If |stream|.[=ReadableStream/[[controller]]=] [=implements=] {{ReadableByteStreamController}} ,
6557
+ then perform !
6558
+ [$ReadableByteStreamControllerClose$] (|stream|.[=ReadableStream/[[controller]]=] ).
6559
+ 1. Perform ! [$ReadableStreamDefaultControllerClose$] (|stream|.[=ReadableStream/[[controller]]=] ).
6560
+ </div>
6561
+
6562
+ <div algorithm>
6563
+ To <dfn export for="ReadableStream">error</dfn> a {{ReadableStream}} |stream| given a JavaScript
6564
+ value |e|:
6565
+
6566
+ 1. If |stream|.[=ReadableStream/[[controller]]=] [=implements=] {{ReadableByteStreamController}} ,
6567
+ then perform ! [$ReadableByteStreamControllerError$] (|stream|.[=ReadableStream/[[controller]]=] ,
6568
+ |e|).
6569
+ 1. Perform ! [$ReadableStreamDefaultControllerError$] (|stream|.[=ReadableStream/[[controller]]=] ,
6570
+ |e|).
6571
+ </div>
6572
+
6573
+ <hr>
6574
+
6575
+ The following algorithm must only be used on {{ReadableStream}} instances initialized via the above
6576
+ [=ReadableStream/set up=] algorithm:
6509
6577
6510
6578
<p algorithm> To <dfn export for="ReadableStream">enqueue</dfn> the JavaScript value |chunk| into a
6511
6579
{{ReadableStream}} |stream|, perform !
6512
6580
[$ReadableStreamDefaultControllerEnqueue$] (|stream|.[=ReadableStream/[[controller]]=] , |chunk|).
6513
6581
6514
- <p algorithm> To <dfn export for="ReadableStream">close</dfn> a {{ReadableStream}} |stream|, perform
6515
- ! [$ReadableStreamDefaultControllerClose$] (|stream|.[=ReadableStream/[[controller]]=] ).
6582
+ <hr>
6583
+
6584
+ The following algorithms must only be used on {{ReadableStream}} instances initialized via the above
6585
+ [=ReadableStream/set up with byte reading support=] algorithm:
6586
+
6587
+ <div algorithm>
6588
+ The <dfn export for="ReadableStream">current BYOB request view</dfn> for a
6589
+ {{ReadableStream}} |stream| is either an {{ArrayBufferView}} or null, determined by the following
6590
+ steps:
6591
+
6592
+ 1. Assert: |stream|.[=ReadableStream/[[controller]]=] [=implements=]
6593
+ {{ReadableByteStreamController}} .
6594
+ 1. Let |byobRequest| be !
6595
+ [$ReadableByteStreamControllerGetBYOBRequest$] (|stream|.[=ReadableStream/[[controller]]=] ).
6596
+ 1. If |byobRequest| is null, then return null.
6597
+ 1. Return |byobRequest|.[=ReadableStreamBYOBRequest/[[view]]=] .
6598
+ </div>
6599
+
6600
+ <div algorithm>
6601
+ To <dfn export for="ReadableStream">enqueue bytes</dfn> into a {{ReadableStream}} |stream| given an
6602
+ {{ArrayBufferView}} |view|:
6603
+
6604
+ 1. Assert: |stream|.[=ReadableStream/[[controller]]=] [=implements=]
6605
+ {{ReadableByteStreamController}} .
6606
+ 1. Let |byobRequest| be !
6607
+ [$ReadableByteStreamControllerGetBYOBRequest$] (|stream|.[=ReadableStream/[[controller]]=] ).
6608
+ 1. If |byobRequest| is non-null, and |view|.\[[ViewedArrayBuffer]] .\[[ArrayBufferData]] is the same
6609
+ [=Data Block=] as |byobRequest|.\[[view]] .\[[ViewedArrayBuffer]] .\[[ArrayBufferData]] , then:
6610
+ 1. Assert: |view|.\[[ByteOffset]] is |byobRequest|.\[[view]] .\[[ByteOffset]] .
6611
+ 1. Assert: |view|.\[[ByteLength]] ≤ |byobRequest|.\[[view]] .\[[ByteLength]] .
6612
+ <p class="note"> These asserts ensure that the caller does not write outside the requested
6613
+ range in the [=ReadableStream/current BYOB request view=] .
6614
+ 1. Perform ?
6615
+ [$ReadableByteStreamControllerRespondWithNewView$] (|stream|.[=ReadableStream/[[controller]]=] ,
6616
+ |view|).
6617
+ <p class="note"> This works fine even in the case where |view|.\[[ViewedArrayBuffer]] equals
6618
+ |byobRequest|.\[[view]] .\[[ViewedArrayBuffer]] .
6619
+ 1. Otherwise, perform ?
6620
+ [$ReadableByteStreamControllerEnqueue$] (|stream|.[=ReadableStream/[[controller]]=] , |view|).
6621
+ </div>
6622
+
6623
+ Specifications should, when possible, [=ArrayBufferView/write=] into the [=ReadableStream/current
6624
+ BYOB request view=] when it is non-null, and then call [=enqueue bytes=] with that view. They should
6625
+ only [=ArrayBufferView/create=] a new {{ArrayBufferView}} to pass to [=enqueue bytes=] when the
6626
+ [=ReadableStream/current BYOB request view=] is null, or when they have more bytes on hand than the
6627
+ [=ReadableStream/current BYOB request view=] 's [=BufferSource/byte length=] . This avoids unnecessary
6628
+ copies and better respects the wishes of the stream's [=consumer=] .
6516
6629
6517
- <p algorithm> To <dfn export for="ReadableStream">error</dfn> a {{ReadableStream}} |stream| given a
6518
- JavaScript value |e|, perform !
6519
- [$ReadableStreamDefaultControllerError$] (|stream|.[=ReadableStream/[[controller]]=] , |e|).
6520
6630
6521
6631
<h4 id="other-specs-rs-reading">Reading</h4>
6522
6632
@@ -6573,7 +6683,8 @@ a chunk</dfn> from a {{ReadableStreamDefaultReader}} |reader|, given a [=read re
6573
6683
6574
6684
<p class="note"> Because |reader| grants exclusive access to its corresponding {{ReadableStream}} ,
6575
6685
the actual mechanism of how to read cannot be observed. Implementations could use a more direct
6576
- mechanism if convenient.
6686
+ mechanism if convenient, such as acquiring and using a {{ReadableStreamBYOBReader}} instead of a
6687
+ {{ReadableStreamDefaultReader}} , or accessing the chunks directly.
6577
6688
</div>
6578
6689
6579
6690
<p algorithm> To <dfn export for="ReadableStreamDefaultReader">release</dfn> a
@@ -6659,7 +6770,7 @@ for="ReadableStream">locked</dfn> if ! [$IsReadableStreamLocked$](|stream|) retu
6659
6770
1. If |result| is a {{Promise}} , then return |result|.
6660
6771
1. Return [=a promise resolved with=] undefined.
6661
6772
1. If |sizeAlgorithm| was not given, then set it to an algorithm that returns 1.
6662
- 1. Perform [$InitializeWritableStream$] (|stream|).
6773
+ 1. Perform ! [$InitializeWritableStream$] (|stream|).
6663
6774
1. Let |controller| be a [=new=] {{WritableStreamDefaultController}} .
6664
6775
1. Perform ! [$SetUpWritableStreamDefaultController$] (|stream|, |controller|, |startAlgorithm|,
6665
6776
|writeAlgorithm|, |closeAlgorithmWrapper|, |abortAlgorithmWrapper|, |highWaterMark|,
0 commit comments