1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | "use strict";
|
23 |
|
24 | Object.defineProperty(exports, "__esModule", {
|
25 | value: true
|
26 | });
|
27 | exports.ObjectLoader = void 0;
|
28 |
|
29 | var _primitives = require("./primitives.js");
|
30 |
|
31 | var _base_stream = require("./base_stream.js");
|
32 |
|
33 | var _core_utils = require("./core_utils.js");
|
34 |
|
35 | var _util = require("../shared/util.js");
|
36 |
|
37 | function mayHaveChildren(value) {
|
38 | return value instanceof _primitives.Ref || value instanceof _primitives.Dict || value instanceof _base_stream.BaseStream || Array.isArray(value);
|
39 | }
|
40 |
|
41 | function 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 |
|
57 | class 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 |
|
166 | exports.ObjectLoader = ObjectLoader; |
\ | No newline at end of file |