@@ -647,7 +647,7 @@ function ReadableByteStreamTee(stream) {
647
647
reading = false ;
648
648
}
649
649
} ;
650
- ReadableStreamBYOBReaderRead ( reader , view , readIntoRequest ) ;
650
+ ReadableStreamBYOBReaderRead ( reader , view , 1 , readIntoRequest ) ;
651
651
}
652
652
653
653
function pull1Algorithm ( ) {
@@ -913,7 +913,7 @@ function ReadableStreamReaderGenericRelease(reader) {
913
913
reader . _stream = undefined ;
914
914
}
915
915
916
- function ReadableStreamBYOBReaderRead ( reader , view , readIntoRequest ) {
916
+ function ReadableStreamBYOBReaderRead ( reader , view , min , readIntoRequest ) {
917
917
const stream = reader . _stream ;
918
918
919
919
assert ( stream !== undefined ) ;
@@ -923,7 +923,7 @@ function ReadableStreamBYOBReaderRead(reader, view, readIntoRequest) {
923
923
if ( stream . _state === 'errored' ) {
924
924
readIntoRequest . errorSteps ( stream . _storedError ) ;
925
925
} else {
926
- ReadableByteStreamControllerPullInto ( stream . _controller , view , readIntoRequest ) ;
926
+ ReadableByteStreamControllerPullInto ( stream . _controller , view , min , readIntoRequest ) ;
927
927
}
928
928
}
929
929
@@ -1272,7 +1272,7 @@ function ReadableByteStreamControllerClose(controller) {
1272
1272
1273
1273
if ( controller . _pendingPullIntos . length > 0 ) {
1274
1274
const firstPendingPullInto = controller . _pendingPullIntos [ 0 ] ;
1275
- if ( firstPendingPullInto . bytesFilled > 0 ) {
1275
+ if ( firstPendingPullInto . bytesFilled % firstPendingPullInto . elementSize !== 0 ) {
1276
1276
const e = new TypeError ( 'Insufficient bytes to fill elements in the given buffer' ) ;
1277
1277
ReadableByteStreamControllerError ( controller , e ) ;
1278
1278
@@ -1290,7 +1290,7 @@ function ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDe
1290
1290
1291
1291
let done = false ;
1292
1292
if ( stream . _state === 'closed' ) {
1293
- assert ( pullIntoDescriptor . bytesFilled === 0 ) ;
1293
+ assert ( pullIntoDescriptor . bytesFilled % pullIntoDescriptor . elementSize === 0 ) ;
1294
1294
done = true ;
1295
1295
}
1296
1296
@@ -1419,18 +1419,18 @@ function ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, size
1419
1419
}
1420
1420
1421
1421
function ReadableByteStreamControllerFillPullIntoDescriptorFromQueue ( controller , pullIntoDescriptor ) {
1422
- const elementSize = pullIntoDescriptor . elementSize ;
1423
-
1424
- const currentAlignedBytes = pullIntoDescriptor . bytesFilled - pullIntoDescriptor . bytesFilled % elementSize ;
1425
-
1426
1422
const maxBytesToCopy = Math . min ( controller . _queueTotalSize ,
1427
1423
pullIntoDescriptor . byteLength - pullIntoDescriptor . bytesFilled ) ;
1428
1424
const maxBytesFilled = pullIntoDescriptor . bytesFilled + maxBytesToCopy ;
1429
- const maxAlignedBytes = maxBytesFilled - maxBytesFilled % elementSize ;
1430
1425
1431
1426
let totalBytesToCopyRemaining = maxBytesToCopy ;
1432
1427
let ready = false ;
1433
- if ( maxAlignedBytes > currentAlignedBytes ) {
1428
+ assert ( pullIntoDescriptor . bytesFilled < pullIntoDescriptor . minimumFill ) ;
1429
+ const remainderBytes = maxBytesFilled % pullIntoDescriptor . elementSize ;
1430
+ const maxAlignedBytes = maxBytesFilled - remainderBytes ;
1431
+ // A descriptor for a read() request that is not yet filled up to its minimum length will stay at the head
1432
+ // of the queue, so the underlying source can keep filling it.
1433
+ if ( maxAlignedBytes >= pullIntoDescriptor . minimumFill ) {
1434
1434
totalBytesToCopyRemaining = maxAlignedBytes - pullIntoDescriptor . bytesFilled ;
1435
1435
ready = true ;
1436
1436
}
@@ -1461,7 +1461,7 @@ function ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller,
1461
1461
if ( ready === false ) {
1462
1462
assert ( controller . _queueTotalSize === 0 ) ;
1463
1463
assert ( pullIntoDescriptor . bytesFilled > 0 ) ;
1464
- assert ( pullIntoDescriptor . bytesFilled < pullIntoDescriptor . elementSize ) ;
1464
+ assert ( pullIntoDescriptor . bytesFilled < pullIntoDescriptor . minimumFill ) ;
1465
1465
}
1466
1466
1467
1467
return ready ;
@@ -1563,14 +1563,18 @@ function ReadableByteStreamControllerProcessReadRequestsUsingQueue(controller) {
1563
1563
}
1564
1564
}
1565
1565
1566
- function ReadableByteStreamControllerPullInto ( controller , view , readIntoRequest ) {
1566
+ function ReadableByteStreamControllerPullInto ( controller , view , min , readIntoRequest ) {
1567
1567
const stream = controller . _stream ;
1568
1568
1569
1569
let elementSize = 1 ;
1570
1570
if ( view . constructor !== DataView ) {
1571
1571
elementSize = view . constructor . BYTES_PER_ELEMENT ;
1572
1572
}
1573
1573
1574
+ const minimumFill = min * elementSize ;
1575
+ assert ( minimumFill >= elementSize && minimumFill <= view . byteLength ) ;
1576
+ assert ( minimumFill % elementSize === 0 ) ;
1577
+
1574
1578
const ctor = view . constructor ;
1575
1579
1576
1580
let buffer ;
@@ -1587,6 +1591,7 @@ function ReadableByteStreamControllerPullInto(controller, view, readIntoRequest)
1587
1591
byteOffset : view . byteOffset ,
1588
1592
byteLength : view . byteLength ,
1589
1593
bytesFilled : 0 ,
1594
+ minimumFill,
1590
1595
elementSize,
1591
1596
viewConstructor : ctor ,
1592
1597
readerType : 'byob'
@@ -1660,7 +1665,7 @@ function ReadableByteStreamControllerRespond(controller, bytesWritten) {
1660
1665
}
1661
1666
1662
1667
function ReadableByteStreamControllerRespondInClosedState ( controller , firstDescriptor ) {
1663
- assert ( firstDescriptor . bytesFilled === 0 ) ;
1668
+ assert ( firstDescriptor . bytesFilled % firstDescriptor . elementSize === 0 ) ;
1664
1669
1665
1670
if ( firstDescriptor . readerType === 'none' ) {
1666
1671
ReadableByteStreamControllerShiftPendingPullInto ( controller ) ;
@@ -1686,7 +1691,9 @@ function ReadableByteStreamControllerRespondInReadableState(controller, bytesWri
1686
1691
return ;
1687
1692
}
1688
1693
1689
- if ( pullIntoDescriptor . bytesFilled < pullIntoDescriptor . elementSize ) {
1694
+ if ( pullIntoDescriptor . bytesFilled < pullIntoDescriptor . minimumFill ) {
1695
+ // A descriptor for a read() request that is not yet filled up to its minimum length will stay at the head
1696
+ // of the queue, so the underlying source can keep filling it.
1690
1697
return ;
1691
1698
}
1692
1699
0 commit comments