(view, forBranch2)
| 1175 | ReadableStreamDefaultReaderRead(reader, readRequest); |
| 1176 | } |
| 1177 | function pullWithBYOBReader(view, forBranch2) { |
| 1178 | if (ReadableStreamDefaultReaderBrand.has(reader.self)) { |
| 1179 | assert(reader.readRequests.length === 0); |
| 1180 | ReadableStreamDefaultReaderRelease(reader); |
| 1181 | reader = AcquireReadableStreamBYOBReader(stream); |
| 1182 | forwardReaderError(reader); |
| 1183 | } |
| 1184 | const byobBranch = forBranch2 ? branch2 : branch1; |
| 1185 | const otherBranch = forBranch2 ? branch1 : branch2; |
| 1186 | const readIntoRequest = { |
| 1187 | chunkSteps: chunk => { |
| 1188 | // This needs to be delayed a microtask because it takes at least a microtask to detect errors (using |
| 1189 | // reader.closedPromise below), and we want errors in stream to error both branches immediately. We cannot let |
| 1190 | // successful synchronously-available reads get ahead of asynchronously-available errors. |
| 1191 | queueMicrotask(() => { |
| 1192 | readAgainForBranch1 = false; |
| 1193 | readAgainForBranch2 = false; |
| 1194 | const byobCanceled = forBranch2 ? canceled2 : canceled1; |
| 1195 | const otherCanceled = forBranch2 ? canceled1 : canceled2; |
| 1196 | if (otherCanceled === false) { |
| 1197 | let clonedChunk; |
| 1198 | try { |
| 1199 | clonedChunk = CloneAsUint8Array(chunk); |
| 1200 | } |
| 1201 | catch (e) { |
| 1202 | ReadableByteStreamControllerError(byobBranch.controller, e); |
| 1203 | ReadableByteStreamControllerError(otherBranch.controller, e); |
| 1204 | cancelPromise.resolvePromise(ReadableStreamCancel(stream, e)); |
| 1205 | return; |
| 1206 | } |
| 1207 | if (byobCanceled === false) { |
| 1208 | ReadableByteStreamControllerRespondWithNewView(byobBranch.controller, chunk); |
| 1209 | } |
| 1210 | ReadableByteStreamControllerEnqueue(otherBranch.controller, clonedChunk); |
| 1211 | } |
| 1212 | else if (byobCanceled === false) { |
| 1213 | ReadableByteStreamControllerRespondWithNewView(byobBranch.controller, chunk); |
| 1214 | } |
| 1215 | reading = false; |
| 1216 | if (readAgainForBranch1 === true) { |
| 1217 | pull1Algorithm(); |
| 1218 | } |
| 1219 | else if (readAgainForBranch2 === true) { |
| 1220 | pull2Algorithm(); |
| 1221 | } |
| 1222 | }); |
| 1223 | }, |
| 1224 | closeSteps: chunk => { |
| 1225 | reading = false; |
| 1226 | const byobCanceled = forBranch2 ? canceled2 : canceled1; |
| 1227 | const otherCanceled = forBranch2 ? canceled1 : canceled2; |
| 1228 | if (byobCanceled === false) { |
| 1229 | ReadableByteStreamControllerClose(byobBranch.controller); |
| 1230 | } |
| 1231 | if (otherCanceled === false) { |
| 1232 | ReadableByteStreamControllerClose(otherBranch.controller); |
| 1233 | } |
| 1234 | if (chunk !== undefined) { |
no test coverage detected