(reader)
| 441 | } |
| 442 | |
| 443 | function createBlobReaderStream(reader) { |
| 444 | return new lazyReadableStream({ |
| 445 | type: 'bytes', |
| 446 | start(c) { |
| 447 | // There really should only be one read at a time so using an |
| 448 | // array here is purely defensive. |
| 449 | this.pendingPulls = []; |
| 450 | // Register a wakeup callback that the C++ side can invoke |
| 451 | // when new data is available after a STATUS_BLOCK. |
| 452 | reader.setWakeup(() => { |
| 453 | if (this.pendingPulls.length > 0) { |
| 454 | this.readNext(c); |
| 455 | } |
| 456 | }); |
| 457 | }, |
| 458 | pull(c) { |
| 459 | const { promise, resolve, reject } = PromiseWithResolvers(); |
| 460 | this.pendingPulls.push({ resolve, reject }); |
| 461 | this.readNext(c); |
| 462 | return promise; |
| 463 | }, |
| 464 | readNext(c) { |
| 465 | reader.pull((status, buffer) => { |
| 466 | // If pendingPulls is empty here, the stream had to have |
| 467 | // been canceled, and we don't really care about the result. |
| 468 | // We can simply exit. |
| 469 | if (this.pendingPulls.length === 0) { |
| 470 | return; |
| 471 | } |
| 472 | if (status === 0) { |
| 473 | // EOS |
| 474 | c.close(); |
| 475 | // This is to signal the end for byob readers |
| 476 | // see https://streams.spec.whatwg.org/#example-rbs-pull |
| 477 | c.byobRequest?.respond(0); |
| 478 | const pending = this.pendingPulls.shift(); |
| 479 | pending.resolve(); |
| 480 | return; |
| 481 | } else if (status < 0) { |
| 482 | // The read could fail for many different reasons when reading |
| 483 | // from a non-memory resident blob part (e.g. file-backed blob). |
| 484 | // The error details the system error code. |
| 485 | const error = |
| 486 | lazyDOMException('The blob could not be read', |
| 487 | 'NotReadableError'); |
| 488 | const pending = this.pendingPulls.shift(); |
| 489 | c.error(error); |
| 490 | pending.reject(error); |
| 491 | return; |
| 492 | } else if (status === 2) { |
| 493 | // STATUS_BLOCK: No data available yet. The wakeup callback |
| 494 | // registered in start() will re-invoke readNext when data |
| 495 | // arrives. |
| 496 | return; |
| 497 | } |
| 498 | // ReadableByteStreamController.enqueue errors if we submit a |
| 499 | // 0-length buffer. We need to check for that here. |
| 500 | if (buffer !== undefined && buffer.byteLength !== 0) { |
no outgoing calls
no test coverage detected
searching dependent graphs…