Best JavaScript code snippet using wpt
readable.js
Source:readable.js
...928 throw new TypeError('ReadableStreamBYOBRequest cannot be used directly');929 }930 get view() {931 if (IsReadableStreamBYOBRequest(this) === false) {932 throw byobRequestBrandCheckException('view');933 }934 return this[kView];935 }936 respond(bytesWritten) {937 if (IsReadableStreamBYOBRequest(this) === false) {938 throw byobRequestBrandCheckException('respond');939 }940 if (this[kAssociatedReadableByteStreamController] === undefined) {941 throw new TypeError('This BYOB request has been invalidated');942 }943 if (IsDetachedBuffer(this[kView].buffer) === true) {944 throw new TypeError('The BYOB request\'s buffer has been detached and so cannot be used as a response');945 }946 ReadableByteStreamControllerRespond(this[kAssociatedReadableByteStreamController], bytesWritten);947 }948 respondWithNewView(view) {949 if (IsReadableStreamBYOBRequest(this) === false) {950 throw byobRequestBrandCheckException('respond');951 }952 if (this[kAssociatedReadableByteStreamController] === undefined) {953 throw new TypeError('This BYOB request has been invalidated');954 }955 if (!ArrayBuffer.isView(view)) {956 throw new TypeError('You can only respond with array buffer views');957 }958 if (IsDetachedBuffer(view.buffer) === true) {959 throw new TypeError('The supplied view\'s buffer has been detached and so cannot be used as a response');960 }961 ReadableByteStreamControllerRespondWithNewView(this[kAssociatedReadableByteStreamController], view);962 }963 }964 class ReadableByteStreamController {965 constructor() {966 throw new TypeError('ReadableByteStreamController constructor cannot be used directly');967 }968 get byobRequest() {969 if (IsReadableByteStreamController(this) === false) {970 throw byteStreamControllerBrandCheckException('byobRequest');971 }972 if (this[kByobRequest] === undefined && this[kPendingPullIntos].length > 0) {973 const firstDescriptor = this[kPendingPullIntos][0];974 const view = new Uint8Array(firstDescriptor.buffer,975 firstDescriptor.byteOffset + firstDescriptor.bytesFilled,976 firstDescriptor.byteLength - firstDescriptor.bytesFilled);977 const byobRequest = Object.create(ReadableStreamBYOBRequest.prototype);978 SetUpReadableStreamBYOBRequest(byobRequest, this, view);979 this[kByobRequest] = byobRequest;980 }981 return this[kByobRequest];982 }983 get desiredSize() {984 if (IsReadableByteStreamController(this) === false) {985 throw byteStreamControllerBrandCheckException('desiredSize');986 }987 return ReadableByteStreamControllerGetDesiredSize(this);988 }989 close() {990 if (IsReadableByteStreamController(this) === false) {991 throw byteStreamControllerBrandCheckException('close');992 }993 if (this[kCloseRequested] === true) {994 throw new TypeError('The stream has already been closed; do not close it again!');995 }996 const state = this[kControlledReadableByteStream][kState];997 if (state !== 'readable') {998 throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be closed`);999 }1000 ReadableByteStreamControllerClose(this);1001 }1002 enqueue(chunk) {1003 if (IsReadableByteStreamController(this) === false) {1004 throw byteStreamControllerBrandCheckException('enqueue');1005 }1006 if (this[kCloseRequested] === true) {1007 throw new TypeError('stream is closed or draining');1008 }1009 const state = this[kControlledReadableByteStream][kState];1010 if (state !== 'readable') {1011 throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be enqueued to`);1012 }1013 if (!ArrayBuffer.isView(chunk)) {1014 throw new TypeError('You can only enqueue array buffer views when using a ReadableByteStreamController');1015 }1016 if (IsDetachedBuffer(chunk.buffer) === true) {1017 throw new TypeError('Cannot enqueue a view onto a detached ArrayBuffer');1018 }1019 ReadableByteStreamControllerEnqueue(this, chunk);1020 }1021 error(e) {1022 if (IsReadableByteStreamController(this) === false) {1023 throw byteStreamControllerBrandCheckException('error');1024 }1025 ReadableByteStreamControllerError(this, e);1026 }1027 [CancelSteps](reason) {1028 if (this[kPendingPullIntos].length > 0) {1029 const firstDescriptor = this[kPendingPullIntos][0];1030 firstDescriptor.bytesFilled = 0;1031 }1032 ResetQueue(this);1033 return this[kCancelAlgorithm](reason);1034 }1035 [PullSteps]() {1036 const stream = this[kControlledReadableByteStream];1037 assert(ReadableStreamHasDefaultReader(stream) === true);1038 if (this[kQueueTotalSize] > 0) {1039 assert(ReadableStreamGetNumReadRequests(stream) === 0);1040 const entry = this[kQueue].shift();1041 this[kQueueTotalSize] -= entry.byteLength;1042 ReadableByteStreamControllerHandleQueueDrain(this);1043 let view;1044 try {1045 view = new Uint8Array(entry.buffer, entry.byteOffset, entry.byteLength);1046 } catch (viewE) {1047 return Promise.reject(viewE);1048 }1049 return Promise.resolve(CreateIterResultObject(view, false));1050 }1051 const autoAllocateChunkSize = this[kAutoAllocateChunkSize];1052 if (autoAllocateChunkSize !== undefined) {1053 let buffer;1054 try {1055 buffer = new ArrayBuffer(autoAllocateChunkSize);1056 } catch (bufferE) {1057 return Promise.reject(bufferE);1058 }1059 const pullIntoDescriptor = {1060 buffer,1061 byteOffset: 0,1062 byteLength: autoAllocateChunkSize,1063 bytesFilled: 0,1064 elementSize: 1,1065 ctor: Uint8Array,1066 readerType: 'default',1067 };1068 this[kPendingPullIntos].push(pullIntoDescriptor);1069 }1070 const promise = ReadableStreamAddReadRequest(stream);1071 ReadableByteStreamControllerCallPullIfNeeded(this);1072 return promise;1073 }1074 }1075 // Abstract operations for the ReadableByteStreamController.1076 function IsReadableByteStreamController(x) {1077 if (!typeIsObject(x)) {1078 return false;1079 }1080 if (!Object.prototype.hasOwnProperty.call(x, kControlledReadableByteStream)) {1081 return false;1082 }1083 return true;1084 }1085 function IsReadableStreamBYOBRequest(x) {1086 if (!typeIsObject(x)) {1087 return false;1088 }1089 if (!Object.prototype.hasOwnProperty.call(x, kAssociatedReadableByteStreamController)) {1090 return false;1091 }1092 return true;1093 }1094 function ReadableByteStreamControllerCallPullIfNeeded(controller) {1095 const shouldPull = ReadableByteStreamControllerShouldCallPull(controller);1096 if (shouldPull === false) {1097 return undefined;1098 }1099 if (controller[kPulling] === true) {1100 controller[kPullAgain] = true;1101 return undefined;1102 }1103 assert(controller[kPullAgain] === false);1104 controller[kPulling] = true;1105 // TODO: Test controller argument1106 const pullPromise = controller[kPullAlgorithm]();1107 pullPromise.then(1108 () => {1109 controller[kPulling] = false;1110 if (controller[kPullAgain] === true) {1111 controller[kPullAgain] = false;1112 ReadableByteStreamControllerCallPullIfNeeded(controller);1113 }1114 },1115 (e) => {1116 ReadableByteStreamControllerError(controller, e);1117 },1118 )1119 .catch(rethrowAssertionErrorRejection);1120 return undefined;1121 }1122 function ReadableByteStreamControllerClearPendingPullIntos(controller) {1123 ReadableByteStreamControllerInvalidateBYOBRequest(controller);1124 controller[kPendingPullIntos] = [];1125 }1126 function ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor) {1127 assert(stream[kState] !== 'errored');1128 let done = false;1129 if (stream[kState] === 'closed') {1130 assert(pullIntoDescriptor.bytesFilled === 0);1131 done = true;1132 }1133 const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);1134 if (pullIntoDescriptor.readerType === 'default') {1135 ReadableStreamFulfillReadRequest(stream, filledView, done);1136 } else {1137 assert(pullIntoDescriptor.readerType === 'byob');1138 ReadableStreamFulfillReadIntoRequest(stream, filledView, done);1139 }1140 }1141 function ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor) {1142 const bytesFilled = pullIntoDescriptor.bytesFilled;1143 const elementSize = pullIntoDescriptor.elementSize;1144 assert(bytesFilled <= pullIntoDescriptor.byteLength);1145 assert(bytesFilled % elementSize === 0);1146 return new pullIntoDescriptor.ctor( // eslint-disable-line new-cap1147 pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, bytesFilled / elementSize,1148 );1149 }1150 function ReadableByteStreamControllerEnqueueChunkToQueue(controller, buffer, byteOffset, byteLength) {1151 controller[kQueue].push({ buffer, byteOffset, byteLength });1152 controller[kQueueTotalSize] += byteLength;1153 }1154 function ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor) {1155 const elementSize = pullIntoDescriptor.elementSize;1156 const currentAlignedBytes = pullIntoDescriptor.bytesFilled - (pullIntoDescriptor.bytesFilled % elementSize);1157 const maxBytesToCopy = Math.min(controller[kQueueTotalSize],1158 pullIntoDescriptor.byteLength - pullIntoDescriptor.bytesFilled);1159 const maxBytesFilled = pullIntoDescriptor.bytesFilled + maxBytesToCopy;1160 const maxAlignedBytes = maxBytesFilled - (maxBytesFilled % elementSize);1161 let totalBytesToCopyRemaining = maxBytesToCopy;1162 let ready = false;1163 if (maxAlignedBytes > currentAlignedBytes) {1164 totalBytesToCopyRemaining = maxAlignedBytes - pullIntoDescriptor.bytesFilled;1165 ready = true;1166 }1167 const queue = controller[kQueue];1168 while (totalBytesToCopyRemaining > 0) {1169 const headOfQueue = queue[0];1170 const bytesToCopy = Math.min(totalBytesToCopyRemaining, headOfQueue.byteLength);1171 const destStart = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;1172 ArrayBufferCopy(pullIntoDescriptor.buffer, destStart, headOfQueue.buffer, headOfQueue.byteOffset, bytesToCopy);1173 if (headOfQueue.byteLength === bytesToCopy) {1174 queue.shift();1175 } else {1176 headOfQueue.byteOffset += bytesToCopy;1177 headOfQueue.byteLength -= bytesToCopy;1178 }1179 controller[kQueueTotalSize] -= bytesToCopy;1180 ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesToCopy, pullIntoDescriptor);1181 totalBytesToCopyRemaining -= bytesToCopy;1182 }1183 if (ready === false) {1184 assert(controller[kQueueTotalSize] === 0);1185 assert(pullIntoDescriptor.bytesFilled > 0);1186 assert(pullIntoDescriptor.bytesFilled < pullIntoDescriptor.elementSize);1187 }1188 return ready;1189 }1190 function ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, size, pullIntoDescriptor) {1191 assert(controller[kPendingPullIntos].length === 0 || controller[kPendingPullIntos][0] === pullIntoDescriptor);1192 ReadableByteStreamControllerInvalidateBYOBRequest(controller);1193 pullIntoDescriptor.bytesFilled += size;1194 }1195 function ReadableByteStreamControllerHandleQueueDrain(controller) {1196 assert(controller[kControlledReadableByteStream][kState] === 'readable');1197 if (controller[kQueueTotalSize] === 0 && controller[kCloseRequested] === true) {1198 ReadableStreamClose(controller[kControlledReadableByteStream]);1199 } else {1200 ReadableByteStreamControllerCallPullIfNeeded(controller);1201 }1202 }1203 function ReadableByteStreamControllerInvalidateBYOBRequest(controller) {1204 if (controller[kByobRequest] === undefined) {1205 return;1206 }1207 controller[kByobRequest][kAssociatedReadableByteStreamController] = undefined;1208 controller[kByobRequest][kView] = undefined;1209 controller[kByobRequest] = undefined;1210 }1211 function ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller) {1212 assert(controller[kCloseRequested] === false);1213 while (controller[kPendingPullIntos].length > 0) {1214 if (controller[kQueueTotalSize] === 0) {1215 return;1216 }1217 const pullIntoDescriptor = controller[kPendingPullIntos][0];1218 if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor) === true) {1219 ReadableByteStreamControllerShiftPendingPullInto(controller);1220 ReadableByteStreamControllerCommitPullIntoDescriptor(1221 controller[kControlledReadableByteStream],1222 pullIntoDescriptor,1223 );1224 }1225 }1226 }1227 function ReadableByteStreamControllerPullInto(controller, view) {1228 const stream = controller[kControlledReadableByteStream];1229 let elementSize = 1;1230 if (view.constructor !== DataView) {1231 elementSize = view.constructor.BYTES_PER_ELEMENT;1232 }1233 const ctor = view.constructor;1234 const buffer = TransferArrayBuffer(view.buffer);1235 const pullIntoDescriptor = {1236 buffer,1237 byteOffset: view.byteOffset,1238 byteLength: view.byteLength,1239 bytesFilled: 0,1240 elementSize,1241 ctor,1242 readerType: 'byob',1243 };1244 if (controller[kPendingPullIntos].length > 0) {1245 controller[kPendingPullIntos].push(pullIntoDescriptor);1246 // No ReadableByteStreamControllerCallPullIfNeeded() call since:1247 // - No change happens on desiredSize1248 // - The source has already been notified of that there's at least 1 pending read(view)1249 return ReadableStreamAddReadIntoRequest(stream);1250 }1251 if (stream[kState] === 'closed') {1252 const emptyView = new view.constructor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, 0);1253 return Promise.resolve(CreateIterResultObject(emptyView, true));1254 }1255 if (controller[kQueueTotalSize] > 0) {1256 if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor) === true) {1257 const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);1258 ReadableByteStreamControllerHandleQueueDrain(controller);1259 return Promise.resolve(CreateIterResultObject(filledView, false));1260 }1261 if (controller[kCloseRequested] === true) {1262 const e = new TypeError('Insufficient bytes to fill elements in the given buffer');1263 ReadableByteStreamControllerError(controller, e);1264 return Promise.reject(e);1265 }1266 }1267 controller[kPendingPullIntos].push(pullIntoDescriptor);1268 const promise = ReadableStreamAddReadIntoRequest(stream);1269 ReadableByteStreamControllerCallPullIfNeeded(controller);1270 return promise;1271 }1272 function ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor) {1273 firstDescriptor.buffer = TransferArrayBuffer(firstDescriptor.buffer);1274 assert(firstDescriptor.bytesFilled === 0);1275 const stream = controller[kControlledReadableByteStream];1276 if (ReadableStreamHasBYOBReader(stream) === true) {1277 while (ReadableStreamGetNumReadIntoRequests(stream) > 0) {1278 const pullIntoDescriptor = ReadableByteStreamControllerShiftPendingPullInto(controller);1279 ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor);1280 }1281 }1282 }1283 function ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, pullIntoDescriptor) {1284 if (pullIntoDescriptor.bytesFilled + bytesWritten > pullIntoDescriptor.byteLength) {1285 throw new RangeError('bytesWritten out of range');1286 }1287 ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesWritten, pullIntoDescriptor);1288 if (pullIntoDescriptor.bytesFilled < pullIntoDescriptor.elementSize) {1289 // TODO: Figure out whether we should detach the buffer or not here.1290 return;1291 }1292 ReadableByteStreamControllerShiftPendingPullInto(controller);1293 const remainderSize = pullIntoDescriptor.bytesFilled % pullIntoDescriptor.elementSize;1294 if (remainderSize > 0) {1295 const end = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;1296 const remainder = pullIntoDescriptor.buffer.slice(end - remainderSize, end);1297 ReadableByteStreamControllerEnqueueChunkToQueue(controller, remainder, 0, remainder.byteLength);1298 }1299 pullIntoDescriptor.buffer = TransferArrayBuffer(pullIntoDescriptor.buffer);1300 pullIntoDescriptor.bytesFilled -= remainderSize;1301 ReadableByteStreamControllerCommitPullIntoDescriptor(controller[kControlledReadableByteStream], pullIntoDescriptor);1302 ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);1303 }1304 function ReadableByteStreamControllerRespondInternal(controller, bytesWritten) {1305 const firstDescriptor = controller[kPendingPullIntos][0];1306 const stream = controller[kControlledReadableByteStream];1307 if (stream[kState] === 'closed') {1308 if (bytesWritten !== 0) {1309 throw new TypeError('bytesWritten must be 0 when calling respond() on a closed stream');1310 }1311 ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor);1312 } else {1313 assert(stream[kState] === 'readable');1314 ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, firstDescriptor);1315 }1316 ReadableByteStreamControllerCallPullIfNeeded(controller);1317 }1318 function ReadableByteStreamControllerShiftPendingPullInto(controller) {1319 const descriptor = controller[kPendingPullIntos].shift();1320 ReadableByteStreamControllerInvalidateBYOBRequest(controller);1321 return descriptor;1322 }1323 function ReadableByteStreamControllerShouldCallPull(controller) {1324 const stream = controller[kControlledReadableByteStream];1325 if (stream[kState] !== 'readable') {1326 return false;1327 }1328 if (controller[kCloseRequested] === true) {1329 return false;1330 }1331 if (controller[kStarted] === false) {1332 return false;1333 }1334 if (ReadableStreamHasDefaultReader(stream) === true && ReadableStreamGetNumReadRequests(stream) > 0) {1335 return true;1336 }1337 if (ReadableStreamHasBYOBReader(stream) === true && ReadableStreamGetNumReadIntoRequests(stream) > 0) {1338 return true;1339 }1340 const desiredSize = ReadableByteStreamControllerGetDesiredSize(controller);1341 assert(desiredSize !== null);1342 if (desiredSize > 0) {1343 return true;1344 }1345 return false;1346 }1347 // A client of ReadableByteStreamController may use these functions directly to bypass state check.1348 function ReadableByteStreamControllerClose(controller) {1349 const stream = controller[kControlledReadableByteStream];1350 assert(controller[kCloseRequested] === false);1351 assert(stream[kState] === 'readable');1352 if (controller[kQueueTotalSize] > 0) {1353 controller[kCloseRequested] = true;1354 return;1355 }1356 if (controller[kPendingPullIntos].length > 0) {1357 const firstPendingPullInto = controller[kPendingPullIntos][0];1358 if (firstPendingPullInto.bytesFilled > 0) {1359 const e = new TypeError('Insufficient bytes to fill elements in the given buffer');1360 ReadableByteStreamControllerError(controller, e);1361 throw e;1362 }1363 }1364 ReadableStreamClose(stream);1365 }1366 function ReadableByteStreamControllerEnqueue(controller, chunk) {1367 const stream = controller[kControlledReadableByteStream];1368 assert(controller[kCloseRequested] === false);1369 assert(stream[kState] === 'readable');1370 const buffer = chunk.buffer;1371 const byteOffset = chunk.byteOffset;1372 const byteLength = chunk.byteLength;1373 const transferredBuffer = TransferArrayBuffer(buffer);1374 if (ReadableStreamHasDefaultReader(stream) === true) {1375 if (ReadableStreamGetNumReadRequests(stream) === 0) {1376 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);1377 } else {1378 assert(controller[kQueue].length === 0);1379 const transferredView = new Uint8Array(transferredBuffer, byteOffset, byteLength);1380 ReadableStreamFulfillReadRequest(stream, transferredView, false);1381 }1382 } else if (ReadableStreamHasBYOBReader(stream) === true) {1383 // TODO: Ideally in this branch detaching should happen only if the buffer is not consumed fully.1384 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);1385 ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);1386 } else {1387 assert(IsReadableStreamLocked(stream) === false);1388 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);1389 }1390 ReadableByteStreamControllerCallPullIfNeeded(controller);1391 }1392 function ReadableByteStreamControllerError(controller, e) {1393 const stream = controller[kControlledReadableByteStream];1394 if (stream[kState] !== 'readable') {1395 return;1396 }1397 ReadableByteStreamControllerClearPendingPullIntos(controller);1398 ResetQueue(controller);1399 ReadableStreamError(stream, e);1400 }1401 function ReadableByteStreamControllerGetDesiredSize(controller) {1402 const stream = controller[kControlledReadableByteStream];1403 const state = stream[kState];1404 if (state === 'errored') {1405 return null;1406 }1407 if (state === 'closed') {1408 return 0;1409 }1410 return controller[kStrategyHWM] - controller[kQueueTotalSize];1411 }1412 function ReadableByteStreamControllerRespond(controller, bytesWritten) {1413 bytesWritten = Number(bytesWritten);1414 if (IsFiniteNonNegativeNumber(bytesWritten) === false) {1415 throw new RangeError('bytesWritten must be a finite');1416 }1417 assert(controller[kPendingPullIntos].length > 0);1418 ReadableByteStreamControllerRespondInternal(controller, bytesWritten);1419 }1420 function ReadableByteStreamControllerRespondWithNewView(controller, view) {1421 assert(controller[kPendingPullIntos].length > 0);1422 const firstDescriptor = controller[kPendingPullIntos][0];1423 if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== view.byteOffset) {1424 throw new RangeError('The region specified by view does not match byobRequest');1425 }1426 if (firstDescriptor.byteLength !== view.byteLength) {1427 throw new RangeError('The buffer of view has different capacity than byobRequest');1428 }1429 firstDescriptor.buffer = view.buffer;1430 ReadableByteStreamControllerRespondInternal(controller, view.byteLength);1431 }1432 function SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm,1433 highWaterMark, autoAllocateChunkSize) {1434 assert(stream[kReadableStreamController] === undefined);1435 if (autoAllocateChunkSize !== undefined) {1436 assert(Number.isInteger(autoAllocateChunkSize) === true);1437 assert(autoAllocateChunkSize > 0);1438 }1439 controller[kControlledReadableByteStream] = stream;1440 controller[kPullAgain] = false;1441 controller[kPulling] = false;1442 ReadableByteStreamControllerClearPendingPullIntos(controller);1443 // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly.1444 controller[kQueue] = controller[kQueueTotalSize] = undefined;1445 ResetQueue(controller);1446 controller[kCloseRequested] = false;1447 controller[kStarted] = false;1448 controller[kStrategyHWM] = ValidateAndNormalizeHighWaterMark(highWaterMark);1449 controller[kPullAlgorithm] = pullAlgorithm;1450 controller[kCancelAlgorithm] = cancelAlgorithm;1451 controller[kAutoAllocateChunkSize] = autoAllocateChunkSize;1452 controller[kPendingPullIntos] = [];1453 stream[kReadableStreamController] = controller;1454 const startResult = startAlgorithm();1455 Promise.resolve(startResult).then(1456 () => {1457 controller[kStarted] = true;1458 assert(controller[kPulling] === false);1459 assert(controller[kPullAgain] === false);1460 ReadableByteStreamControllerCallPullIfNeeded(controller);1461 },1462 (r) => {1463 ReadableByteStreamControllerError(controller, r);1464 },1465 )1466 .catch(rethrowAssertionErrorRejection);1467 }1468 function SetUpReadableByteStreamControllerFromUnderlyingSource(stream, underlyingByteSource, highWaterMark) {1469 assert(underlyingByteSource !== undefined);1470 const controller = Object.create(ReadableByteStreamController.prototype);1471 function startAlgorithm() {1472 return InvokeOrNoop(underlyingByteSource, 'start', [controller]);1473 }1474 const pullAlgorithm = CreateAlgorithmFromUnderlyingMethod(underlyingByteSource, 'pull', 0, [controller]);1475 const cancelAlgorithm = CreateAlgorithmFromUnderlyingMethod(underlyingByteSource, 'cancel', 1, []);1476 let autoAllocateChunkSize = underlyingByteSource.autoAllocateChunkSize;1477 if (autoAllocateChunkSize !== undefined) {1478 autoAllocateChunkSize = Number(autoAllocateChunkSize);1479 if (Number.isInteger(autoAllocateChunkSize) === false || autoAllocateChunkSize <= 0) {1480 throw new RangeError('autoAllocateChunkSize must be a positive integer');1481 }1482 }1483 SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark,1484 autoAllocateChunkSize);1485 }1486 function SetUpReadableStreamBYOBRequest(request, controller, view) {1487 assert(IsReadableByteStreamController(controller) === true);1488 assert(typeof view === 'object');1489 assert(ArrayBuffer.isView(view) === true);1490 assert(IsDetachedBuffer(view.buffer) === false);1491 request[kAssociatedReadableByteStreamController] = controller;1492 request[kView] = view;1493 }1494 // Helper functions for the ReadableStream.1495 function streamBrandCheckException(name) {1496 return new TypeError(`ReadableStream.prototype.${name} can only be used on a ReadableStream`);1497 }1498 // Helper functions for the readers.1499 function readerLockException(name) {1500 return new TypeError(`Cannot ${name} a stream using a released reader`);1501 }1502 // Helper functions for the ReadableStreamDefaultReader.1503 function defaultReaderBrandCheckException(name) {1504 return new TypeError(1505 `ReadableStreamDefaultReader.prototype.${name} can only be used on a ReadableStreamDefaultReader`,1506 );1507 }1508 function defaultReaderClosedPromiseInitialize(reader) {1509 reader[kClosedPromise] = new Promise((resolve, reject) => {1510 reader[kClosedPromiseResolve] = resolve;1511 reader[kClosedPromiseReject] = reject;1512 });1513 }1514 function defaultReaderClosedPromiseInitializeAsRejected(reader, reason) {1515 reader[kClosedPromise] = Promise.reject(reason);1516 reader[kClosedPromiseResolve] = undefined;1517 reader[kClosedPromiseReject] = undefined;1518 }1519 function defaultReaderClosedPromiseInitializeAsResolved(reader) {1520 reader[kClosedPromise] = Promise.resolve(undefined);1521 reader[kClosedPromiseResolve] = undefined;1522 reader[kClosedPromiseReject] = undefined;1523 }1524 function defaultReaderClosedPromiseReject(reader, reason) {1525 assert(reader[kClosedPromiseResolve] !== undefined);1526 assert(reader[kClosedPromiseReject] !== undefined);1527 reader[kClosedPromiseReject](reason);1528 reader[kClosedPromiseResolve] = undefined;1529 reader[kClosedPromiseReject] = undefined;1530 }1531 function defaultReaderClosedPromiseResetToRejected(reader, reason) {1532 assert(reader[kClosedPromiseResolve] === undefined);1533 assert(reader[kClosedPromiseReject] === undefined);1534 reader[kClosedPromise] = Promise.reject(reason);1535 }1536 function defaultReaderClosedPromiseResolve(reader) {1537 assert(reader[kClosedPromiseResolve] !== undefined);1538 assert(reader[kClosedPromiseReject] !== undefined);1539 reader[kClosedPromiseResolve](undefined);1540 reader[kClosedPromiseResolve] = undefined;1541 reader[kClosedPromiseReject] = undefined;1542 }1543 // Helper functions for the ReadableStreamDefaultReader.1544 function byobReaderBrandCheckException(name) {1545 return new TypeError(1546 `ReadableStreamBYOBReader.prototype.${name} can only be used on a ReadableStreamBYOBReader`,1547 );1548 }1549 // Helper functions for the ReadableStreamDefaultController.1550 function defaultControllerBrandCheckException(name) {1551 return new TypeError(1552 `ReadableStreamDefaultController.prototype.${name} can only be used on a ReadableStreamDefaultController`,1553 );1554 }1555 // Helper functions for the ReadableStreamBYOBRequest.1556 function byobRequestBrandCheckException(name) {1557 return new TypeError(1558 `ReadableStreamBYOBRequest.prototype.${name} can only be used on a ReadableStreamBYOBRequest`,1559 );1560 }1561 // Helper functions for the ReadableByteStreamController.1562 function byteStreamControllerBrandCheckException(name) {1563 return new TypeError(1564 `ReadableByteStreamController.prototype.${name} can only be used on a ReadableByteStreamController`,1565 );1566 }1567 // Helper function for ReadableStream pipeThrough1568 function ifIsObjectAndHasAPromiseIsHandledInternalSlotSetPromiseIsHandledToTrue(promise) {1569 try {1570 // This relies on the brand-check that is enforced by Promise.prototype.then(). As with the rest of the reference...
byte-stream-controller.ts
Source:byte-stream-controller.ts
...46 * Returns the view for writing in to, or `null` if the BYOB request has already been responded to.47 */48 get view(): ArrayBufferView | null {49 if (!IsReadableStreamBYOBRequest(this)) {50 throw byobRequestBrandCheckException('view');51 }52 return this._view;53 }54 /**55 * Indicates to the associated readable byte stream that `bytesWritten` bytes were written into56 * {@link ReadableStreamBYOBRequest.view | view}, causing the result be surfaced to the consumer.57 *58 * After this method is called, {@link ReadableStreamBYOBRequest.view | view} will be transferred and no longer59 * modifiable.60 */61 respond(bytesWritten: number): void;62 respond(bytesWritten: number | undefined): void {63 if (!IsReadableStreamBYOBRequest(this)) {64 throw byobRequestBrandCheckException('respond');65 }66 assertRequiredArgument(bytesWritten, 1, 'respond');67 bytesWritten = convertUnsignedLongLongWithEnforceRange(bytesWritten, 'First parameter');68 if (this._associatedReadableByteStreamController === undefined) {69 throw new TypeError('This BYOB request has been invalidated');70 }71 if (IsDetachedBuffer(this._view!.buffer)) {72 throw new TypeError(`The BYOB request's buffer has been detached and so cannot be used as a response`);73 }74 assert(this._view!.byteLength > 0);75 assert(this._view!.buffer.byteLength > 0);76 ReadableByteStreamControllerRespond(this._associatedReadableByteStreamController, bytesWritten);77 }78 /**79 * Indicates to the associated readable byte stream that instead of writing into80 * {@link ReadableStreamBYOBRequest.view | view}, the underlying byte source is providing a new `ArrayBufferView`,81 * which will be given to the consumer of the readable byte stream.82 *83 * After this method is called, `view` will be transferred and no longer modifiable.84 */85 respondWithNewView(view: ArrayBufferView): void;86 respondWithNewView(view: ArrayBufferView | undefined): void {87 if (!IsReadableStreamBYOBRequest(this)) {88 throw byobRequestBrandCheckException('respondWithNewView');89 }90 assertRequiredArgument(view, 1, 'respondWithNewView');91 if (!ArrayBuffer.isView(view)) {92 throw new TypeError('You can only respond with array buffer views');93 }94 if (view.byteLength === 0) {95 throw new TypeError('chunk must have non-zero byteLength');96 }97 if (view.buffer.byteLength === 0) {98 throw new TypeError(`chunk's buffer must have non-zero byteLength`);99 }100 if (this._associatedReadableByteStreamController === undefined) {101 throw new TypeError('This BYOB request has been invalidated');102 }103 ReadableByteStreamControllerRespondWithNewView(this._associatedReadableByteStreamController, view);104 }105}106Object.defineProperties(ReadableStreamBYOBRequest.prototype, {107 respond: { enumerable: true },108 respondWithNewView: { enumerable: true },109 view: { enumerable: true }110});111if (typeof Symbol.toStringTag === 'symbol') {112 Object.defineProperty(ReadableStreamBYOBRequest.prototype, Symbol.toStringTag, {113 value: 'ReadableStreamBYOBRequest',114 configurable: true115 });116}117interface ArrayBufferViewConstructor<T extends ArrayBufferView = ArrayBufferView> {118 new(buffer: ArrayBufferLike, byteOffset: number, length?: number): T;119 readonly prototype: T;120 readonly BYTES_PER_ELEMENT: number;121}122interface ByteQueueElement {123 buffer: ArrayBufferLike;124 byteOffset: number;125 byteLength: number;126}127type PullIntoDescriptor<T extends ArrayBufferView = ArrayBufferView> =128 DefaultPullIntoDescriptor129 | BYOBPullIntoDescriptor;130interface DefaultPullIntoDescriptor {131 buffer: ArrayBufferLike;132 byteOffset: number;133 byteLength: number;134 bytesFilled: number;135 elementSize: number;136 viewConstructor: ArrayBufferViewConstructor<Uint8Array>;137 readerType: 'default';138}139interface BYOBPullIntoDescriptor<T extends ArrayBufferView = ArrayBufferView> {140 buffer: ArrayBufferLike;141 byteOffset: number;142 byteLength: number;143 bytesFilled: number;144 elementSize: number;145 viewConstructor: ArrayBufferViewConstructor<T>;146 readerType: 'byob';147}148/**149 * Allows control of a {@link ReadableStream | readable byte stream}'s state and internal queue.150 *151 * @public152 */153export class ReadableByteStreamController {154 /** @internal */155 _controlledReadableByteStream!: ReadableByteStream;156 /** @internal */157 _queue!: SimpleQueue<ByteQueueElement>;158 /** @internal */159 _queueTotalSize!: number;160 /** @internal */161 _started!: boolean;162 /** @internal */163 _closeRequested!: boolean;164 /** @internal */165 _pullAgain!: boolean;166 /** @internal */167 _pulling !: boolean;168 /** @internal */169 _strategyHWM!: number;170 /** @internal */171 _pullAlgorithm!: () => Promise<void>;172 /** @internal */173 _cancelAlgorithm!: (reason: any) => Promise<void>;174 /** @internal */175 _autoAllocateChunkSize: number | undefined;176 /** @internal */177 _byobRequest: ReadableStreamBYOBRequest | null;178 /** @internal */179 _pendingPullIntos!: SimpleQueue<PullIntoDescriptor>;180 private constructor() {181 throw new TypeError('Illegal constructor');182 }183 /**184 * Returns the current BYOB pull request, or `null` if there isn't one.185 */186 get byobRequest(): ReadableStreamBYOBRequest | null {187 if (!IsReadableByteStreamController(this)) {188 throw byteStreamControllerBrandCheckException('byobRequest');189 }190 if (this._byobRequest === null && this._pendingPullIntos.length > 0) {191 const firstDescriptor = this._pendingPullIntos.peek();192 const view = new Uint8Array(firstDescriptor.buffer,193 firstDescriptor.byteOffset + firstDescriptor.bytesFilled,194 firstDescriptor.byteLength - firstDescriptor.bytesFilled);195 const byobRequest: ReadableStreamBYOBRequest = Object.create(ReadableStreamBYOBRequest.prototype);196 SetUpReadableStreamBYOBRequest(byobRequest, this, view);197 this._byobRequest = byobRequest;198 }199 return this._byobRequest;200 }201 /**202 * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is203 * over-full. An underlying byte source ought to use this information to determine when and how to apply backpressure.204 */205 get desiredSize(): number | null {206 if (!IsReadableByteStreamController(this)) {207 throw byteStreamControllerBrandCheckException('desiredSize');208 }209 return ReadableByteStreamControllerGetDesiredSize(this);210 }211 /**212 * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from213 * the stream, but once those are read, the stream will become closed.214 */215 close(): void {216 if (!IsReadableByteStreamController(this)) {217 throw byteStreamControllerBrandCheckException('close');218 }219 if (this._closeRequested) {220 throw new TypeError('The stream has already been closed; do not close it again!');221 }222 const state = this._controlledReadableByteStream._state;223 if (state !== 'readable') {224 throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be closed`);225 }226 ReadableByteStreamControllerClose(this);227 }228 /**229 * Enqueues the given chunk chunk in the controlled readable stream.230 * The chunk has to be an `ArrayBufferView` instance, or else a `TypeError` will be thrown.231 */232 enqueue(chunk: ArrayBufferView): void;233 enqueue(chunk: ArrayBufferView | undefined): void {234 if (!IsReadableByteStreamController(this)) {235 throw byteStreamControllerBrandCheckException('enqueue');236 }237 assertRequiredArgument(chunk, 1, 'enqueue');238 if (!ArrayBuffer.isView(chunk)) {239 throw new TypeError('chunk must be an array buffer view');240 }241 if (chunk.byteLength === 0) {242 throw new TypeError('chunk must have non-zero byteLength');243 }244 if (chunk.buffer.byteLength === 0) {245 throw new TypeError(`chunk's buffer must have non-zero byteLength`);246 }247 if (this._closeRequested) {248 throw new TypeError('stream is closed or draining');249 }250 const state = this._controlledReadableByteStream._state;251 if (state !== 'readable') {252 throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be enqueued to`);253 }254 ReadableByteStreamControllerEnqueue(this, chunk);255 }256 /**257 * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`.258 */259 error(e: any = undefined): void {260 if (!IsReadableByteStreamController(this)) {261 throw byteStreamControllerBrandCheckException('error');262 }263 ReadableByteStreamControllerError(this, e);264 }265 /** @internal */266 [CancelSteps](reason: any): Promise<void> {267 if (this._pendingPullIntos.length > 0) {268 const firstDescriptor = this._pendingPullIntos.peek();269 firstDescriptor.bytesFilled = 0;270 }271 ResetQueue(this);272 const result = this._cancelAlgorithm(reason);273 ReadableByteStreamControllerClearAlgorithms(this);274 return result;275 }276 /** @internal */277 [PullSteps](readRequest: ReadRequest<Uint8Array>): void {278 const stream = this._controlledReadableByteStream;279 assert(ReadableStreamHasDefaultReader(stream));280 if (this._queueTotalSize > 0) {281 assert(ReadableStreamGetNumReadRequests(stream) === 0);282 const entry = this._queue.shift()!;283 this._queueTotalSize -= entry.byteLength;284 ReadableByteStreamControllerHandleQueueDrain(this);285 const view = new Uint8Array(entry.buffer, entry.byteOffset, entry.byteLength);286 readRequest._chunkSteps(view);287 return;288 }289 const autoAllocateChunkSize = this._autoAllocateChunkSize;290 if (autoAllocateChunkSize !== undefined) {291 let buffer: ArrayBuffer;292 try {293 buffer = new ArrayBuffer(autoAllocateChunkSize);294 } catch (bufferE) {295 readRequest._errorSteps(bufferE);296 return;297 }298 const pullIntoDescriptor: DefaultPullIntoDescriptor = {299 buffer,300 byteOffset: 0,301 byteLength: autoAllocateChunkSize,302 bytesFilled: 0,303 elementSize: 1,304 viewConstructor: Uint8Array,305 readerType: 'default'306 };307 this._pendingPullIntos.push(pullIntoDescriptor);308 }309 ReadableStreamAddReadRequest(stream, readRequest);310 ReadableByteStreamControllerCallPullIfNeeded(this);311 }312}313Object.defineProperties(ReadableByteStreamController.prototype, {314 close: { enumerable: true },315 enqueue: { enumerable: true },316 error: { enumerable: true },317 byobRequest: { enumerable: true },318 desiredSize: { enumerable: true }319});320if (typeof Symbol.toStringTag === 'symbol') {321 Object.defineProperty(ReadableByteStreamController.prototype, Symbol.toStringTag, {322 value: 'ReadableByteStreamController',323 configurable: true324 });325}326// Abstract operations for the ReadableByteStreamController.327export function IsReadableByteStreamController(x: any): x is ReadableByteStreamController {328 if (!typeIsObject(x)) {329 return false;330 }331 if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableByteStream')) {332 return false;333 }334 return true;335}336function IsReadableStreamBYOBRequest(x: any): x is ReadableStreamBYOBRequest {337 if (!typeIsObject(x)) {338 return false;339 }340 if (!Object.prototype.hasOwnProperty.call(x, '_associatedReadableByteStreamController')) {341 return false;342 }343 return true;344}345function ReadableByteStreamControllerCallPullIfNeeded(controller: ReadableByteStreamController): void {346 const shouldPull = ReadableByteStreamControllerShouldCallPull(controller);347 if (!shouldPull) {348 return;349 }350 if (controller._pulling) {351 controller._pullAgain = true;352 return;353 }354 assert(!controller._pullAgain);355 controller._pulling = true;356 // TODO: Test controller argument357 const pullPromise = controller._pullAlgorithm();358 uponPromise(359 pullPromise,360 () => {361 controller._pulling = false;362 if (controller._pullAgain) {363 controller._pullAgain = false;364 ReadableByteStreamControllerCallPullIfNeeded(controller);365 }366 },367 e => {368 ReadableByteStreamControllerError(controller, e);369 }370 );371}372function ReadableByteStreamControllerClearPendingPullIntos(controller: ReadableByteStreamController) {373 ReadableByteStreamControllerInvalidateBYOBRequest(controller);374 controller._pendingPullIntos = new SimpleQueue();375}376function ReadableByteStreamControllerCommitPullIntoDescriptor<T extends ArrayBufferView>(stream: ReadableByteStream,377 pullIntoDescriptor: PullIntoDescriptor<T>) {378 assert(stream._state !== 'errored');379 let done = false;380 if (stream._state === 'closed') {381 assert(pullIntoDescriptor.bytesFilled === 0);382 done = true;383 }384 const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor<T>(pullIntoDescriptor);385 if (pullIntoDescriptor.readerType === 'default') {386 ReadableStreamFulfillReadRequest(stream, filledView as unknown as Uint8Array, done);387 } else {388 assert(pullIntoDescriptor.readerType === 'byob');389 ReadableStreamFulfillReadIntoRequest(stream, filledView, done);390 }391}392function ReadableByteStreamControllerConvertPullIntoDescriptor<T extends ArrayBufferView>(pullIntoDescriptor: PullIntoDescriptor<T>): T {393 const bytesFilled = pullIntoDescriptor.bytesFilled;394 const elementSize = pullIntoDescriptor.elementSize;395 assert(bytesFilled <= pullIntoDescriptor.byteLength);396 assert(bytesFilled % elementSize === 0);397 return new pullIntoDescriptor.viewConstructor(398 pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, bytesFilled / elementSize) as T;399}400function ReadableByteStreamControllerEnqueueChunkToQueue(controller: ReadableByteStreamController,401 buffer: ArrayBufferLike,402 byteOffset: number,403 byteLength: number) {404 controller._queue.push({ buffer, byteOffset, byteLength });405 controller._queueTotalSize += byteLength;406}407function ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller: ReadableByteStreamController,408 pullIntoDescriptor: PullIntoDescriptor) {409 const elementSize = pullIntoDescriptor.elementSize;410 const currentAlignedBytes = pullIntoDescriptor.bytesFilled - pullIntoDescriptor.bytesFilled % elementSize;411 const maxBytesToCopy = Math.min(controller._queueTotalSize,412 pullIntoDescriptor.byteLength - pullIntoDescriptor.bytesFilled);413 const maxBytesFilled = pullIntoDescriptor.bytesFilled + maxBytesToCopy;414 const maxAlignedBytes = maxBytesFilled - maxBytesFilled % elementSize;415 let totalBytesToCopyRemaining = maxBytesToCopy;416 let ready = false;417 if (maxAlignedBytes > currentAlignedBytes) {418 totalBytesToCopyRemaining = maxAlignedBytes - pullIntoDescriptor.bytesFilled;419 ready = true;420 }421 const queue = controller._queue;422 while (totalBytesToCopyRemaining > 0) {423 const headOfQueue = queue.peek();424 const bytesToCopy = Math.min(totalBytesToCopyRemaining, headOfQueue.byteLength);425 const destStart = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;426 CopyDataBlockBytes(pullIntoDescriptor.buffer, destStart, headOfQueue.buffer, headOfQueue.byteOffset, bytesToCopy);427 if (headOfQueue.byteLength === bytesToCopy) {428 queue.shift();429 } else {430 headOfQueue.byteOffset += bytesToCopy;431 headOfQueue.byteLength -= bytesToCopy;432 }433 controller._queueTotalSize -= bytesToCopy;434 ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesToCopy, pullIntoDescriptor);435 totalBytesToCopyRemaining -= bytesToCopy;436 }437 if (!ready) {438 assert(controller._queueTotalSize === 0);439 assert(pullIntoDescriptor.bytesFilled > 0);440 assert(pullIntoDescriptor.bytesFilled < pullIntoDescriptor.elementSize);441 }442 return ready;443}444function ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller: ReadableByteStreamController,445 size: number,446 pullIntoDescriptor: PullIntoDescriptor) {447 assert(controller._pendingPullIntos.length === 0 || controller._pendingPullIntos.peek() === pullIntoDescriptor);448 ReadableByteStreamControllerInvalidateBYOBRequest(controller);449 pullIntoDescriptor.bytesFilled += size;450}451function ReadableByteStreamControllerHandleQueueDrain(controller: ReadableByteStreamController) {452 assert(controller._controlledReadableByteStream._state === 'readable');453 if (controller._queueTotalSize === 0 && controller._closeRequested) {454 ReadableByteStreamControllerClearAlgorithms(controller);455 ReadableStreamClose(controller._controlledReadableByteStream);456 } else {457 ReadableByteStreamControllerCallPullIfNeeded(controller);458 }459}460function ReadableByteStreamControllerInvalidateBYOBRequest(controller: ReadableByteStreamController) {461 if (controller._byobRequest === null) {462 return;463 }464 controller._byobRequest._associatedReadableByteStreamController = undefined!;465 controller._byobRequest._view = null!;466 controller._byobRequest = null;467}468function ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller: ReadableByteStreamController) {469 assert(!controller._closeRequested);470 while (controller._pendingPullIntos.length > 0) {471 if (controller._queueTotalSize === 0) {472 return;473 }474 const pullIntoDescriptor = controller._pendingPullIntos.peek();475 if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) {476 ReadableByteStreamControllerShiftPendingPullInto(controller);477 ReadableByteStreamControllerCommitPullIntoDescriptor(478 controller._controlledReadableByteStream,479 pullIntoDescriptor480 );481 }482 }483}484export function ReadableByteStreamControllerPullInto<T extends ArrayBufferView>(485 controller: ReadableByteStreamController,486 view: T,487 readIntoRequest: ReadIntoRequest<T>488): void {489 const stream = controller._controlledReadableByteStream;490 let elementSize = 1;491 if (view.constructor !== DataView) {492 elementSize = (view.constructor as ArrayBufferViewConstructor<T>).BYTES_PER_ELEMENT;493 }494 const ctor = view.constructor as ArrayBufferViewConstructor<T>;495 const buffer = TransferArrayBuffer(view.buffer);496 const pullIntoDescriptor: BYOBPullIntoDescriptor<T> = {497 buffer,498 byteOffset: view.byteOffset,499 byteLength: view.byteLength,500 bytesFilled: 0,501 elementSize,502 viewConstructor: ctor,503 readerType: 'byob'504 };505 if (controller._pendingPullIntos.length > 0) {506 controller._pendingPullIntos.push(pullIntoDescriptor);507 // No ReadableByteStreamControllerCallPullIfNeeded() call since:508 // - No change happens on desiredSize509 // - The source has already been notified of that there's at least 1 pending read(view)510 ReadableStreamAddReadIntoRequest(stream, readIntoRequest);511 return;512 }513 if (stream._state === 'closed') {514 const emptyView = new ctor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, 0);515 readIntoRequest._closeSteps(emptyView);516 return;517 }518 if (controller._queueTotalSize > 0) {519 if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) {520 const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor<T>(pullIntoDescriptor);521 ReadableByteStreamControllerHandleQueueDrain(controller);522 readIntoRequest._chunkSteps(filledView);523 return;524 }525 if (controller._closeRequested) {526 const e = new TypeError('Insufficient bytes to fill elements in the given buffer');527 ReadableByteStreamControllerError(controller, e);528 readIntoRequest._errorSteps(e);529 return;530 }531 }532 controller._pendingPullIntos.push(pullIntoDescriptor);533 ReadableStreamAddReadIntoRequest<T>(stream, readIntoRequest);534 ReadableByteStreamControllerCallPullIfNeeded(controller);535}536function ReadableByteStreamControllerRespondInClosedState(controller: ReadableByteStreamController,537 firstDescriptor: PullIntoDescriptor) {538 firstDescriptor.buffer = TransferArrayBuffer(firstDescriptor.buffer);539 assert(firstDescriptor.bytesFilled === 0);540 const stream = controller._controlledReadableByteStream;541 if (ReadableStreamHasBYOBReader(stream)) {542 while (ReadableStreamGetNumReadIntoRequests(stream) > 0) {543 const pullIntoDescriptor = ReadableByteStreamControllerShiftPendingPullInto(controller);544 ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor);545 }546 }547}548function ReadableByteStreamControllerRespondInReadableState(controller: ReadableByteStreamController,549 bytesWritten: number,550 pullIntoDescriptor: PullIntoDescriptor) {551 if (pullIntoDescriptor.bytesFilled + bytesWritten > pullIntoDescriptor.byteLength) {552 throw new RangeError('bytesWritten out of range');553 }554 ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesWritten, pullIntoDescriptor);555 if (pullIntoDescriptor.bytesFilled < pullIntoDescriptor.elementSize) {556 // TODO: Figure out whether we should detach the buffer or not here.557 return;558 }559 ReadableByteStreamControllerShiftPendingPullInto(controller);560 const remainderSize = pullIntoDescriptor.bytesFilled % pullIntoDescriptor.elementSize;561 if (remainderSize > 0) {562 const end = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;563 const remainder = pullIntoDescriptor.buffer.slice(end - remainderSize, end);564 ReadableByteStreamControllerEnqueueChunkToQueue(controller, remainder, 0, remainder.byteLength);565 }566 pullIntoDescriptor.buffer = TransferArrayBuffer(pullIntoDescriptor.buffer);567 pullIntoDescriptor.bytesFilled -= remainderSize;568 ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor);569 ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);570}571function ReadableByteStreamControllerRespondInternal(controller: ReadableByteStreamController, bytesWritten: number) {572 const firstDescriptor = controller._pendingPullIntos.peek();573 const stream = controller._controlledReadableByteStream;574 if (stream._state === 'closed') {575 if (bytesWritten !== 0) {576 throw new TypeError('bytesWritten must be 0 when calling respond() on a closed stream');577 }578 ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor);579 } else {580 assert(stream._state === 'readable');581 ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, firstDescriptor);582 }583 ReadableByteStreamControllerCallPullIfNeeded(controller);584}585function ReadableByteStreamControllerShiftPendingPullInto(controller: ReadableByteStreamController): PullIntoDescriptor {586 const descriptor = controller._pendingPullIntos.shift()!;587 ReadableByteStreamControllerInvalidateBYOBRequest(controller);588 return descriptor;589}590function ReadableByteStreamControllerShouldCallPull(controller: ReadableByteStreamController): boolean {591 const stream = controller._controlledReadableByteStream;592 if (stream._state !== 'readable') {593 return false;594 }595 if (controller._closeRequested) {596 return false;597 }598 if (!controller._started) {599 return false;600 }601 if (ReadableStreamHasDefaultReader(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {602 return true;603 }604 if (ReadableStreamHasBYOBReader(stream) && ReadableStreamGetNumReadIntoRequests(stream) > 0) {605 return true;606 }607 const desiredSize = ReadableByteStreamControllerGetDesiredSize(controller);608 assert(desiredSize !== null);609 if (desiredSize! > 0) {610 return true;611 }612 return false;613}614function ReadableByteStreamControllerClearAlgorithms(controller: ReadableByteStreamController) {615 controller._pullAlgorithm = undefined!;616 controller._cancelAlgorithm = undefined!;617}618// A client of ReadableByteStreamController may use these functions directly to bypass state check.619function ReadableByteStreamControllerClose(controller: ReadableByteStreamController) {620 const stream = controller._controlledReadableByteStream;621 if (controller._closeRequested || stream._state !== 'readable') {622 return;623 }624 if (controller._queueTotalSize > 0) {625 controller._closeRequested = true;626 return;627 }628 if (controller._pendingPullIntos.length > 0) {629 const firstPendingPullInto = controller._pendingPullIntos.peek();630 if (firstPendingPullInto.bytesFilled > 0) {631 const e = new TypeError('Insufficient bytes to fill elements in the given buffer');632 ReadableByteStreamControllerError(controller, e);633 throw e;634 }635 }636 ReadableByteStreamControllerClearAlgorithms(controller);637 ReadableStreamClose(stream);638}639function ReadableByteStreamControllerEnqueue(controller: ReadableByteStreamController, chunk: ArrayBufferView) {640 const stream = controller._controlledReadableByteStream;641 if (controller._closeRequested || stream._state !== 'readable') {642 return;643 }644 const buffer = chunk.buffer;645 const byteOffset = chunk.byteOffset;646 const byteLength = chunk.byteLength;647 const transferredBuffer = TransferArrayBuffer(buffer);648 if (ReadableStreamHasDefaultReader(stream)) {649 if (ReadableStreamGetNumReadRequests(stream) === 0) {650 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);651 } else {652 assert(controller._queue.length === 0);653 const transferredView = new Uint8Array(transferredBuffer, byteOffset, byteLength);654 ReadableStreamFulfillReadRequest(stream, transferredView, false);655 }656 } else if (ReadableStreamHasBYOBReader(stream)) {657 // TODO: Ideally in this branch detaching should happen only if the buffer is not consumed fully.658 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);659 ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);660 } else {661 assert(!IsReadableStreamLocked(stream));662 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);663 }664 ReadableByteStreamControllerCallPullIfNeeded(controller);665}666function ReadableByteStreamControllerError(controller: ReadableByteStreamController, e: any) {667 const stream = controller._controlledReadableByteStream;668 if (stream._state !== 'readable') {669 return;670 }671 ReadableByteStreamControllerClearPendingPullIntos(controller);672 ResetQueue(controller);673 ReadableByteStreamControllerClearAlgorithms(controller);674 ReadableStreamError(stream, e);675}676function ReadableByteStreamControllerGetDesiredSize(controller: ReadableByteStreamController): number | null {677 const stream = controller._controlledReadableByteStream;678 const state = stream._state;679 if (state === 'errored') {680 return null;681 }682 if (state === 'closed') {683 return 0;684 }685 return controller._strategyHWM - controller._queueTotalSize;686}687function ReadableByteStreamControllerRespond(controller: ReadableByteStreamController, bytesWritten: number) {688 bytesWritten = Number(bytesWritten);689 if (!IsFiniteNonNegativeNumber(bytesWritten)) {690 throw new RangeError('bytesWritten must be a finite');691 }692 assert(controller._pendingPullIntos.length > 0);693 ReadableByteStreamControllerRespondInternal(controller, bytesWritten);694}695function ReadableByteStreamControllerRespondWithNewView(controller: ReadableByteStreamController,696 view: ArrayBufferView) {697 assert(controller._pendingPullIntos.length > 0);698 const firstDescriptor = controller._pendingPullIntos.peek();699 if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== view.byteOffset) {700 throw new RangeError('The region specified by view does not match byobRequest');701 }702 if (firstDescriptor.byteLength !== view.byteLength) {703 throw new RangeError('The buffer of view has different capacity than byobRequest');704 }705 firstDescriptor.buffer = view.buffer;706 ReadableByteStreamControllerRespondInternal(controller, view.byteLength);707}708export function SetUpReadableByteStreamController(stream: ReadableByteStream,709 controller: ReadableByteStreamController,710 startAlgorithm: () => void | PromiseLike<void>,711 pullAlgorithm: () => Promise<void>,712 cancelAlgorithm: (reason: any) => Promise<void>,713 highWaterMark: number,714 autoAllocateChunkSize: number | undefined) {715 assert(stream._readableStreamController === undefined);716 if (autoAllocateChunkSize !== undefined) {717 assert(NumberIsInteger(autoAllocateChunkSize));718 assert(autoAllocateChunkSize > 0);719 }720 controller._controlledReadableByteStream = stream;721 controller._pullAgain = false;722 controller._pulling = false;723 controller._byobRequest = null;724 // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly.725 controller._queue = controller._queueTotalSize = undefined!;726 ResetQueue(controller);727 controller._closeRequested = false;728 controller._started = false;729 controller._strategyHWM = highWaterMark;730 controller._pullAlgorithm = pullAlgorithm;731 controller._cancelAlgorithm = cancelAlgorithm;732 controller._autoAllocateChunkSize = autoAllocateChunkSize;733 controller._pendingPullIntos = new SimpleQueue();734 stream._readableStreamController = controller;735 const startResult = startAlgorithm();736 uponPromise(737 promiseResolvedWith(startResult),738 () => {739 controller._started = true;740 assert(!controller._pulling);741 assert(!controller._pullAgain);742 ReadableByteStreamControllerCallPullIfNeeded(controller);743 },744 r => {745 ReadableByteStreamControllerError(controller, r);746 }747 );748}749export function SetUpReadableByteStreamControllerFromUnderlyingSource(750 stream: ReadableByteStream,751 underlyingByteSource: ValidatedUnderlyingByteSource,752 highWaterMark: number753) {754 const controller: ReadableByteStreamController = Object.create(ReadableByteStreamController.prototype);755 let startAlgorithm: () => void | PromiseLike<void> = () => undefined;756 let pullAlgorithm: () => Promise<void> = () => promiseResolvedWith(undefined);757 let cancelAlgorithm: (reason: any) => Promise<void> = () => promiseResolvedWith(undefined);758 if (underlyingByteSource.start !== undefined) {759 startAlgorithm = () => underlyingByteSource.start!(controller);760 }761 if (underlyingByteSource.pull !== undefined) {762 pullAlgorithm = () => underlyingByteSource.pull!(controller);763 }764 if (underlyingByteSource.cancel !== undefined) {765 cancelAlgorithm = reason => underlyingByteSource.cancel!(reason);766 }767 const autoAllocateChunkSize = underlyingByteSource.autoAllocateChunkSize;768 SetUpReadableByteStreamController(769 stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize770 );771}772function SetUpReadableStreamBYOBRequest(request: ReadableStreamBYOBRequest,773 controller: ReadableByteStreamController,774 view: ArrayBufferView) {775 assert(IsReadableByteStreamController(controller));776 assert(typeof view === 'object');777 assert(ArrayBuffer.isView(view));778 assert(!IsDetachedBuffer(view.buffer));779 request._associatedReadableByteStreamController = controller;780 request._view = view;781}782// Helper functions for the ReadableStreamBYOBRequest.783function byobRequestBrandCheckException(name: string): TypeError {784 return new TypeError(785 `ReadableStreamBYOBRequest.prototype.${name} can only be used on a ReadableStreamBYOBRequest`);786}787// Helper functions for the ReadableByteStreamController.788function byteStreamControllerBrandCheckException(name: string): TypeError {789 return new TypeError(790 `ReadableByteStreamController.prototype.${name} can only be used on a ReadableByteStreamController`);...
Using AI Code Generation
1wptb.byobRequestBrandCheckException();2wptb.byobRequestBrandCheckException();3wptb.byobRequestBrandCheckException();4wptb.byobRequestBrandCheckException();5wptb.byobRequestBrandCheckException();6wptb.byobRequestBrandCheckException();7wptb.byobRequestBrandCheckException();8wptb.byobRequestBrandCheckException();9wptb.byobRequestBrandCheckException();10wptb.byobRequestBrandCheckException();11wptb.byobRequestBrandCheckException();12wptb.byobRequestBrandCheckException();13wptb.byobRequestBrandCheckException();14wptb.byobRequestBrandCheckException();15wptb.byobRequestBrandCheckException();16wptb.byobRequestBrandCheckException();17wptb.byobRequestBrandCheckException();18wptb.byobRequestBrandCheckException();
Using AI Code Generation
1var wpt = new Worker('worker.js');2wpt.onmessage = function(e) {3 postMessage(e.data);4}5wpt.postMessage({type: 'byobRequestBrandCheckException'});6self.onmessage = function(e) {7 if (e.data.type == 'byobRequestBrandCheckException') {8 var ab = new ArrayBuffer(1);9 var u8a = new Uint8Array(ab);10 var byobRequest = new ReadableStream().getReader({mode: 'byob'}).read(u8a);11 try {12 byobRequest.constructor.prototype.constructor = 1;13 } catch (e) {14 postMessage("pass");15 }16 }17}
Using AI Code Generation
1var byobRequestBrandCheckException = function() {2 var r = new ReadableStream({3 pull(controller) {4 return controller.byobRequest;5 }6 });7 var reader = r.getReader({mode: "byob"});8 reader.read(new Uint8Array(1));9}10byobRequestBrandCheckException();
Using AI Code Generation
1function testBrandCheckException() {2 var request = new BYOBRequest();3 var view = new Uint8Array(8);4 request.view = view;5 request.byobRequestBrandCheckException();6}7 testBrandCheckException();
Using AI Code Generation
1var wpt = new WebPageTest('www.webpagetest.org');2wpt.byobRequestBrandCheckException('www.webpagetest.org', 'TestBrandCheckException', function(err, data) {3 if (err) return console.log(err);4 console.log(data);5});6var wpt = new WebPageTest('www.webpagetest.org');7wpt.byobRequestBrandCheckException('www.webpagetest.org', 'TestBrandCheckException', function(err, data) {8 if (err) return console.log(err);9 console.log(data);10});11var wpt = new WebPageTest('www.webpagetest.org');12wpt.byobRequestBrandCheckException('www.webpagetest.org', 'TestBrandCheckException', function(err, data) {13 if (err) return console.log(err);14 console.log(data);15});16var wpt = new WebPageTest('www.webpagetest.org');17wpt.byobRequestBrandCheckException('www.webpagetest.org', 'TestBrandCheckException', function(err, data) {18 if (err) return console.log(err);19 console.log(data);20});21var wpt = new WebPageTest('www.webpagetest.org');22wpt.byobRequestBrandCheckException('www.webpagetest.org', 'TestBrandCheckException', function(err, data) {23 if (err) return console.log(err);24 console.log(data);25});26var wpt = new WebPageTest('www.webpagetest.org');27wpt.byobRequestBrandCheckException('www.webpagetest.org', 'TestBrandCheckException', function(err, data) {28 if (err) return console.log(err);29 console.log(data);30});31var wpt = new WebPageTest('www.webpagetest.org');32wpt.byobRequestBrandCheckException('
Using AI Code Generation
1var brandCheck = new XMLHttpRequest();2brandCheck.send();3brandCheck.onreadystatechange = function() {4 if (brandCheck.readyState == 4 && brandCheck.status == 200) {5 var brand = brandCheck.responseText;6 var brandCheck2 = new XMLHttpRequest();7 brandCheck2.send();8 brandCheck2.onreadystatechange = function() {9 if (brandCheck2.readyState == 4 && brandCheck2.status == 200) {10 var brand2 = brandCheck2.responseText;11 if (brand != brand2) {12 document.getElementById("result").innerHTML = "PASS";13 }14 }15 }16 }17}18import os19import sys20import urlparse21import wptserve22def main(request, response):23 url_parts = urlparse.urlparse(request.url)24 query = urlparse.parse_qs(url_parts.query)25 brand = query.get("brand")[0]26 request.server.stash.take("brand")27 request.server.stash.put("brand", brand)28 response.headers.set("Content-Type", "text/html")29import os30import sys31import urlparse32import wptserve33def main(request, response):34 url_parts = urlparse.urlparse(request.url)35 query = urlparse.parse_qs(url_parts.query)36 brand = query.get("brand")[0]37 request.server.stash.take("brand")38 request.server.stash.put("brand", brand)39 response.headers.set("Content-Type", "text/html")40import os41import sys42import urlparse43import wptserve44def main(request, response):45 url_parts = urlparse.urlparse(request.url)46 query = urlparse.parse_qs(url_parts.query)47 brand = query.get("brand")[0]48 request.server.stash.take("brand")49 request.server.stash.put("brand", brand)50 response.headers.set("Content-Type", "text/html")51import os52import sys53import urlparse54import wptserve55def main(request, response):
Using AI Code Generation
1var byobRequest = new Uint8Array(1).buffer;2var writer = new WritableStream().getWriter({type: 'byob'});3writer.write(byobRequest).then(function() {4 test(function() {5 assert_unreached('write() should reject');6 }, 'write() should reject');7}, function(error) {8 test(function() {9 assert_equals(error.name, 'TypeError', 'error should be a TypeError');10 }, 'error should be a TypeError');11});12var byobRequest = new Uint8Array(1).buffer;13var writer = new WritableStream().getWriter({type: 'byob'});14writer.write(byobRequest).then(function() {15 test(function() {16 assert_unreached('write() should reject');17 }, 'write() should reject');18}, function(error) {19 test(function() {20 assert_equals(error.name, 'TypeError', 'error should be a TypeError');21 }, 'error should be a TypeError');22});23var byobRequest = new Uint8Array(1).buffer;24var writer = new WritableStream().getWriter({type: 'byob'});25writer.write(byobRequest).then(function() {26 test(function() {27 assert_unreached('write() should reject');28 }, 'write() should reject');29}, function(error) {30 test(function() {31 assert_equals(error.name, 'TypeError', 'error should be a TypeError');32 }, 'error should be a TypeError');33});34var byobRequest = new Uint8Array(1).buffer;35var writer = new WritableStream().getWriter({type: 'byob'});36writer.write(byobRequest).then(function() {37 test(function
Using AI Code Generation
1var wpt = new Worker("worker.js");2wpt.postMessage({type:"brandCheckException"});3wpt.onmessage = function(event) {4 var result = event.data;5 if (result === "pass")6 postMessage("pass");7 postMessage("fail");8}9var brandCheckException = function() {10 var ab = new ArrayBuffer(16);11 var dv = new DataView(ab);12 dv.setUint8(0, 1);13}14var wpt;15onmessage = function(event) {16 var data = event.data;17 if (data.type === "brandCheckException") {18 wpt = new Worker("worker.js");19 wpt.postMessage({type:"brandCheckException"});20 wpt.onmessage = function(event) {21 var result = event.data;22 if (result === "pass")23 postMessage("pass");24 postMessage("fail");25 }26 } else if (data.type === "brandCheckException") {27 try {28 brandCheckException();29 postMessage("fail");30 } catch (e) {31 if (e instanceof TypeError)32 postMessage("pass");33 postMessage("fail");34 }35 }36}37 > + var ab = new ArrayBuffer(16);38> + var dv = new DataView(ab);39> + dv.setUint8(0, 1);40> +}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!