/** * @licstart The following is the entire license notice for the * Javascript code in this page * * Copyright 2021 Mozilla Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @licend The above is the entire license notice for the * Javascript code in this page */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ObjectLoader = void 0; var _primitives = require("./primitives.js"); var _core_utils = require("./core_utils.js"); var _util = require("../shared/util.js"); function mayHaveChildren(value) { return value instanceof _primitives.Ref || value instanceof _primitives.Dict || Array.isArray(value) || (0, _primitives.isStream)(value); } function addChildren(node, nodesToVisit) { if (node instanceof _primitives.Dict) { node = node.getRawValues(); } else if ((0, _primitives.isStream)(node)) { node = node.dict.getRawValues(); } else if (!Array.isArray(node)) { return; } for (const rawValue of node) { if (mayHaveChildren(rawValue)) { nodesToVisit.push(rawValue); } } } class ObjectLoader { constructor(dict, keys, xref) { this.dict = dict; this.keys = keys; this.xref = xref; this.refSet = null; } async load() { if (this.xref.stream.isDataLoaded) { return undefined; } const { keys, dict } = this; this.refSet = new _primitives.RefSet(); const nodesToVisit = []; for (let i = 0, ii = keys.length; i < ii; i++) { const rawValue = dict.getRaw(keys[i]); if (rawValue !== undefined) { nodesToVisit.push(rawValue); } } return this._walk(nodesToVisit); } async _walk(nodesToVisit) { const nodesToRevisit = []; const pendingRequests = []; while (nodesToVisit.length) { let currentNode = nodesToVisit.pop(); if (currentNode instanceof _primitives.Ref) { if (this.refSet.has(currentNode)) { continue; } try { this.refSet.put(currentNode); currentNode = this.xref.fetch(currentNode); } catch (ex) { if (!(ex instanceof _core_utils.MissingDataException)) { (0, _util.warn)(`ObjectLoader._walk - requesting all data: "${ex}".`); this.refSet = null; const { manager } = this.xref.stream; return manager.requestAllChunks(); } nodesToRevisit.push(currentNode); pendingRequests.push({ begin: ex.begin, end: ex.end }); } } if ((0, _primitives.isStream)(currentNode)) { const baseStreams = currentNode.getBaseStreams(); if (baseStreams) { let foundMissingData = false; for (const stream of baseStreams) { if (stream.isDataLoaded) { continue; } foundMissingData = true; pendingRequests.push({ begin: stream.start, end: stream.end }); } if (foundMissingData) { nodesToRevisit.push(currentNode); } } } addChildren(currentNode, nodesToVisit); } if (pendingRequests.length) { await this.xref.stream.manager.requestRanges(pendingRequests); for (const node of nodesToRevisit) { if (node instanceof _primitives.Ref) { this.refSet.remove(node); } } return this._walk(nodesToRevisit); } this.refSet = null; return undefined; } } exports.ObjectLoader = ObjectLoader;