Skip to content

Commit 54d8c5e

Browse files
committed
Add an abstract BasePDFStreamReader class, that all the old IPDFStreamReader implementations inherit from
Given that there's no less than *five* different, but very similar, implementations this helps reduce code duplication and simplifies maintenance. Also, remove the `rangeChunkSize` not defined checks in all the relevant stream-constructor implementations. Note how the API, since some time, always validates *and* provides that parameter when creating a `BasePDFStreamReader`-instance.
1 parent 4a8fb4d commit 54d8c5e

File tree

7 files changed

+182
-267
lines changed

7 files changed

+182
-267
lines changed

src/core/worker_stream.js

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,50 +13,34 @@
1313
* limitations under the License.
1414
*/
1515

16-
import { BasePDFStream } from "../shared/base_pdf_stream.js";
16+
import {
17+
BasePDFStream,
18+
BasePDFStreamReader,
19+
} from "../shared/base_pdf_stream.js";
1720

1821
class PDFWorkerStream extends BasePDFStream {
1922
constructor(source) {
2023
super(source, PDFWorkerStreamReader, PDFWorkerStreamRangeReader);
2124
}
2225
}
2326

24-
/** @implements {IPDFStreamReader} */
25-
class PDFWorkerStreamReader {
27+
class PDFWorkerStreamReader extends BasePDFStreamReader {
28+
_reader = null;
29+
2630
constructor(stream) {
31+
super(stream);
2732
const { msgHandler } = stream._source;
28-
this.onProgress = null;
29-
30-
this._contentLength = null;
31-
this._isRangeSupported = false;
32-
this._isStreamingSupported = false;
3333

3434
const readableStream = msgHandler.sendWithStream("GetReader");
3535
this._reader = readableStream.getReader();
3636

37-
this._headersReady = msgHandler
38-
.sendWithPromise("ReaderHeadersReady")
39-
.then(data => {
40-
this._isStreamingSupported = data.isStreamingSupported;
41-
this._isRangeSupported = data.isRangeSupported;
42-
this._contentLength = data.contentLength;
43-
});
44-
}
45-
46-
get headersReady() {
47-
return this._headersReady;
48-
}
49-
50-
get contentLength() {
51-
return this._contentLength;
52-
}
53-
54-
get isStreamingSupported() {
55-
return this._isStreamingSupported;
56-
}
37+
msgHandler.sendWithPromise("ReaderHeadersReady").then(data => {
38+
this._contentLength = data.contentLength;
39+
this._isStreamingSupported = data.isStreamingSupported;
40+
this._isRangeSupported = data.isRangeSupported;
5741

58-
get isRangeSupported() {
59-
return this._isRangeSupported;
42+
this._headersCapability.resolve();
43+
}, this._headersCapability.reject);
6044
}
6145

6246
async read() {

src/display/fetch_stream.js

Lines changed: 30 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
*/
1515

1616
import { AbortException, warn } from "../shared/util.js";
17+
import {
18+
BasePDFStream,
19+
BasePDFStreamReader,
20+
} from "../shared/base_pdf_stream.js";
1721
import {
1822
createHeaders,
1923
createResponseError,
@@ -22,23 +26,22 @@ import {
2226
validateRangeRequestCapabilities,
2327
validateResponseStatus,
2428
} from "./network_utils.js";
25-
import { BasePDFStream } from "../shared/base_pdf_stream.js";
2629

2730
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
2831
throw new Error(
2932
'Module "./fetch_stream.js" shall not be used with MOZCENTRAL builds.'
3033
);
3134
}
3235

33-
function createFetchOptions(headers, withCredentials, abortController) {
34-
return {
36+
function fetchUrl(url, headers, withCredentials, abortController) {
37+
return fetch(url, {
3538
method: "GET",
3639
headers,
3740
signal: abortController.signal,
3841
mode: "cors",
3942
credentials: withCredentials ? "include" : "same-origin",
4043
redirect: "follow",
41-
};
44+
});
4245
}
4346

4447
function getArrayBuffer(val) {
@@ -62,51 +65,45 @@ class PDFFetchStream extends BasePDFStream {
6265
}
6366
}
6467

65-
/** @implements {IPDFStreamReader} */
66-
class PDFFetchStreamReader {
68+
class PDFFetchStreamReader extends BasePDFStreamReader {
69+
_abortController = new AbortController();
70+
71+
_reader = null;
72+
6773
constructor(stream) {
68-
this._stream = stream;
69-
this._reader = null;
70-
this._loaded = 0;
71-
this._filename = null;
72-
const source = stream._source;
73-
this._withCredentials = source.withCredentials || false;
74-
this._contentLength = source.length;
75-
this._headersCapability = Promise.withResolvers();
76-
this._disableRange = source.disableRange || false;
77-
this._rangeChunkSize = source.rangeChunkSize;
78-
if (!this._rangeChunkSize && !this._disableRange) {
79-
this._disableRange = true;
80-
}
74+
super(stream);
75+
const {
76+
disableRange,
77+
disableStream,
78+
length,
79+
rangeChunkSize,
80+
url,
81+
withCredentials,
82+
} = stream._source;
8183

82-
this._abortController = new AbortController();
83-
this._isStreamingSupported = !source.disableStream;
84-
this._isRangeSupported = !source.disableRange;
84+
this._contentLength = length;
85+
this._isStreamingSupported = !disableStream;
86+
this._isRangeSupported = !disableRange;
8587
// Always create a copy of the headers.
8688
const headers = new Headers(stream.headers);
8789

88-
const url = source.url;
89-
fetch(
90-
url,
91-
createFetchOptions(headers, this._withCredentials, this._abortController)
92-
)
90+
fetchUrl(url, headers, withCredentials, this._abortController)
9391
.then(response => {
9492
stream._responseOrigin = getResponseOrigin(response.url);
9593

9694
if (!validateResponseStatus(response.status)) {
9795
throw createResponseError(response.status, url);
9896
}
9997
this._reader = response.body.getReader();
100-
this._headersCapability.resolve();
10198

10299
const responseHeaders = response.headers;
103100

104101
const { allowRangeRequests, suggestedLength } =
105102
validateRangeRequestCapabilities({
106103
responseHeaders,
107104
isHttp: stream.isHttp,
108-
rangeChunkSize: this._rangeChunkSize,
109-
disableRange: this._disableRange,
105+
rangeChunkSize,
106+
disableRange,
110107
});
111108

112109
this._isRangeSupported = allowRangeRequests;
@@ -120,30 +117,10 @@ class PDFFetchStreamReader {
120117
if (!this._isStreamingSupported && this._isRangeSupported) {
121118
this.cancel(new AbortException("Streaming is disabled."));
122119
}
120+
121+
this._headersCapability.resolve();
123122
})
124123
.catch(this._headersCapability.reject);
125-
126-
this.onProgress = null;
127-
}
128-
129-
get headersReady() {
130-
return this._headersCapability.promise;
131-
}
132-
133-
get filename() {
134-
return this._filename;
135-
}
136-
137-
get contentLength() {
138-
return this._contentLength;
139-
}
140-
141-
get isRangeSupported() {
142-
return this._isRangeSupported;
143-
}
144-
145-
get isStreamingSupported() {
146-
return this._isStreamingSupported;
147124
}
148125

149126
async read() {
@@ -182,10 +159,7 @@ class PDFFetchStreamRangeReader {
182159
headers.append("Range", `bytes=${begin}-${end - 1}`);
183160

184161
const url = source.url;
185-
fetch(
186-
url,
187-
createFetchOptions(headers, this._withCredentials, this._abortController)
188-
)
162+
fetchUrl(url, headers, this._withCredentials, this._abortController)
189163
.then(response => {
190164
const responseOrigin = getResponseOrigin(response.url);
191165

0 commit comments

Comments
 (0)