From 62d5408cf0d7b14d796d1fe16de02c31adc7e07d Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Fri, 30 Jan 2026 07:55:27 +0100 Subject: [PATCH] Stop tracking `progressiveDataLength` in the `ChunkedStreamManager` class Currently this property is essentially "duplicated", so let's instead use the identical one that's availble on the `ChunkedStream` instance. --- src/core/chunked_stream.js | 66 ++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/src/core/chunked_stream.js b/src/core/chunked_stream.js index c77f62531..eaa13e29c 100644 --- a/src/core/chunked_stream.js +++ b/src/core/chunked_stream.js @@ -18,6 +18,12 @@ import { assert } from "../shared/util.js"; import { Stream } from "./stream.js"; class ChunkedStream extends Stream { + progressiveDataLength = 0; + + _lastSuccessfulEnsureByteChunk = -1; // Single-entry cache + + _loadedChunks = new Set(); + constructor(length, chunkSize, manager) { super( /* arrayBuffer = */ new Uint8Array(length), @@ -27,11 +33,8 @@ class ChunkedStream extends Stream { ); this.chunkSize = chunkSize; - this._loadedChunks = new Set(); this.numChunks = Math.ceil(length / chunkSize); this.manager = manager; - this.progressiveDataLength = 0; - this.lastSuccessfulEnsureByteChunk = -1; // Single-entry cache } // If a particular stream does not implement one or more of these methods, @@ -106,14 +109,14 @@ class ChunkedStream extends Stream { if (chunk > this.numChunks) { return; } - if (chunk === this.lastSuccessfulEnsureByteChunk) { + if (chunk === this._lastSuccessfulEnsureByteChunk) { return; } if (!this._loadedChunks.has(chunk)) { throw new MissingDataException(pos, pos + 1); } - this.lastSuccessfulEnsureByteChunk = chunk; + this._lastSuccessfulEnsureByteChunk = chunk; } ensureRange(begin, end) { @@ -257,6 +260,18 @@ class ChunkedStream extends Stream { } class ChunkedStreamManager { + aborted = false; + + currRequestId = 0; + + _chunksNeededByRequest = new Map(); + + _loadedStreamCapability = Promise.withResolvers(); + + _promisesByRequest = new Map(); + + _requestsByChunk = new Map(); + constructor(pdfNetworkStream, args) { this.length = args.length; this.chunkSize = args.rangeChunkSize; @@ -264,16 +279,6 @@ class ChunkedStreamManager { this.pdfNetworkStream = pdfNetworkStream; this.disableAutoFetch = args.disableAutoFetch; this.msgHandler = args.msgHandler; - - this.currRequestId = 0; - - this._chunksNeededByRequest = new Map(); - this._requestsByChunk = new Map(); - this._promisesByRequest = new Map(); - this.progressiveDataLength = 0; - this.aborted = false; - - this._loadedStreamCapability = Promise.withResolvers(); } sendRequest(begin, end) { @@ -454,26 +459,25 @@ class ChunkedStreamManager { } onReceiveData(args) { + const { chunkSize, length, stream } = this; + const chunk = args.chunk; const isProgressive = args.begin === undefined; - const begin = isProgressive ? this.progressiveDataLength : args.begin; + const begin = isProgressive ? stream.progressiveDataLength : args.begin; const end = begin + chunk.byteLength; - const beginChunk = Math.floor(begin / this.chunkSize); + const beginChunk = Math.floor(begin / chunkSize); const endChunk = - end < this.length - ? Math.floor(end / this.chunkSize) - : Math.ceil(end / this.chunkSize); + end < length ? Math.floor(end / chunkSize) : Math.ceil(end / chunkSize); if (isProgressive) { - this.stream.onReceiveProgressiveData(chunk); - this.progressiveDataLength = end; + stream.onReceiveProgressiveData(chunk); } else { - this.stream.onReceiveData(begin, chunk); + stream.onReceiveData(begin, chunk); } - if (this.stream.isDataLoaded) { - this._loadedStreamCapability.resolve(this.stream); + if (stream.isDataLoaded) { + this._loadedStreamCapability.resolve(stream); } const loadedRequests = []; @@ -502,16 +506,16 @@ class ChunkedStreamManager { // unfetched chunk of the PDF file. if (!this.disableAutoFetch && this._requestsByChunk.size === 0) { let nextEmptyChunk; - if (this.stream.numChunksLoaded === 1) { + if (stream.numChunksLoaded === 1) { // This is a special optimization so that after fetching the first // chunk, rather than fetching the second chunk, we fetch the last // chunk. - const lastChunk = this.stream.numChunks - 1; - if (!this.stream.hasChunk(lastChunk)) { + const lastChunk = stream.numChunks - 1; + if (!stream.hasChunk(lastChunk)) { nextEmptyChunk = lastChunk; } } else { - nextEmptyChunk = this.stream.nextEmptyChunk(endChunk); + nextEmptyChunk = stream.nextEmptyChunk(endChunk); } if (Number.isInteger(nextEmptyChunk)) { this._requestChunks([nextEmptyChunk]); @@ -525,8 +529,8 @@ class ChunkedStreamManager { } this.msgHandler.send("DocProgress", { - loaded: this.stream.numChunksLoaded * this.chunkSize, - total: this.length, + loaded: stream.numChunksLoaded * chunkSize, + total: length, }); }