UNPKG

4.19 kBJavaScriptView Raw
1/**
2 * @licstart The following is the entire license notice for the
3 * JavaScript code in this page
4 *
5 * Copyright 2022 Mozilla Foundation
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * @licend The above is the entire license notice for the
20 * JavaScript code in this page
21 */
22"use strict";
23
24Object.defineProperty(exports, "__esModule", {
25 value: true
26});
27exports.ObjectLoader = void 0;
28
29var _primitives = require("./primitives.js");
30
31var _base_stream = require("./base_stream.js");
32
33var _core_utils = require("./core_utils.js");
34
35var _util = require("../shared/util.js");
36
37function mayHaveChildren(value) {
38 return value instanceof _primitives.Ref || value instanceof _primitives.Dict || value instanceof _base_stream.BaseStream || Array.isArray(value);
39}
40
41function addChildren(node, nodesToVisit) {
42 if (node instanceof _primitives.Dict) {
43 node = node.getRawValues();
44 } else if (node instanceof _base_stream.BaseStream) {
45 node = node.dict.getRawValues();
46 } else if (!Array.isArray(node)) {
47 return;
48 }
49
50 for (const rawValue of node) {
51 if (mayHaveChildren(rawValue)) {
52 nodesToVisit.push(rawValue);
53 }
54 }
55}
56
57class ObjectLoader {
58 constructor(dict, keys, xref) {
59 this.dict = dict;
60 this.keys = keys;
61 this.xref = xref;
62 this.refSet = null;
63 }
64
65 async load() {
66 if (this.xref.stream.isDataLoaded) {
67 return undefined;
68 }
69
70 const {
71 keys,
72 dict
73 } = this;
74 this.refSet = new _primitives.RefSet();
75 const nodesToVisit = [];
76
77 for (let i = 0, ii = keys.length; i < ii; i++) {
78 const rawValue = dict.getRaw(keys[i]);
79
80 if (rawValue !== undefined) {
81 nodesToVisit.push(rawValue);
82 }
83 }
84
85 return this._walk(nodesToVisit);
86 }
87
88 async _walk(nodesToVisit) {
89 const nodesToRevisit = [];
90 const pendingRequests = [];
91
92 while (nodesToVisit.length) {
93 let currentNode = nodesToVisit.pop();
94
95 if (currentNode instanceof _primitives.Ref) {
96 if (this.refSet.has(currentNode)) {
97 continue;
98 }
99
100 try {
101 this.refSet.put(currentNode);
102 currentNode = this.xref.fetch(currentNode);
103 } catch (ex) {
104 if (!(ex instanceof _core_utils.MissingDataException)) {
105 (0, _util.warn)(`ObjectLoader._walk - requesting all data: "${ex}".`);
106 this.refSet = null;
107 const {
108 manager
109 } = this.xref.stream;
110 return manager.requestAllChunks();
111 }
112
113 nodesToRevisit.push(currentNode);
114 pendingRequests.push({
115 begin: ex.begin,
116 end: ex.end
117 });
118 }
119 }
120
121 if (currentNode instanceof _base_stream.BaseStream) {
122 const baseStreams = currentNode.getBaseStreams();
123
124 if (baseStreams) {
125 let foundMissingData = false;
126
127 for (const stream of baseStreams) {
128 if (stream.isDataLoaded) {
129 continue;
130 }
131
132 foundMissingData = true;
133 pendingRequests.push({
134 begin: stream.start,
135 end: stream.end
136 });
137 }
138
139 if (foundMissingData) {
140 nodesToRevisit.push(currentNode);
141 }
142 }
143 }
144
145 addChildren(currentNode, nodesToVisit);
146 }
147
148 if (pendingRequests.length) {
149 await this.xref.stream.manager.requestRanges(pendingRequests);
150
151 for (const node of nodesToRevisit) {
152 if (node instanceof _primitives.Ref) {
153 this.refSet.remove(node);
154 }
155 }
156
157 return this._walk(nodesToRevisit);
158 }
159
160 this.refSet = null;
161 return undefined;
162 }
163
164}
165
166exports.ObjectLoader = ObjectLoader;
\No newline at end of file