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.FileSpec = exports.XRef = exports.ObjectLoader = exports.Catalog = void 0;
|
28 |
|
29 | var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
30 |
|
31 | var _util = require("../shared/util");
|
32 |
|
33 | var _primitives = require("./primitives");
|
34 |
|
35 | var _parser = require("./parser");
|
36 |
|
37 | var _chunked_stream = require("./chunked_stream");
|
38 |
|
39 | var _crypto = require("./crypto");
|
40 |
|
41 | var _colorspace = require("./colorspace");
|
42 |
|
43 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
44 |
|
45 | function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
|
46 |
|
47 | function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
48 |
|
49 | function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
50 |
|
51 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
52 |
|
53 | function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
54 |
|
55 | function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
56 |
|
57 | function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
58 |
|
59 | function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
|
60 |
|
61 | function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
62 |
|
63 | function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
64 |
|
65 | function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
66 |
|
67 | function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
68 |
|
69 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
70 |
|
71 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
72 |
|
73 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
74 |
|
75 | function fetchDestination(dest) {
|
76 | return (0, _primitives.isDict)(dest) ? dest.get('D') : dest;
|
77 | }
|
78 |
|
79 | var Catalog =
|
80 |
|
81 | function () {
|
82 | function Catalog(pdfManager, xref) {
|
83 | _classCallCheck(this, Catalog);
|
84 |
|
85 | this.pdfManager = pdfManager;
|
86 | this.xref = xref;
|
87 | this.catDict = xref.getCatalogObj();
|
88 |
|
89 | if (!(0, _primitives.isDict)(this.catDict)) {
|
90 | throw new _util.FormatError('Catalog object is not a dictionary.');
|
91 | }
|
92 |
|
93 | this.fontCache = new _primitives.RefSetCache();
|
94 | this.builtInCMapCache = new Map();
|
95 | this.pageKidsCountCache = new _primitives.RefSetCache();
|
96 | }
|
97 |
|
98 | _createClass(Catalog, [{
|
99 | key: "_readDocumentOutline",
|
100 | value: function _readDocumentOutline() {
|
101 | var obj = this.catDict.get('Outlines');
|
102 |
|
103 | if (!(0, _primitives.isDict)(obj)) {
|
104 | return null;
|
105 | }
|
106 |
|
107 | obj = obj.getRaw('First');
|
108 |
|
109 | if (!(0, _primitives.isRef)(obj)) {
|
110 | return null;
|
111 | }
|
112 |
|
113 | var root = {
|
114 | items: []
|
115 | };
|
116 | var queue = [{
|
117 | obj: obj,
|
118 | parent: root
|
119 | }];
|
120 | var processed = new _primitives.RefSet();
|
121 | processed.put(obj);
|
122 | var xref = this.xref,
|
123 | blackColor = new Uint8ClampedArray(3);
|
124 |
|
125 | while (queue.length > 0) {
|
126 | var i = queue.shift();
|
127 | var outlineDict = xref.fetchIfRef(i.obj);
|
128 |
|
129 | if (outlineDict === null) {
|
130 | continue;
|
131 | }
|
132 |
|
133 | if (!outlineDict.has('Title')) {
|
134 | throw new _util.FormatError('Invalid outline item encountered.');
|
135 | }
|
136 |
|
137 | var data = {
|
138 | url: null,
|
139 | dest: null
|
140 | };
|
141 | Catalog.parseDestDictionary({
|
142 | destDict: outlineDict,
|
143 | resultObj: data,
|
144 | docBaseUrl: this.pdfManager.docBaseUrl
|
145 | });
|
146 | var title = outlineDict.get('Title');
|
147 | var flags = outlineDict.get('F') || 0;
|
148 | var color = outlineDict.getArray('C');
|
149 | var rgbColor = blackColor;
|
150 |
|
151 | if (Array.isArray(color) && color.length === 3 && (color[0] !== 0 || color[1] !== 0 || color[2] !== 0)) {
|
152 | rgbColor = _colorspace.ColorSpace.singletons.rgb.getRgb(color, 0);
|
153 | }
|
154 |
|
155 | var outlineItem = {
|
156 | dest: data.dest,
|
157 | url: data.url,
|
158 | unsafeUrl: data.unsafeUrl,
|
159 | newWindow: data.newWindow,
|
160 | title: (0, _util.stringToPDFString)(title),
|
161 | color: rgbColor,
|
162 | count: outlineDict.get('Count'),
|
163 | bold: !!(flags & 2),
|
164 | italic: !!(flags & 1),
|
165 | items: []
|
166 | };
|
167 | i.parent.items.push(outlineItem);
|
168 | obj = outlineDict.getRaw('First');
|
169 |
|
170 | if ((0, _primitives.isRef)(obj) && !processed.has(obj)) {
|
171 | queue.push({
|
172 | obj: obj,
|
173 | parent: outlineItem
|
174 | });
|
175 | processed.put(obj);
|
176 | }
|
177 |
|
178 | obj = outlineDict.getRaw('Next');
|
179 |
|
180 | if ((0, _primitives.isRef)(obj) && !processed.has(obj)) {
|
181 | queue.push({
|
182 | obj: obj,
|
183 | parent: i.parent
|
184 | });
|
185 | processed.put(obj);
|
186 | }
|
187 | }
|
188 |
|
189 | return root.items.length > 0 ? root.items : null;
|
190 | }
|
191 | }, {
|
192 | key: "_readPermissions",
|
193 | value: function _readPermissions() {
|
194 | var encrypt = this.xref.trailer.get('Encrypt');
|
195 |
|
196 | if (!(0, _primitives.isDict)(encrypt)) {
|
197 | return null;
|
198 | }
|
199 |
|
200 | var flags = encrypt.get('P');
|
201 |
|
202 | if (!(0, _util.isNum)(flags)) {
|
203 | return null;
|
204 | }
|
205 |
|
206 | flags += Math.pow(2, 32);
|
207 | var permissions = [];
|
208 |
|
209 | for (var key in _util.PermissionFlag) {
|
210 | var value = _util.PermissionFlag[key];
|
211 |
|
212 | if (flags & value) {
|
213 | permissions.push(value);
|
214 | }
|
215 | }
|
216 |
|
217 | return permissions;
|
218 | }
|
219 | }, {
|
220 | key: "getDestination",
|
221 | value: function getDestination(destinationId) {
|
222 | var obj = this._readDests();
|
223 |
|
224 | if (obj instanceof NameTree || obj instanceof _primitives.Dict) {
|
225 | return fetchDestination(obj.get(destinationId) || null);
|
226 | }
|
227 |
|
228 | return null;
|
229 | }
|
230 | }, {
|
231 | key: "_readDests",
|
232 | value: function _readDests() {
|
233 | var obj = this.catDict.get('Names');
|
234 |
|
235 | if (obj && obj.has('Dests')) {
|
236 | return new NameTree(obj.getRaw('Dests'), this.xref);
|
237 | } else if (this.catDict.has('Dests')) {
|
238 | return this.catDict.get('Dests');
|
239 | }
|
240 | }
|
241 | }, {
|
242 | key: "_readPageLabels",
|
243 | value: function _readPageLabels() {
|
244 | var obj = this.catDict.getRaw('PageLabels');
|
245 |
|
246 | if (!obj) {
|
247 | return null;
|
248 | }
|
249 |
|
250 | var pageLabels = new Array(this.numPages);
|
251 | var style = null,
|
252 | prefix = '';
|
253 | var numberTree = new NumberTree(obj, this.xref);
|
254 | var nums = numberTree.getAll();
|
255 | var currentLabel = '',
|
256 | currentIndex = 1;
|
257 |
|
258 | for (var i = 0, ii = this.numPages; i < ii; i++) {
|
259 | if (i in nums) {
|
260 | var labelDict = nums[i];
|
261 |
|
262 | if (!(0, _primitives.isDict)(labelDict)) {
|
263 | throw new _util.FormatError('PageLabel is not a dictionary.');
|
264 | }
|
265 |
|
266 | if (labelDict.has('Type') && !(0, _primitives.isName)(labelDict.get('Type'), 'PageLabel')) {
|
267 | throw new _util.FormatError('Invalid type in PageLabel dictionary.');
|
268 | }
|
269 |
|
270 | if (labelDict.has('S')) {
|
271 | var s = labelDict.get('S');
|
272 |
|
273 | if (!(0, _primitives.isName)(s)) {
|
274 | throw new _util.FormatError('Invalid style in PageLabel dictionary.');
|
275 | }
|
276 |
|
277 | style = s.name;
|
278 | } else {
|
279 | style = null;
|
280 | }
|
281 |
|
282 | if (labelDict.has('P')) {
|
283 | var p = labelDict.get('P');
|
284 |
|
285 | if (!(0, _util.isString)(p)) {
|
286 | throw new _util.FormatError('Invalid prefix in PageLabel dictionary.');
|
287 | }
|
288 |
|
289 | prefix = (0, _util.stringToPDFString)(p);
|
290 | } else {
|
291 | prefix = '';
|
292 | }
|
293 |
|
294 | if (labelDict.has('St')) {
|
295 | var st = labelDict.get('St');
|
296 |
|
297 | if (!(Number.isInteger(st) && st >= 1)) {
|
298 | throw new _util.FormatError('Invalid start in PageLabel dictionary.');
|
299 | }
|
300 |
|
301 | currentIndex = st;
|
302 | } else {
|
303 | currentIndex = 1;
|
304 | }
|
305 | }
|
306 |
|
307 | switch (style) {
|
308 | case 'D':
|
309 | currentLabel = currentIndex;
|
310 | break;
|
311 |
|
312 | case 'R':
|
313 | case 'r':
|
314 | currentLabel = (0, _util.toRomanNumerals)(currentIndex, style === 'r');
|
315 | break;
|
316 |
|
317 | case 'A':
|
318 | case 'a':
|
319 | var LIMIT = 26;
|
320 | var A_UPPER_CASE = 0x41,
|
321 | A_LOWER_CASE = 0x61;
|
322 | var baseCharCode = style === 'a' ? A_LOWER_CASE : A_UPPER_CASE;
|
323 | var letterIndex = currentIndex - 1;
|
324 | var character = String.fromCharCode(baseCharCode + letterIndex % LIMIT);
|
325 | var charBuf = [];
|
326 |
|
327 | for (var j = 0, jj = letterIndex / LIMIT | 0; j <= jj; j++) {
|
328 | charBuf.push(character);
|
329 | }
|
330 |
|
331 | currentLabel = charBuf.join('');
|
332 | break;
|
333 |
|
334 | default:
|
335 | if (style) {
|
336 | throw new _util.FormatError("Invalid style \"".concat(style, "\" in PageLabel dictionary."));
|
337 | }
|
338 |
|
339 | currentLabel = '';
|
340 | }
|
341 |
|
342 | pageLabels[i] = prefix + currentLabel;
|
343 | currentIndex++;
|
344 | }
|
345 |
|
346 | return pageLabels;
|
347 | }
|
348 | }, {
|
349 | key: "fontFallback",
|
350 | value: function fontFallback(id, handler) {
|
351 | var promises = [];
|
352 | this.fontCache.forEach(function (promise) {
|
353 | promises.push(promise);
|
354 | });
|
355 | return Promise.all(promises).then(function (translatedFonts) {
|
356 | var _iteratorNormalCompletion = true;
|
357 | var _didIteratorError = false;
|
358 | var _iteratorError = undefined;
|
359 |
|
360 | try {
|
361 | for (var _iterator = translatedFonts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
362 | var translatedFont = _step.value;
|
363 |
|
364 | if (translatedFont.loadedName === id) {
|
365 | translatedFont.fallback(handler);
|
366 | return;
|
367 | }
|
368 | }
|
369 | } catch (err) {
|
370 | _didIteratorError = true;
|
371 | _iteratorError = err;
|
372 | } finally {
|
373 | try {
|
374 | if (!_iteratorNormalCompletion && _iterator.return != null) {
|
375 | _iterator.return();
|
376 | }
|
377 | } finally {
|
378 | if (_didIteratorError) {
|
379 | throw _iteratorError;
|
380 | }
|
381 | }
|
382 | }
|
383 | });
|
384 | }
|
385 | }, {
|
386 | key: "cleanup",
|
387 | value: function cleanup() {
|
388 | var _this = this;
|
389 |
|
390 | this.pageKidsCountCache.clear();
|
391 | var promises = [];
|
392 | this.fontCache.forEach(function (promise) {
|
393 | promises.push(promise);
|
394 | });
|
395 | return Promise.all(promises).then(function (translatedFonts) {
|
396 | for (var i = 0, ii = translatedFonts.length; i < ii; i++) {
|
397 | var font = translatedFonts[i].dict;
|
398 | delete font.translated;
|
399 | }
|
400 |
|
401 | _this.fontCache.clear();
|
402 |
|
403 | _this.builtInCMapCache.clear();
|
404 | });
|
405 | }
|
406 | }, {
|
407 | key: "getPageDict",
|
408 | value: function getPageDict(pageIndex) {
|
409 | var capability = (0, _util.createPromiseCapability)();
|
410 | var nodesToVisit = [this.catDict.getRaw('Pages')];
|
411 | var xref = this.xref,
|
412 | pageKidsCountCache = this.pageKidsCountCache;
|
413 | var count,
|
414 | currentPageIndex = 0;
|
415 |
|
416 | function next() {
|
417 | var _loop = function _loop() {
|
418 | var currentNode = nodesToVisit.pop();
|
419 |
|
420 | if ((0, _primitives.isRef)(currentNode)) {
|
421 | count = pageKidsCountCache.get(currentNode);
|
422 |
|
423 | if (count > 0 && currentPageIndex + count < pageIndex) {
|
424 | currentPageIndex += count;
|
425 | return "continue";
|
426 | }
|
427 |
|
428 | xref.fetchAsync(currentNode).then(function (obj) {
|
429 | if ((0, _primitives.isDict)(obj, 'Page') || (0, _primitives.isDict)(obj) && !obj.has('Kids')) {
|
430 | if (pageIndex === currentPageIndex) {
|
431 | if (currentNode && !pageKidsCountCache.has(currentNode)) {
|
432 | pageKidsCountCache.put(currentNode, 1);
|
433 | }
|
434 |
|
435 | capability.resolve([obj, currentNode]);
|
436 | } else {
|
437 | currentPageIndex++;
|
438 | next();
|
439 | }
|
440 |
|
441 | return;
|
442 | }
|
443 |
|
444 | nodesToVisit.push(obj);
|
445 | next();
|
446 | }, capability.reject);
|
447 | return {
|
448 | v: void 0
|
449 | };
|
450 | }
|
451 |
|
452 | if (!(0, _primitives.isDict)(currentNode)) {
|
453 | capability.reject(new _util.FormatError('Page dictionary kid reference points to wrong type of object.'));
|
454 | return {
|
455 | v: void 0
|
456 | };
|
457 | }
|
458 |
|
459 | count = currentNode.get('Count');
|
460 |
|
461 | if (Number.isInteger(count) && count >= 0) {
|
462 | var objId = currentNode.objId;
|
463 |
|
464 | if (objId && !pageKidsCountCache.has(objId)) {
|
465 | pageKidsCountCache.put(objId, count);
|
466 | }
|
467 |
|
468 | if (currentPageIndex + count <= pageIndex) {
|
469 | currentPageIndex += count;
|
470 | return "continue";
|
471 | }
|
472 | }
|
473 |
|
474 | var kids = currentNode.get('Kids');
|
475 |
|
476 | if (!Array.isArray(kids)) {
|
477 | if ((0, _primitives.isName)(currentNode.get('Type'), 'Page') || !currentNode.has('Type') && currentNode.has('Contents')) {
|
478 | if (currentPageIndex === pageIndex) {
|
479 | capability.resolve([currentNode, null]);
|
480 | return {
|
481 | v: void 0
|
482 | };
|
483 | }
|
484 |
|
485 | currentPageIndex++;
|
486 | return "continue";
|
487 | }
|
488 |
|
489 | capability.reject(new _util.FormatError('Page dictionary kids object is not an array.'));
|
490 | return {
|
491 | v: void 0
|
492 | };
|
493 | }
|
494 |
|
495 | for (var last = kids.length - 1; last >= 0; last--) {
|
496 | nodesToVisit.push(kids[last]);
|
497 | }
|
498 | };
|
499 |
|
500 | while (nodesToVisit.length) {
|
501 | var _ret = _loop();
|
502 |
|
503 | switch (_ret) {
|
504 | case "continue":
|
505 | continue;
|
506 |
|
507 | default:
|
508 | if (_typeof(_ret) === "object") return _ret.v;
|
509 | }
|
510 | }
|
511 |
|
512 | capability.reject(new Error("Page index ".concat(pageIndex, " not found.")));
|
513 | }
|
514 |
|
515 | next();
|
516 | return capability.promise;
|
517 | }
|
518 | }, {
|
519 | key: "getPageIndex",
|
520 | value: function getPageIndex(pageRef) {
|
521 | var xref = this.xref;
|
522 |
|
523 | function pagesBeforeRef(kidRef) {
|
524 | var total = 0,
|
525 | parentRef;
|
526 | return xref.fetchAsync(kidRef).then(function (node) {
|
527 | if ((0, _primitives.isRefsEqual)(kidRef, pageRef) && !(0, _primitives.isDict)(node, 'Page') && !((0, _primitives.isDict)(node) && !node.has('Type') && node.has('Contents'))) {
|
528 | throw new _util.FormatError('The reference does not point to a /Page dictionary.');
|
529 | }
|
530 |
|
531 | if (!node) {
|
532 | return null;
|
533 | }
|
534 |
|
535 | if (!(0, _primitives.isDict)(node)) {
|
536 | throw new _util.FormatError('Node must be a dictionary.');
|
537 | }
|
538 |
|
539 | parentRef = node.getRaw('Parent');
|
540 | return node.getAsync('Parent');
|
541 | }).then(function (parent) {
|
542 | if (!parent) {
|
543 | return null;
|
544 | }
|
545 |
|
546 | if (!(0, _primitives.isDict)(parent)) {
|
547 | throw new _util.FormatError('Parent must be a dictionary.');
|
548 | }
|
549 |
|
550 | return parent.getAsync('Kids');
|
551 | }).then(function (kids) {
|
552 | if (!kids) {
|
553 | return null;
|
554 | }
|
555 |
|
556 | var kidPromises = [];
|
557 | var found = false;
|
558 |
|
559 | for (var i = 0, ii = kids.length; i < ii; i++) {
|
560 | var kid = kids[i];
|
561 |
|
562 | if (!(0, _primitives.isRef)(kid)) {
|
563 | throw new _util.FormatError('Kid must be a reference.');
|
564 | }
|
565 |
|
566 | if ((0, _primitives.isRefsEqual)(kid, kidRef)) {
|
567 | found = true;
|
568 | break;
|
569 | }
|
570 |
|
571 | kidPromises.push(xref.fetchAsync(kid).then(function (kid) {
|
572 | if (!(0, _primitives.isDict)(kid)) {
|
573 | throw new _util.FormatError('Kid node must be a dictionary.');
|
574 | }
|
575 |
|
576 | if (kid.has('Count')) {
|
577 | total += kid.get('Count');
|
578 | } else {
|
579 | total++;
|
580 | }
|
581 | }));
|
582 | }
|
583 |
|
584 | if (!found) {
|
585 | throw new _util.FormatError('Kid reference not found in parent\'s kids.');
|
586 | }
|
587 |
|
588 | return Promise.all(kidPromises).then(function () {
|
589 | return [total, parentRef];
|
590 | });
|
591 | });
|
592 | }
|
593 |
|
594 | var total = 0;
|
595 |
|
596 | function next(ref) {
|
597 | return pagesBeforeRef(ref).then(function (args) {
|
598 | if (!args) {
|
599 | return total;
|
600 | }
|
601 |
|
602 | var _args = _slicedToArray(args, 2),
|
603 | count = _args[0],
|
604 | parentRef = _args[1];
|
605 |
|
606 | total += count;
|
607 | return next(parentRef);
|
608 | });
|
609 | }
|
610 |
|
611 | return next(pageRef);
|
612 | }
|
613 | }, {
|
614 | key: "metadata",
|
615 | get: function get() {
|
616 | var streamRef = this.catDict.getRaw('Metadata');
|
617 |
|
618 | if (!(0, _primitives.isRef)(streamRef)) {
|
619 | return (0, _util.shadow)(this, 'metadata', null);
|
620 | }
|
621 |
|
622 | var suppressEncryption = !(this.xref.encrypt && this.xref.encrypt.encryptMetadata);
|
623 | var stream = this.xref.fetch(streamRef, suppressEncryption);
|
624 | var metadata;
|
625 |
|
626 | if (stream && (0, _primitives.isDict)(stream.dict)) {
|
627 | var type = stream.dict.get('Type');
|
628 | var subtype = stream.dict.get('Subtype');
|
629 |
|
630 | if ((0, _primitives.isName)(type, 'Metadata') && (0, _primitives.isName)(subtype, 'XML')) {
|
631 | try {
|
632 | metadata = (0, _util.stringToUTF8String)((0, _util.bytesToString)(stream.getBytes()));
|
633 | } catch (e) {
|
634 | if (e instanceof _util.MissingDataException) {
|
635 | throw e;
|
636 | }
|
637 |
|
638 | (0, _util.info)('Skipping invalid metadata.');
|
639 | }
|
640 | }
|
641 | }
|
642 |
|
643 | return (0, _util.shadow)(this, 'metadata', metadata);
|
644 | }
|
645 | }, {
|
646 | key: "toplevelPagesDict",
|
647 | get: function get() {
|
648 | var pagesObj = this.catDict.get('Pages');
|
649 |
|
650 | if (!(0, _primitives.isDict)(pagesObj)) {
|
651 | throw new _util.FormatError('Invalid top-level pages dictionary.');
|
652 | }
|
653 |
|
654 | return (0, _util.shadow)(this, 'toplevelPagesDict', pagesObj);
|
655 | }
|
656 | }, {
|
657 | key: "documentOutline",
|
658 | get: function get() {
|
659 | var obj = null;
|
660 |
|
661 | try {
|
662 | obj = this._readDocumentOutline();
|
663 | } catch (ex) {
|
664 | if (ex instanceof _util.MissingDataException) {
|
665 | throw ex;
|
666 | }
|
667 |
|
668 | (0, _util.warn)('Unable to read document outline.');
|
669 | }
|
670 |
|
671 | return (0, _util.shadow)(this, 'documentOutline', obj);
|
672 | }
|
673 | }, {
|
674 | key: "permissions",
|
675 | get: function get() {
|
676 | var permissions = null;
|
677 |
|
678 | try {
|
679 | permissions = this._readPermissions();
|
680 | } catch (ex) {
|
681 | if (ex instanceof _util.MissingDataException) {
|
682 | throw ex;
|
683 | }
|
684 |
|
685 | (0, _util.warn)('Unable to read permissions.');
|
686 | }
|
687 |
|
688 | return (0, _util.shadow)(this, 'permissions', permissions);
|
689 | }
|
690 | }, {
|
691 | key: "numPages",
|
692 | get: function get() {
|
693 | var obj = this.toplevelPagesDict.get('Count');
|
694 |
|
695 | if (!Number.isInteger(obj)) {
|
696 | throw new _util.FormatError('Page count in top-level pages dictionary is not an integer.');
|
697 | }
|
698 |
|
699 | return (0, _util.shadow)(this, 'numPages', obj);
|
700 | }
|
701 | }, {
|
702 | key: "destinations",
|
703 | get: function get() {
|
704 | var obj = this._readDests(),
|
705 | dests = Object.create(null);
|
706 |
|
707 | if (obj instanceof NameTree) {
|
708 | var names = obj.getAll();
|
709 |
|
710 | for (var name in names) {
|
711 | dests[name] = fetchDestination(names[name]);
|
712 | }
|
713 | } else if (obj instanceof _primitives.Dict) {
|
714 | obj.forEach(function (key, value) {
|
715 | if (value) {
|
716 | dests[key] = fetchDestination(value);
|
717 | }
|
718 | });
|
719 | }
|
720 |
|
721 | return (0, _util.shadow)(this, 'destinations', dests);
|
722 | }
|
723 | }, {
|
724 | key: "pageLabels",
|
725 | get: function get() {
|
726 | var obj = null;
|
727 |
|
728 | try {
|
729 | obj = this._readPageLabels();
|
730 | } catch (ex) {
|
731 | if (ex instanceof _util.MissingDataException) {
|
732 | throw ex;
|
733 | }
|
734 |
|
735 | (0, _util.warn)('Unable to read page labels.');
|
736 | }
|
737 |
|
738 | return (0, _util.shadow)(this, 'pageLabels', obj);
|
739 | }
|
740 | }, {
|
741 | key: "pageMode",
|
742 | get: function get() {
|
743 | var obj = this.catDict.get('PageMode');
|
744 | var pageMode = 'UseNone';
|
745 |
|
746 | if ((0, _primitives.isName)(obj)) {
|
747 | switch (obj.name) {
|
748 | case 'UseNone':
|
749 | case 'UseOutlines':
|
750 | case 'UseThumbs':
|
751 | case 'FullScreen':
|
752 | case 'UseOC':
|
753 | case 'UseAttachments':
|
754 | pageMode = obj.name;
|
755 | }
|
756 | }
|
757 |
|
758 | return (0, _util.shadow)(this, 'pageMode', pageMode);
|
759 | }
|
760 | }, {
|
761 | key: "openActionDestination",
|
762 | get: function get() {
|
763 | var obj = this.catDict.get('OpenAction');
|
764 | var openActionDest = null;
|
765 |
|
766 | if ((0, _primitives.isDict)(obj)) {
|
767 | var destDict = new _primitives.Dict(this.xref);
|
768 | destDict.set('A', obj);
|
769 | var resultObj = {
|
770 | url: null,
|
771 | dest: null
|
772 | };
|
773 | Catalog.parseDestDictionary({
|
774 | destDict: destDict,
|
775 | resultObj: resultObj
|
776 | });
|
777 |
|
778 | if (Array.isArray(resultObj.dest)) {
|
779 | openActionDest = resultObj.dest;
|
780 | }
|
781 | } else if (Array.isArray(obj)) {
|
782 | openActionDest = obj;
|
783 | }
|
784 |
|
785 | return (0, _util.shadow)(this, 'openActionDestination', openActionDest);
|
786 | }
|
787 | }, {
|
788 | key: "attachments",
|
789 | get: function get() {
|
790 | var obj = this.catDict.get('Names');
|
791 | var attachments = null;
|
792 |
|
793 | if (obj && obj.has('EmbeddedFiles')) {
|
794 | var nameTree = new NameTree(obj.getRaw('EmbeddedFiles'), this.xref);
|
795 | var names = nameTree.getAll();
|
796 |
|
797 | for (var name in names) {
|
798 | var fs = new FileSpec(names[name], this.xref);
|
799 |
|
800 | if (!attachments) {
|
801 | attachments = Object.create(null);
|
802 | }
|
803 |
|
804 | attachments[(0, _util.stringToPDFString)(name)] = fs.serializable;
|
805 | }
|
806 | }
|
807 |
|
808 | return (0, _util.shadow)(this, 'attachments', attachments);
|
809 | }
|
810 | }, {
|
811 | key: "javaScript",
|
812 | get: function get() {
|
813 | var obj = this.catDict.get('Names');
|
814 | var javaScript = null;
|
815 |
|
816 | function appendIfJavaScriptDict(jsDict) {
|
817 | var type = jsDict.get('S');
|
818 |
|
819 | if (!(0, _primitives.isName)(type, 'JavaScript')) {
|
820 | return;
|
821 | }
|
822 |
|
823 | var js = jsDict.get('JS');
|
824 |
|
825 | if ((0, _primitives.isStream)(js)) {
|
826 | js = (0, _util.bytesToString)(js.getBytes());
|
827 | } else if (!(0, _util.isString)(js)) {
|
828 | return;
|
829 | }
|
830 |
|
831 | if (!javaScript) {
|
832 | javaScript = [];
|
833 | }
|
834 |
|
835 | javaScript.push((0, _util.stringToPDFString)(js));
|
836 | }
|
837 |
|
838 | if (obj && obj.has('JavaScript')) {
|
839 | var nameTree = new NameTree(obj.getRaw('JavaScript'), this.xref);
|
840 | var names = nameTree.getAll();
|
841 |
|
842 | for (var name in names) {
|
843 | var jsDict = names[name];
|
844 |
|
845 | if ((0, _primitives.isDict)(jsDict)) {
|
846 | appendIfJavaScriptDict(jsDict);
|
847 | }
|
848 | }
|
849 | }
|
850 |
|
851 | var openActionDict = this.catDict.get('OpenAction');
|
852 |
|
853 | if ((0, _primitives.isDict)(openActionDict, 'Action')) {
|
854 | var actionType = openActionDict.get('S');
|
855 |
|
856 | if ((0, _primitives.isName)(actionType, 'Named')) {
|
857 | var action = openActionDict.get('N');
|
858 |
|
859 | if ((0, _primitives.isName)(action, 'Print')) {
|
860 | if (!javaScript) {
|
861 | javaScript = [];
|
862 | }
|
863 |
|
864 | javaScript.push('print({});');
|
865 | }
|
866 | } else {
|
867 | appendIfJavaScriptDict(openActionDict);
|
868 | }
|
869 | }
|
870 |
|
871 | return (0, _util.shadow)(this, 'javaScript', javaScript);
|
872 | }
|
873 | }], [{
|
874 | key: "parseDestDictionary",
|
875 | value: function parseDestDictionary(params) {
|
876 | function addDefaultProtocolToUrl(url) {
|
877 | return url.startsWith('www.') ? "http://".concat(url) : url;
|
878 | }
|
879 |
|
880 | function tryConvertUrlEncoding(url) {
|
881 | try {
|
882 | return (0, _util.stringToUTF8String)(url);
|
883 | } catch (e) {
|
884 | return url;
|
885 | }
|
886 | }
|
887 |
|
888 | var destDict = params.destDict;
|
889 |
|
890 | if (!(0, _primitives.isDict)(destDict)) {
|
891 | (0, _util.warn)('parseDestDictionary: `destDict` must be a dictionary.');
|
892 | return;
|
893 | }
|
894 |
|
895 | var resultObj = params.resultObj;
|
896 |
|
897 | if (_typeof(resultObj) !== 'object') {
|
898 | (0, _util.warn)('parseDestDictionary: `resultObj` must be an object.');
|
899 | return;
|
900 | }
|
901 |
|
902 | var docBaseUrl = params.docBaseUrl || null;
|
903 | var action = destDict.get('A'),
|
904 | url,
|
905 | dest;
|
906 |
|
907 | if (!(0, _primitives.isDict)(action) && destDict.has('Dest')) {
|
908 | action = destDict.get('Dest');
|
909 | }
|
910 |
|
911 | if ((0, _primitives.isDict)(action)) {
|
912 | var actionType = action.get('S');
|
913 |
|
914 | if (!(0, _primitives.isName)(actionType)) {
|
915 | (0, _util.warn)('parseDestDictionary: Invalid type in Action dictionary.');
|
916 | return;
|
917 | }
|
918 |
|
919 | var actionName = actionType.name;
|
920 |
|
921 | switch (actionName) {
|
922 | case 'URI':
|
923 | url = action.get('URI');
|
924 |
|
925 | if ((0, _primitives.isName)(url)) {
|
926 | url = '/' + url.name;
|
927 | } else if ((0, _util.isString)(url)) {
|
928 | url = addDefaultProtocolToUrl(url);
|
929 | }
|
930 |
|
931 | break;
|
932 |
|
933 | case 'GoTo':
|
934 | dest = action.get('D');
|
935 | break;
|
936 |
|
937 | case 'Launch':
|
938 | case 'GoToR':
|
939 | var urlDict = action.get('F');
|
940 |
|
941 | if ((0, _primitives.isDict)(urlDict)) {
|
942 | url = urlDict.get('F') || null;
|
943 | } else if ((0, _util.isString)(urlDict)) {
|
944 | url = urlDict;
|
945 | }
|
946 |
|
947 | var remoteDest = action.get('D');
|
948 |
|
949 | if (remoteDest) {
|
950 | if ((0, _primitives.isName)(remoteDest)) {
|
951 | remoteDest = remoteDest.name;
|
952 | }
|
953 |
|
954 | if ((0, _util.isString)(url)) {
|
955 | var baseUrl = url.split('#')[0];
|
956 |
|
957 | if ((0, _util.isString)(remoteDest)) {
|
958 | url = baseUrl + '#' + remoteDest;
|
959 | } else if (Array.isArray(remoteDest)) {
|
960 | url = baseUrl + '#' + JSON.stringify(remoteDest);
|
961 | }
|
962 | }
|
963 | }
|
964 |
|
965 | var newWindow = action.get('NewWindow');
|
966 |
|
967 | if ((0, _util.isBool)(newWindow)) {
|
968 | resultObj.newWindow = newWindow;
|
969 | }
|
970 |
|
971 | break;
|
972 |
|
973 | case 'Named':
|
974 | var namedAction = action.get('N');
|
975 |
|
976 | if ((0, _primitives.isName)(namedAction)) {
|
977 | resultObj.action = namedAction.name;
|
978 | }
|
979 |
|
980 | break;
|
981 |
|
982 | case 'JavaScript':
|
983 | var jsAction = action.get('JS');
|
984 | var js;
|
985 |
|
986 | if ((0, _primitives.isStream)(jsAction)) {
|
987 | js = (0, _util.bytesToString)(jsAction.getBytes());
|
988 | } else if ((0, _util.isString)(jsAction)) {
|
989 | js = jsAction;
|
990 | }
|
991 |
|
992 | if (js) {
|
993 | var URL_OPEN_METHODS = ['app.launchURL', 'window.open'];
|
994 | var regex = new RegExp('^\\s*(' + URL_OPEN_METHODS.join('|').split('.').join('\\.') + ')\\((?:\'|\")([^\'\"]*)(?:\'|\")(?:,\\s*(\\w+)\\)|\\))', 'i');
|
995 | var jsUrl = regex.exec((0, _util.stringToPDFString)(js));
|
996 |
|
997 | if (jsUrl && jsUrl[2]) {
|
998 | url = jsUrl[2];
|
999 |
|
1000 | if (jsUrl[3] === 'true' && jsUrl[1] === 'app.launchURL') {
|
1001 | resultObj.newWindow = true;
|
1002 | }
|
1003 |
|
1004 | break;
|
1005 | }
|
1006 | }
|
1007 |
|
1008 | default:
|
1009 | (0, _util.warn)("parseDestDictionary: unsupported action type \"".concat(actionName, "\"."));
|
1010 | break;
|
1011 | }
|
1012 | } else if (destDict.has('Dest')) {
|
1013 | dest = destDict.get('Dest');
|
1014 | }
|
1015 |
|
1016 | if ((0, _util.isString)(url)) {
|
1017 | url = tryConvertUrlEncoding(url);
|
1018 | var absoluteUrl = (0, _util.createValidAbsoluteUrl)(url, docBaseUrl);
|
1019 |
|
1020 | if (absoluteUrl) {
|
1021 | resultObj.url = absoluteUrl.href;
|
1022 | }
|
1023 |
|
1024 | resultObj.unsafeUrl = url;
|
1025 | }
|
1026 |
|
1027 | if (dest) {
|
1028 | if ((0, _primitives.isName)(dest)) {
|
1029 | dest = dest.name;
|
1030 | }
|
1031 |
|
1032 | if ((0, _util.isString)(dest) || Array.isArray(dest)) {
|
1033 | resultObj.dest = dest;
|
1034 | }
|
1035 | }
|
1036 | }
|
1037 | }]);
|
1038 |
|
1039 | return Catalog;
|
1040 | }();
|
1041 |
|
1042 | exports.Catalog = Catalog;
|
1043 |
|
1044 | var XRef = function XRefClosure() {
|
1045 | function XRef(stream, pdfManager) {
|
1046 | this.stream = stream;
|
1047 | this.pdfManager = pdfManager;
|
1048 | this.entries = [];
|
1049 | this.xrefstms = Object.create(null);
|
1050 | this.cache = [];
|
1051 | this.stats = {
|
1052 | streamTypes: [],
|
1053 | fontTypes: []
|
1054 | };
|
1055 | }
|
1056 |
|
1057 | XRef.prototype = {
|
1058 | setStartXRef: function XRef_setStartXRef(startXRef) {
|
1059 | this.startXRefQueue = [startXRef];
|
1060 | },
|
1061 | parse: function XRef_parse(recoveryMode) {
|
1062 | var trailerDict;
|
1063 |
|
1064 | if (!recoveryMode) {
|
1065 | trailerDict = this.readXRef();
|
1066 | } else {
|
1067 | (0, _util.warn)('Indexing all PDF objects');
|
1068 | trailerDict = this.indexObjects();
|
1069 | }
|
1070 |
|
1071 | trailerDict.assignXref(this);
|
1072 | this.trailer = trailerDict;
|
1073 | var encrypt;
|
1074 |
|
1075 | try {
|
1076 | encrypt = trailerDict.get('Encrypt');
|
1077 | } catch (ex) {
|
1078 | if (ex instanceof _util.MissingDataException) {
|
1079 | throw ex;
|
1080 | }
|
1081 |
|
1082 | (0, _util.warn)("XRef.parse - Invalid \"Encrypt\" reference: \"".concat(ex, "\"."));
|
1083 | }
|
1084 |
|
1085 | if ((0, _primitives.isDict)(encrypt)) {
|
1086 | var ids = trailerDict.get('ID');
|
1087 | var fileId = ids && ids.length ? ids[0] : '';
|
1088 | encrypt.suppressEncryption = true;
|
1089 | this.encrypt = new _crypto.CipherTransformFactory(encrypt, fileId, this.pdfManager.password);
|
1090 | }
|
1091 |
|
1092 | var root;
|
1093 |
|
1094 | try {
|
1095 | root = trailerDict.get('Root');
|
1096 | } catch (ex) {
|
1097 | if (ex instanceof _util.MissingDataException) {
|
1098 | throw ex;
|
1099 | }
|
1100 |
|
1101 | (0, _util.warn)("XRef.parse - Invalid \"Root\" reference: \"".concat(ex, "\"."));
|
1102 | }
|
1103 |
|
1104 | if ((0, _primitives.isDict)(root) && root.has('Pages')) {
|
1105 | this.root = root;
|
1106 | } else {
|
1107 | if (!recoveryMode) {
|
1108 | throw new _util.XRefParseException();
|
1109 | }
|
1110 |
|
1111 | throw new _util.FormatError('Invalid root reference');
|
1112 | }
|
1113 | },
|
1114 | processXRefTable: function XRef_processXRefTable(parser) {
|
1115 | if (!('tableState' in this)) {
|
1116 | this.tableState = {
|
1117 | entryNum: 0,
|
1118 | streamPos: parser.lexer.stream.pos,
|
1119 | parserBuf1: parser.buf1,
|
1120 | parserBuf2: parser.buf2
|
1121 | };
|
1122 | }
|
1123 |
|
1124 | var obj = this.readXRefTable(parser);
|
1125 |
|
1126 | if (!(0, _primitives.isCmd)(obj, 'trailer')) {
|
1127 | throw new _util.FormatError('Invalid XRef table: could not find trailer dictionary');
|
1128 | }
|
1129 |
|
1130 | var dict = parser.getObj();
|
1131 |
|
1132 | if (!(0, _primitives.isDict)(dict) && dict.dict) {
|
1133 | dict = dict.dict;
|
1134 | }
|
1135 |
|
1136 | if (!(0, _primitives.isDict)(dict)) {
|
1137 | throw new _util.FormatError('Invalid XRef table: could not parse trailer dictionary');
|
1138 | }
|
1139 |
|
1140 | delete this.tableState;
|
1141 | return dict;
|
1142 | },
|
1143 | readXRefTable: function XRef_readXRefTable(parser) {
|
1144 | var stream = parser.lexer.stream;
|
1145 | var tableState = this.tableState;
|
1146 | stream.pos = tableState.streamPos;
|
1147 | parser.buf1 = tableState.parserBuf1;
|
1148 | parser.buf2 = tableState.parserBuf2;
|
1149 | var obj;
|
1150 |
|
1151 | while (true) {
|
1152 | if (!('firstEntryNum' in tableState) || !('entryCount' in tableState)) {
|
1153 | if ((0, _primitives.isCmd)(obj = parser.getObj(), 'trailer')) {
|
1154 | break;
|
1155 | }
|
1156 |
|
1157 | tableState.firstEntryNum = obj;
|
1158 | tableState.entryCount = parser.getObj();
|
1159 | }
|
1160 |
|
1161 | var first = tableState.firstEntryNum;
|
1162 | var count = tableState.entryCount;
|
1163 |
|
1164 | if (!Number.isInteger(first) || !Number.isInteger(count)) {
|
1165 | throw new _util.FormatError('Invalid XRef table: wrong types in subsection header');
|
1166 | }
|
1167 |
|
1168 | for (var i = tableState.entryNum; i < count; i++) {
|
1169 | tableState.streamPos = stream.pos;
|
1170 | tableState.entryNum = i;
|
1171 | tableState.parserBuf1 = parser.buf1;
|
1172 | tableState.parserBuf2 = parser.buf2;
|
1173 | var entry = {};
|
1174 | entry.offset = parser.getObj();
|
1175 | entry.gen = parser.getObj();
|
1176 | var type = parser.getObj();
|
1177 |
|
1178 | if ((0, _primitives.isCmd)(type, 'f')) {
|
1179 | entry.free = true;
|
1180 | } else if ((0, _primitives.isCmd)(type, 'n')) {
|
1181 | entry.uncompressed = true;
|
1182 | }
|
1183 |
|
1184 | if (!Number.isInteger(entry.offset) || !Number.isInteger(entry.gen) || !(entry.free || entry.uncompressed)) {
|
1185 | throw new _util.FormatError("Invalid entry in XRef subsection: ".concat(first, ", ").concat(count));
|
1186 | }
|
1187 |
|
1188 | if (i === 0 && entry.free && first === 1) {
|
1189 | first = 0;
|
1190 | }
|
1191 |
|
1192 | if (!this.entries[i + first]) {
|
1193 | this.entries[i + first] = entry;
|
1194 | }
|
1195 | }
|
1196 |
|
1197 | tableState.entryNum = 0;
|
1198 | tableState.streamPos = stream.pos;
|
1199 | tableState.parserBuf1 = parser.buf1;
|
1200 | tableState.parserBuf2 = parser.buf2;
|
1201 | delete tableState.firstEntryNum;
|
1202 | delete tableState.entryCount;
|
1203 | }
|
1204 |
|
1205 | if (this.entries[0] && !this.entries[0].free) {
|
1206 | throw new _util.FormatError('Invalid XRef table: unexpected first object');
|
1207 | }
|
1208 |
|
1209 | return obj;
|
1210 | },
|
1211 | processXRefStream: function XRef_processXRefStream(stream) {
|
1212 | if (!('streamState' in this)) {
|
1213 | var streamParameters = stream.dict;
|
1214 | var byteWidths = streamParameters.get('W');
|
1215 | var range = streamParameters.get('Index');
|
1216 |
|
1217 | if (!range) {
|
1218 | range = [0, streamParameters.get('Size')];
|
1219 | }
|
1220 |
|
1221 | this.streamState = {
|
1222 | entryRanges: range,
|
1223 | byteWidths: byteWidths,
|
1224 | entryNum: 0,
|
1225 | streamPos: stream.pos
|
1226 | };
|
1227 | }
|
1228 |
|
1229 | this.readXRefStream(stream);
|
1230 | delete this.streamState;
|
1231 | return stream.dict;
|
1232 | },
|
1233 | readXRefStream: function XRef_readXRefStream(stream) {
|
1234 | var i, j;
|
1235 | var streamState = this.streamState;
|
1236 | stream.pos = streamState.streamPos;
|
1237 | var byteWidths = streamState.byteWidths;
|
1238 | var typeFieldWidth = byteWidths[0];
|
1239 | var offsetFieldWidth = byteWidths[1];
|
1240 | var generationFieldWidth = byteWidths[2];
|
1241 | var entryRanges = streamState.entryRanges;
|
1242 |
|
1243 | while (entryRanges.length > 0) {
|
1244 | var first = entryRanges[0];
|
1245 | var n = entryRanges[1];
|
1246 |
|
1247 | if (!Number.isInteger(first) || !Number.isInteger(n)) {
|
1248 | throw new _util.FormatError("Invalid XRef range fields: ".concat(first, ", ").concat(n));
|
1249 | }
|
1250 |
|
1251 | if (!Number.isInteger(typeFieldWidth) || !Number.isInteger(offsetFieldWidth) || !Number.isInteger(generationFieldWidth)) {
|
1252 | throw new _util.FormatError("Invalid XRef entry fields length: ".concat(first, ", ").concat(n));
|
1253 | }
|
1254 |
|
1255 | for (i = streamState.entryNum; i < n; ++i) {
|
1256 | streamState.entryNum = i;
|
1257 | streamState.streamPos = stream.pos;
|
1258 | var type = 0,
|
1259 | offset = 0,
|
1260 | generation = 0;
|
1261 |
|
1262 | for (j = 0; j < typeFieldWidth; ++j) {
|
1263 | type = type << 8 | stream.getByte();
|
1264 | }
|
1265 |
|
1266 | if (typeFieldWidth === 0) {
|
1267 | type = 1;
|
1268 | }
|
1269 |
|
1270 | for (j = 0; j < offsetFieldWidth; ++j) {
|
1271 | offset = offset << 8 | stream.getByte();
|
1272 | }
|
1273 |
|
1274 | for (j = 0; j < generationFieldWidth; ++j) {
|
1275 | generation = generation << 8 | stream.getByte();
|
1276 | }
|
1277 |
|
1278 | var entry = {};
|
1279 | entry.offset = offset;
|
1280 | entry.gen = generation;
|
1281 |
|
1282 | switch (type) {
|
1283 | case 0:
|
1284 | entry.free = true;
|
1285 | break;
|
1286 |
|
1287 | case 1:
|
1288 | entry.uncompressed = true;
|
1289 | break;
|
1290 |
|
1291 | case 2:
|
1292 | break;
|
1293 |
|
1294 | default:
|
1295 | throw new _util.FormatError("Invalid XRef entry type: ".concat(type));
|
1296 | }
|
1297 |
|
1298 | if (!this.entries[first + i]) {
|
1299 | this.entries[first + i] = entry;
|
1300 | }
|
1301 | }
|
1302 |
|
1303 | streamState.entryNum = 0;
|
1304 | streamState.streamPos = stream.pos;
|
1305 | entryRanges.splice(0, 2);
|
1306 | }
|
1307 | },
|
1308 | indexObjects: function XRef_indexObjects() {
|
1309 | var TAB = 0x9,
|
1310 | LF = 0xA,
|
1311 | CR = 0xD,
|
1312 | SPACE = 0x20;
|
1313 | var PERCENT = 0x25,
|
1314 | LT = 0x3C;
|
1315 |
|
1316 | function readToken(data, offset) {
|
1317 | var token = '',
|
1318 | ch = data[offset];
|
1319 |
|
1320 | while (ch !== LF && ch !== CR && ch !== LT) {
|
1321 | if (++offset >= data.length) {
|
1322 | break;
|
1323 | }
|
1324 |
|
1325 | token += String.fromCharCode(ch);
|
1326 | ch = data[offset];
|
1327 | }
|
1328 |
|
1329 | return token;
|
1330 | }
|
1331 |
|
1332 | function skipUntil(data, offset, what) {
|
1333 | var length = what.length,
|
1334 | dataLength = data.length;
|
1335 | var skipped = 0;
|
1336 |
|
1337 | while (offset < dataLength) {
|
1338 | var i = 0;
|
1339 |
|
1340 | while (i < length && data[offset + i] === what[i]) {
|
1341 | ++i;
|
1342 | }
|
1343 |
|
1344 | if (i >= length) {
|
1345 | break;
|
1346 | }
|
1347 |
|
1348 | offset++;
|
1349 | skipped++;
|
1350 | }
|
1351 |
|
1352 | return skipped;
|
1353 | }
|
1354 |
|
1355 | var objRegExp = /^(\d+)\s+(\d+)\s+obj\b/;
|
1356 | var endobjRegExp = /\bendobj[\b\s]$/;
|
1357 | var nestedObjRegExp = /\s+(\d+\s+\d+\s+obj[\b\s<])$/;
|
1358 | var CHECK_CONTENT_LENGTH = 25;
|
1359 | var trailerBytes = new Uint8Array([116, 114, 97, 105, 108, 101, 114]);
|
1360 | var startxrefBytes = new Uint8Array([115, 116, 97, 114, 116, 120, 114, 101, 102]);
|
1361 | var objBytes = new Uint8Array([111, 98, 106]);
|
1362 | var xrefBytes = new Uint8Array([47, 88, 82, 101, 102]);
|
1363 | this.entries.length = 0;
|
1364 | var stream = this.stream;
|
1365 | stream.pos = 0;
|
1366 | var buffer = stream.getBytes();
|
1367 | var position = stream.start,
|
1368 | length = buffer.length;
|
1369 | var trailers = [],
|
1370 | xrefStms = [];
|
1371 |
|
1372 | while (position < length) {
|
1373 | var ch = buffer[position];
|
1374 |
|
1375 | if (ch === TAB || ch === LF || ch === CR || ch === SPACE) {
|
1376 | ++position;
|
1377 | continue;
|
1378 | }
|
1379 |
|
1380 | if (ch === PERCENT) {
|
1381 | do {
|
1382 | ++position;
|
1383 |
|
1384 | if (position >= length) {
|
1385 | break;
|
1386 | }
|
1387 |
|
1388 | ch = buffer[position];
|
1389 | } while (ch !== LF && ch !== CR);
|
1390 |
|
1391 | continue;
|
1392 | }
|
1393 |
|
1394 | var token = readToken(buffer, position);
|
1395 | var m;
|
1396 |
|
1397 | if (token.startsWith('xref') && (token.length === 4 || /\s/.test(token[4]))) {
|
1398 | position += skipUntil(buffer, position, trailerBytes);
|
1399 | trailers.push(position);
|
1400 | position += skipUntil(buffer, position, startxrefBytes);
|
1401 | } else if (m = objRegExp.exec(token)) {
|
1402 | var num = m[1] | 0,
|
1403 | gen = m[2] | 0;
|
1404 |
|
1405 | if (typeof this.entries[num] === 'undefined') {
|
1406 | this.entries[num] = {
|
1407 | offset: position - stream.start,
|
1408 | gen: gen,
|
1409 | uncompressed: true
|
1410 | };
|
1411 | }
|
1412 |
|
1413 | var contentLength = void 0,
|
1414 | startPos = position + token.length;
|
1415 |
|
1416 | while (startPos < buffer.length) {
|
1417 | var endPos = startPos + skipUntil(buffer, startPos, objBytes) + 4;
|
1418 | contentLength = endPos - position;
|
1419 | var checkPos = Math.max(endPos - CHECK_CONTENT_LENGTH, startPos);
|
1420 | var tokenStr = (0, _util.bytesToString)(buffer.subarray(checkPos, endPos));
|
1421 |
|
1422 | if (endobjRegExp.test(tokenStr)) {
|
1423 | break;
|
1424 | } else {
|
1425 | var objToken = nestedObjRegExp.exec(tokenStr);
|
1426 |
|
1427 | if (objToken && objToken[1]) {
|
1428 | (0, _util.warn)('indexObjects: Found new "obj" inside of another "obj", ' + 'caused by missing "endobj" -- trying to recover.');
|
1429 | contentLength -= objToken[1].length;
|
1430 | break;
|
1431 | }
|
1432 | }
|
1433 |
|
1434 | startPos = endPos;
|
1435 | }
|
1436 |
|
1437 | var content = buffer.subarray(position, position + contentLength);
|
1438 | var xrefTagOffset = skipUntil(content, 0, xrefBytes);
|
1439 |
|
1440 | if (xrefTagOffset < contentLength && content[xrefTagOffset + 5] < 64) {
|
1441 | xrefStms.push(position - stream.start);
|
1442 | this.xrefstms[position - stream.start] = 1;
|
1443 | }
|
1444 |
|
1445 | position += contentLength;
|
1446 | } else if (token.startsWith('trailer') && (token.length === 7 || /\s/.test(token[7]))) {
|
1447 | trailers.push(position);
|
1448 | position += skipUntil(buffer, position, startxrefBytes);
|
1449 | } else {
|
1450 | position += token.length + 1;
|
1451 | }
|
1452 | }
|
1453 |
|
1454 | var i, ii;
|
1455 |
|
1456 | for (i = 0, ii = xrefStms.length; i < ii; ++i) {
|
1457 | this.startXRefQueue.push(xrefStms[i]);
|
1458 | this.readXRef(true);
|
1459 | }
|
1460 |
|
1461 | var trailerDict;
|
1462 |
|
1463 | for (i = 0, ii = trailers.length; i < ii; ++i) {
|
1464 | stream.pos = trailers[i];
|
1465 | var parser = new _parser.Parser(new _parser.Lexer(stream), true, this, true);
|
1466 | var obj = parser.getObj();
|
1467 |
|
1468 | if (!(0, _primitives.isCmd)(obj, 'trailer')) {
|
1469 | continue;
|
1470 | }
|
1471 |
|
1472 | var dict = parser.getObj();
|
1473 |
|
1474 | if (!(0, _primitives.isDict)(dict)) {
|
1475 | continue;
|
1476 | }
|
1477 |
|
1478 | var rootDict = void 0;
|
1479 |
|
1480 | try {
|
1481 | rootDict = dict.get('Root');
|
1482 | } catch (ex) {
|
1483 | if (ex instanceof _util.MissingDataException) {
|
1484 | throw ex;
|
1485 | }
|
1486 |
|
1487 | continue;
|
1488 | }
|
1489 |
|
1490 | if (!(0, _primitives.isDict)(rootDict) || !rootDict.has('Pages')) {
|
1491 | continue;
|
1492 | }
|
1493 |
|
1494 | if (dict.has('ID')) {
|
1495 | return dict;
|
1496 | }
|
1497 |
|
1498 | trailerDict = dict;
|
1499 | }
|
1500 |
|
1501 | if (trailerDict) {
|
1502 | return trailerDict;
|
1503 | }
|
1504 |
|
1505 | throw new _util.InvalidPDFException('Invalid PDF structure');
|
1506 | },
|
1507 | readXRef: function XRef_readXRef(recoveryMode) {
|
1508 | var stream = this.stream;
|
1509 | var startXRefParsedCache = Object.create(null);
|
1510 |
|
1511 | try {
|
1512 | while (this.startXRefQueue.length) {
|
1513 | var startXRef = this.startXRefQueue[0];
|
1514 |
|
1515 | if (startXRefParsedCache[startXRef]) {
|
1516 | (0, _util.warn)('readXRef - skipping XRef table since it was already parsed.');
|
1517 | this.startXRefQueue.shift();
|
1518 | continue;
|
1519 | }
|
1520 |
|
1521 | startXRefParsedCache[startXRef] = true;
|
1522 | stream.pos = startXRef + stream.start;
|
1523 | var parser = new _parser.Parser(new _parser.Lexer(stream), true, this);
|
1524 | var obj = parser.getObj();
|
1525 | var dict;
|
1526 |
|
1527 | if ((0, _primitives.isCmd)(obj, 'xref')) {
|
1528 | dict = this.processXRefTable(parser);
|
1529 |
|
1530 | if (!this.topDict) {
|
1531 | this.topDict = dict;
|
1532 | }
|
1533 |
|
1534 | obj = dict.get('XRefStm');
|
1535 |
|
1536 | if (Number.isInteger(obj)) {
|
1537 | var pos = obj;
|
1538 |
|
1539 | if (!(pos in this.xrefstms)) {
|
1540 | this.xrefstms[pos] = 1;
|
1541 | this.startXRefQueue.push(pos);
|
1542 | }
|
1543 | }
|
1544 | } else if (Number.isInteger(obj)) {
|
1545 | if (!Number.isInteger(parser.getObj()) || !(0, _primitives.isCmd)(parser.getObj(), 'obj') || !(0, _primitives.isStream)(obj = parser.getObj())) {
|
1546 | throw new _util.FormatError('Invalid XRef stream');
|
1547 | }
|
1548 |
|
1549 | dict = this.processXRefStream(obj);
|
1550 |
|
1551 | if (!this.topDict) {
|
1552 | this.topDict = dict;
|
1553 | }
|
1554 |
|
1555 | if (!dict) {
|
1556 | throw new _util.FormatError('Failed to read XRef stream');
|
1557 | }
|
1558 | } else {
|
1559 | throw new _util.FormatError('Invalid XRef stream header');
|
1560 | }
|
1561 |
|
1562 | obj = dict.get('Prev');
|
1563 |
|
1564 | if (Number.isInteger(obj)) {
|
1565 | this.startXRefQueue.push(obj);
|
1566 | } else if ((0, _primitives.isRef)(obj)) {
|
1567 | this.startXRefQueue.push(obj.num);
|
1568 | }
|
1569 |
|
1570 | this.startXRefQueue.shift();
|
1571 | }
|
1572 |
|
1573 | return this.topDict;
|
1574 | } catch (e) {
|
1575 | if (e instanceof _util.MissingDataException) {
|
1576 | throw e;
|
1577 | }
|
1578 |
|
1579 | (0, _util.info)('(while reading XRef): ' + e);
|
1580 | }
|
1581 |
|
1582 | if (recoveryMode) {
|
1583 | return;
|
1584 | }
|
1585 |
|
1586 | throw new _util.XRefParseException();
|
1587 | },
|
1588 | getEntry: function XRef_getEntry(i) {
|
1589 | var xrefEntry = this.entries[i];
|
1590 |
|
1591 | if (xrefEntry && !xrefEntry.free && xrefEntry.offset) {
|
1592 | return xrefEntry;
|
1593 | }
|
1594 |
|
1595 | return null;
|
1596 | },
|
1597 | fetchIfRef: function XRef_fetchIfRef(obj, suppressEncryption) {
|
1598 | if (!(0, _primitives.isRef)(obj)) {
|
1599 | return obj;
|
1600 | }
|
1601 |
|
1602 | return this.fetch(obj, suppressEncryption);
|
1603 | },
|
1604 | fetch: function XRef_fetch(ref, suppressEncryption) {
|
1605 | if (!(0, _primitives.isRef)(ref)) {
|
1606 | throw new Error('ref object is not a reference');
|
1607 | }
|
1608 |
|
1609 | var num = ref.num;
|
1610 |
|
1611 | if (num in this.cache) {
|
1612 | var cacheEntry = this.cache[num];
|
1613 |
|
1614 | if (cacheEntry instanceof _primitives.Dict && !cacheEntry.objId) {
|
1615 | cacheEntry.objId = ref.toString();
|
1616 | }
|
1617 |
|
1618 | return cacheEntry;
|
1619 | }
|
1620 |
|
1621 | var xrefEntry = this.getEntry(num);
|
1622 |
|
1623 | if (xrefEntry === null) {
|
1624 | return this.cache[num] = null;
|
1625 | }
|
1626 |
|
1627 | if (xrefEntry.uncompressed) {
|
1628 | xrefEntry = this.fetchUncompressed(ref, xrefEntry, suppressEncryption);
|
1629 | } else {
|
1630 | xrefEntry = this.fetchCompressed(ref, xrefEntry, suppressEncryption);
|
1631 | }
|
1632 |
|
1633 | if ((0, _primitives.isDict)(xrefEntry)) {
|
1634 | xrefEntry.objId = ref.toString();
|
1635 | } else if ((0, _primitives.isStream)(xrefEntry)) {
|
1636 | xrefEntry.dict.objId = ref.toString();
|
1637 | }
|
1638 |
|
1639 | return xrefEntry;
|
1640 | },
|
1641 | fetchUncompressed: function fetchUncompressed(ref, xrefEntry) {
|
1642 | var suppressEncryption = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
1643 | var gen = ref.gen;
|
1644 | var num = ref.num;
|
1645 |
|
1646 | if (xrefEntry.gen !== gen) {
|
1647 | throw new _util.XRefEntryException("Inconsistent generation in XRef: ".concat(ref));
|
1648 | }
|
1649 |
|
1650 | var stream = this.stream.makeSubStream(xrefEntry.offset + this.stream.start);
|
1651 | var parser = new _parser.Parser(new _parser.Lexer(stream), true, this);
|
1652 | var obj1 = parser.getObj();
|
1653 | var obj2 = parser.getObj();
|
1654 | var obj3 = parser.getObj();
|
1655 |
|
1656 | if (!Number.isInteger(obj1)) {
|
1657 | obj1 = parseInt(obj1, 10);
|
1658 | }
|
1659 |
|
1660 | if (!Number.isInteger(obj2)) {
|
1661 | obj2 = parseInt(obj2, 10);
|
1662 | }
|
1663 |
|
1664 | if (obj1 !== num || obj2 !== gen || !(0, _primitives.isCmd)(obj3)) {
|
1665 | throw new _util.XRefEntryException("Bad (uncompressed) XRef entry: ".concat(ref));
|
1666 | }
|
1667 |
|
1668 | if (obj3.cmd !== 'obj') {
|
1669 | if (obj3.cmd.startsWith('obj')) {
|
1670 | num = parseInt(obj3.cmd.substring(3), 10);
|
1671 |
|
1672 | if (!Number.isNaN(num)) {
|
1673 | return num;
|
1674 | }
|
1675 | }
|
1676 |
|
1677 | throw new _util.XRefEntryException("Bad (uncompressed) XRef entry: ".concat(ref));
|
1678 | }
|
1679 |
|
1680 | if (this.encrypt && !suppressEncryption) {
|
1681 | xrefEntry = parser.getObj(this.encrypt.createCipherTransform(num, gen));
|
1682 | } else {
|
1683 | xrefEntry = parser.getObj();
|
1684 | }
|
1685 |
|
1686 | if (!(0, _primitives.isStream)(xrefEntry)) {
|
1687 | this.cache[num] = xrefEntry;
|
1688 | }
|
1689 |
|
1690 | return xrefEntry;
|
1691 | },
|
1692 | fetchCompressed: function fetchCompressed(ref, xrefEntry) {
|
1693 | var suppressEncryption = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
1694 | var tableOffset = xrefEntry.offset;
|
1695 | var stream = this.fetch(new _primitives.Ref(tableOffset, 0));
|
1696 |
|
1697 | if (!(0, _primitives.isStream)(stream)) {
|
1698 | throw new _util.FormatError('bad ObjStm stream');
|
1699 | }
|
1700 |
|
1701 | var first = stream.dict.get('First');
|
1702 | var n = stream.dict.get('N');
|
1703 |
|
1704 | if (!Number.isInteger(first) || !Number.isInteger(n)) {
|
1705 | throw new _util.FormatError('invalid first and n parameters for ObjStm stream');
|
1706 | }
|
1707 |
|
1708 | var parser = new _parser.Parser(new _parser.Lexer(stream), false, this);
|
1709 | parser.allowStreams = true;
|
1710 | var i,
|
1711 | entries = [],
|
1712 | num,
|
1713 | nums = [];
|
1714 |
|
1715 | for (i = 0; i < n; ++i) {
|
1716 | num = parser.getObj();
|
1717 |
|
1718 | if (!Number.isInteger(num)) {
|
1719 | throw new _util.FormatError("invalid object number in the ObjStm stream: ".concat(num));
|
1720 | }
|
1721 |
|
1722 | nums.push(num);
|
1723 | var offset = parser.getObj();
|
1724 |
|
1725 | if (!Number.isInteger(offset)) {
|
1726 | throw new _util.FormatError("invalid object offset in the ObjStm stream: ".concat(offset));
|
1727 | }
|
1728 | }
|
1729 |
|
1730 | for (i = 0; i < n; ++i) {
|
1731 | entries.push(parser.getObj());
|
1732 |
|
1733 | if ((0, _primitives.isCmd)(parser.buf1, 'endobj')) {
|
1734 | parser.shift();
|
1735 | }
|
1736 |
|
1737 | num = nums[i];
|
1738 | var entry = this.entries[num];
|
1739 |
|
1740 | if (entry && entry.offset === tableOffset && entry.gen === i) {
|
1741 | this.cache[num] = entries[i];
|
1742 | }
|
1743 | }
|
1744 |
|
1745 | xrefEntry = entries[xrefEntry.gen];
|
1746 |
|
1747 | if (xrefEntry === undefined) {
|
1748 | throw new _util.XRefEntryException("Bad (compressed) XRef entry: ".concat(ref));
|
1749 | }
|
1750 |
|
1751 | return xrefEntry;
|
1752 | },
|
1753 | fetchIfRefAsync: function () {
|
1754 | var _fetchIfRefAsync = _asyncToGenerator(
|
1755 |
|
1756 | _regenerator.default.mark(function _callee(obj, suppressEncryption) {
|
1757 | return _regenerator.default.wrap(function _callee$(_context) {
|
1758 | while (1) {
|
1759 | switch (_context.prev = _context.next) {
|
1760 | case 0:
|
1761 | if ((0, _primitives.isRef)(obj)) {
|
1762 | _context.next = 2;
|
1763 | break;
|
1764 | }
|
1765 |
|
1766 | return _context.abrupt("return", obj);
|
1767 |
|
1768 | case 2:
|
1769 | return _context.abrupt("return", this.fetchAsync(obj, suppressEncryption));
|
1770 |
|
1771 | case 3:
|
1772 | case "end":
|
1773 | return _context.stop();
|
1774 | }
|
1775 | }
|
1776 | }, _callee, this);
|
1777 | }));
|
1778 |
|
1779 | function fetchIfRefAsync(_x, _x2) {
|
1780 | return _fetchIfRefAsync.apply(this, arguments);
|
1781 | }
|
1782 |
|
1783 | return fetchIfRefAsync;
|
1784 | }(),
|
1785 | fetchAsync: function () {
|
1786 | var _fetchAsync = _asyncToGenerator(
|
1787 |
|
1788 | _regenerator.default.mark(function _callee2(ref, suppressEncryption) {
|
1789 | return _regenerator.default.wrap(function _callee2$(_context2) {
|
1790 | while (1) {
|
1791 | switch (_context2.prev = _context2.next) {
|
1792 | case 0:
|
1793 | _context2.prev = 0;
|
1794 | return _context2.abrupt("return", this.fetch(ref, suppressEncryption));
|
1795 |
|
1796 | case 4:
|
1797 | _context2.prev = 4;
|
1798 | _context2.t0 = _context2["catch"](0);
|
1799 |
|
1800 | if (_context2.t0 instanceof _util.MissingDataException) {
|
1801 | _context2.next = 8;
|
1802 | break;
|
1803 | }
|
1804 |
|
1805 | throw _context2.t0;
|
1806 |
|
1807 | case 8:
|
1808 | _context2.next = 10;
|
1809 | return this.pdfManager.requestRange(_context2.t0.begin, _context2.t0.end);
|
1810 |
|
1811 | case 10:
|
1812 | return _context2.abrupt("return", this.fetchAsync(ref, suppressEncryption));
|
1813 |
|
1814 | case 11:
|
1815 | case "end":
|
1816 | return _context2.stop();
|
1817 | }
|
1818 | }
|
1819 | }, _callee2, this, [[0, 4]]);
|
1820 | }));
|
1821 |
|
1822 | function fetchAsync(_x3, _x4) {
|
1823 | return _fetchAsync.apply(this, arguments);
|
1824 | }
|
1825 |
|
1826 | return fetchAsync;
|
1827 | }(),
|
1828 | getCatalogObj: function XRef_getCatalogObj() {
|
1829 | return this.root;
|
1830 | }
|
1831 | };
|
1832 | return XRef;
|
1833 | }();
|
1834 |
|
1835 | exports.XRef = XRef;
|
1836 |
|
1837 | var NameOrNumberTree =
|
1838 |
|
1839 | function () {
|
1840 | function NameOrNumberTree(root, xref, type) {
|
1841 | _classCallCheck(this, NameOrNumberTree);
|
1842 |
|
1843 | if (this.constructor === NameOrNumberTree) {
|
1844 | (0, _util.unreachable)('Cannot initialize NameOrNumberTree.');
|
1845 | }
|
1846 |
|
1847 | this.root = root;
|
1848 | this.xref = xref;
|
1849 | this._type = type;
|
1850 | }
|
1851 |
|
1852 | _createClass(NameOrNumberTree, [{
|
1853 | key: "getAll",
|
1854 | value: function getAll() {
|
1855 | var dict = Object.create(null);
|
1856 |
|
1857 | if (!this.root) {
|
1858 | return dict;
|
1859 | }
|
1860 |
|
1861 | var xref = this.xref;
|
1862 | var processed = new _primitives.RefSet();
|
1863 | processed.put(this.root);
|
1864 | var queue = [this.root];
|
1865 |
|
1866 | while (queue.length > 0) {
|
1867 | var obj = xref.fetchIfRef(queue.shift());
|
1868 |
|
1869 | if (!(0, _primitives.isDict)(obj)) {
|
1870 | continue;
|
1871 | }
|
1872 |
|
1873 | if (obj.has('Kids')) {
|
1874 | var kids = obj.get('Kids');
|
1875 |
|
1876 | for (var i = 0, ii = kids.length; i < ii; i++) {
|
1877 | var kid = kids[i];
|
1878 |
|
1879 | if (processed.has(kid)) {
|
1880 | throw new _util.FormatError("Duplicate entry in \"".concat(this._type, "\" tree."));
|
1881 | }
|
1882 |
|
1883 | queue.push(kid);
|
1884 | processed.put(kid);
|
1885 | }
|
1886 |
|
1887 | continue;
|
1888 | }
|
1889 |
|
1890 | var entries = obj.get(this._type);
|
1891 |
|
1892 | if (Array.isArray(entries)) {
|
1893 | for (var _i2 = 0, _ii = entries.length; _i2 < _ii; _i2 += 2) {
|
1894 | dict[xref.fetchIfRef(entries[_i2])] = xref.fetchIfRef(entries[_i2 + 1]);
|
1895 | }
|
1896 | }
|
1897 | }
|
1898 |
|
1899 | return dict;
|
1900 | }
|
1901 | }, {
|
1902 | key: "get",
|
1903 | value: function get(key) {
|
1904 | if (!this.root) {
|
1905 | return null;
|
1906 | }
|
1907 |
|
1908 | var xref = this.xref;
|
1909 | var kidsOrEntries = xref.fetchIfRef(this.root);
|
1910 | var loopCount = 0;
|
1911 | var MAX_LEVELS = 10;
|
1912 |
|
1913 | while (kidsOrEntries.has('Kids')) {
|
1914 | if (++loopCount > MAX_LEVELS) {
|
1915 | (0, _util.warn)("Search depth limit reached for \"".concat(this._type, "\" tree."));
|
1916 | return null;
|
1917 | }
|
1918 |
|
1919 | var kids = kidsOrEntries.get('Kids');
|
1920 |
|
1921 | if (!Array.isArray(kids)) {
|
1922 | return null;
|
1923 | }
|
1924 |
|
1925 | var l = 0,
|
1926 | r = kids.length - 1;
|
1927 |
|
1928 | while (l <= r) {
|
1929 | var m = l + r >> 1;
|
1930 | var kid = xref.fetchIfRef(kids[m]);
|
1931 | var limits = kid.get('Limits');
|
1932 |
|
1933 | if (key < xref.fetchIfRef(limits[0])) {
|
1934 | r = m - 1;
|
1935 | } else if (key > xref.fetchIfRef(limits[1])) {
|
1936 | l = m + 1;
|
1937 | } else {
|
1938 | kidsOrEntries = xref.fetchIfRef(kids[m]);
|
1939 | break;
|
1940 | }
|
1941 | }
|
1942 |
|
1943 | if (l > r) {
|
1944 | return null;
|
1945 | }
|
1946 | }
|
1947 |
|
1948 | var entries = kidsOrEntries.get(this._type);
|
1949 |
|
1950 | if (Array.isArray(entries)) {
|
1951 | var _l = 0,
|
1952 | _r = entries.length - 2;
|
1953 |
|
1954 | while (_l <= _r) {
|
1955 | var tmp = _l + _r >> 1,
|
1956 | _m = tmp + (tmp & 1);
|
1957 |
|
1958 | var currentKey = xref.fetchIfRef(entries[_m]);
|
1959 |
|
1960 | if (key < currentKey) {
|
1961 | _r = _m - 2;
|
1962 | } else if (key > currentKey) {
|
1963 | _l = _m + 2;
|
1964 | } else {
|
1965 | return xref.fetchIfRef(entries[_m + 1]);
|
1966 | }
|
1967 | }
|
1968 |
|
1969 | (0, _util.info)("Falling back to an exhaustive search, for key \"".concat(key, "\", ") + "in \"".concat(this._type, "\" tree."));
|
1970 |
|
1971 | for (var _m2 = 0, mm = entries.length; _m2 < mm; _m2 += 2) {
|
1972 | var _currentKey = xref.fetchIfRef(entries[_m2]);
|
1973 |
|
1974 | if (_currentKey === key) {
|
1975 | (0, _util.warn)("The \"".concat(key, "\" key was found at an incorrect, ") + "i.e. out-of-order, position in \"".concat(this._type, "\" tree."));
|
1976 | return xref.fetchIfRef(entries[_m2 + 1]);
|
1977 | }
|
1978 | }
|
1979 | }
|
1980 |
|
1981 | return null;
|
1982 | }
|
1983 | }]);
|
1984 |
|
1985 | return NameOrNumberTree;
|
1986 | }();
|
1987 |
|
1988 | var NameTree =
|
1989 |
|
1990 | function (_NameOrNumberTree) {
|
1991 | _inherits(NameTree, _NameOrNumberTree);
|
1992 |
|
1993 | function NameTree(root, xref) {
|
1994 | _classCallCheck(this, NameTree);
|
1995 |
|
1996 | return _possibleConstructorReturn(this, _getPrototypeOf(NameTree).call(this, root, xref, 'Names'));
|
1997 | }
|
1998 |
|
1999 | return NameTree;
|
2000 | }(NameOrNumberTree);
|
2001 |
|
2002 | var NumberTree =
|
2003 |
|
2004 | function (_NameOrNumberTree2) {
|
2005 | _inherits(NumberTree, _NameOrNumberTree2);
|
2006 |
|
2007 | function NumberTree(root, xref) {
|
2008 | _classCallCheck(this, NumberTree);
|
2009 |
|
2010 | return _possibleConstructorReturn(this, _getPrototypeOf(NumberTree).call(this, root, xref, 'Nums'));
|
2011 | }
|
2012 |
|
2013 | return NumberTree;
|
2014 | }(NameOrNumberTree);
|
2015 |
|
2016 | var FileSpec = function FileSpecClosure() {
|
2017 | function FileSpec(root, xref) {
|
2018 | if (!root || !(0, _primitives.isDict)(root)) {
|
2019 | return;
|
2020 | }
|
2021 |
|
2022 | this.xref = xref;
|
2023 | this.root = root;
|
2024 |
|
2025 | if (root.has('FS')) {
|
2026 | this.fs = root.get('FS');
|
2027 | }
|
2028 |
|
2029 | this.description = root.has('Desc') ? (0, _util.stringToPDFString)(root.get('Desc')) : '';
|
2030 |
|
2031 | if (root.has('RF')) {
|
2032 | (0, _util.warn)('Related file specifications are not supported');
|
2033 | }
|
2034 |
|
2035 | this.contentAvailable = true;
|
2036 |
|
2037 | if (!root.has('EF')) {
|
2038 | this.contentAvailable = false;
|
2039 | (0, _util.warn)('Non-embedded file specifications are not supported');
|
2040 | }
|
2041 | }
|
2042 |
|
2043 | function pickPlatformItem(dict) {
|
2044 | if (dict.has('UF')) {
|
2045 | return dict.get('UF');
|
2046 | } else if (dict.has('F')) {
|
2047 | return dict.get('F');
|
2048 | } else if (dict.has('Unix')) {
|
2049 | return dict.get('Unix');
|
2050 | } else if (dict.has('Mac')) {
|
2051 | return dict.get('Mac');
|
2052 | } else if (dict.has('DOS')) {
|
2053 | return dict.get('DOS');
|
2054 | }
|
2055 |
|
2056 | return null;
|
2057 | }
|
2058 |
|
2059 | FileSpec.prototype = {
|
2060 | get filename() {
|
2061 | if (!this._filename && this.root) {
|
2062 | var filename = pickPlatformItem(this.root) || 'unnamed';
|
2063 | this._filename = (0, _util.stringToPDFString)(filename).replace(/\\\\/g, '\\').replace(/\\\//g, '/').replace(/\\/g, '/');
|
2064 | }
|
2065 |
|
2066 | return this._filename;
|
2067 | },
|
2068 |
|
2069 | get content() {
|
2070 | if (!this.contentAvailable) {
|
2071 | return null;
|
2072 | }
|
2073 |
|
2074 | if (!this.contentRef && this.root) {
|
2075 | this.contentRef = pickPlatformItem(this.root.get('EF'));
|
2076 | }
|
2077 |
|
2078 | var content = null;
|
2079 |
|
2080 | if (this.contentRef) {
|
2081 | var xref = this.xref;
|
2082 | var fileObj = xref.fetchIfRef(this.contentRef);
|
2083 |
|
2084 | if (fileObj && (0, _primitives.isStream)(fileObj)) {
|
2085 | content = fileObj.getBytes();
|
2086 | } else {
|
2087 | (0, _util.warn)('Embedded file specification points to non-existing/invalid ' + 'content');
|
2088 | }
|
2089 | } else {
|
2090 | (0, _util.warn)('Embedded file specification does not have a content');
|
2091 | }
|
2092 |
|
2093 | return content;
|
2094 | },
|
2095 |
|
2096 | get serializable() {
|
2097 | return {
|
2098 | filename: this.filename,
|
2099 | content: this.content
|
2100 | };
|
2101 | }
|
2102 |
|
2103 | };
|
2104 | return FileSpec;
|
2105 | }();
|
2106 |
|
2107 | exports.FileSpec = FileSpec;
|
2108 |
|
2109 | var ObjectLoader = function () {
|
2110 | function mayHaveChildren(value) {
|
2111 | return (0, _primitives.isRef)(value) || (0, _primitives.isDict)(value) || Array.isArray(value) || (0, _primitives.isStream)(value);
|
2112 | }
|
2113 |
|
2114 | function addChildren(node, nodesToVisit) {
|
2115 | if ((0, _primitives.isDict)(node) || (0, _primitives.isStream)(node)) {
|
2116 | var dict = (0, _primitives.isDict)(node) ? node : node.dict;
|
2117 | var dictKeys = dict.getKeys();
|
2118 |
|
2119 | for (var i = 0, ii = dictKeys.length; i < ii; i++) {
|
2120 | var rawValue = dict.getRaw(dictKeys[i]);
|
2121 |
|
2122 | if (mayHaveChildren(rawValue)) {
|
2123 | nodesToVisit.push(rawValue);
|
2124 | }
|
2125 | }
|
2126 | } else if (Array.isArray(node)) {
|
2127 | for (var _i3 = 0, _ii2 = node.length; _i3 < _ii2; _i3++) {
|
2128 | var value = node[_i3];
|
2129 |
|
2130 | if (mayHaveChildren(value)) {
|
2131 | nodesToVisit.push(value);
|
2132 | }
|
2133 | }
|
2134 | }
|
2135 | }
|
2136 |
|
2137 | function ObjectLoader(dict, keys, xref) {
|
2138 | this.dict = dict;
|
2139 | this.keys = keys;
|
2140 | this.xref = xref;
|
2141 | this.refSet = null;
|
2142 | this.capability = null;
|
2143 | }
|
2144 |
|
2145 | ObjectLoader.prototype = {
|
2146 | load: function load() {
|
2147 | this.capability = (0, _util.createPromiseCapability)();
|
2148 |
|
2149 | if (!(this.xref.stream instanceof _chunked_stream.ChunkedStream) || this.xref.stream.getMissingChunks().length === 0) {
|
2150 | this.capability.resolve();
|
2151 | return this.capability.promise;
|
2152 | }
|
2153 |
|
2154 | var keys = this.keys,
|
2155 | dict = this.dict;
|
2156 | this.refSet = new _primitives.RefSet();
|
2157 | var nodesToVisit = [];
|
2158 |
|
2159 | for (var i = 0, ii = keys.length; i < ii; i++) {
|
2160 | var rawValue = dict.getRaw(keys[i]);
|
2161 |
|
2162 | if (rawValue !== undefined) {
|
2163 | nodesToVisit.push(rawValue);
|
2164 | }
|
2165 | }
|
2166 |
|
2167 | this._walk(nodesToVisit);
|
2168 |
|
2169 | return this.capability.promise;
|
2170 | },
|
2171 | _walk: function _walk(nodesToVisit) {
|
2172 | var _this2 = this;
|
2173 |
|
2174 | var nodesToRevisit = [];
|
2175 | var pendingRequests = [];
|
2176 |
|
2177 | while (nodesToVisit.length) {
|
2178 | var currentNode = nodesToVisit.pop();
|
2179 |
|
2180 | if ((0, _primitives.isRef)(currentNode)) {
|
2181 | if (this.refSet.has(currentNode)) {
|
2182 | continue;
|
2183 | }
|
2184 |
|
2185 | try {
|
2186 | this.refSet.put(currentNode);
|
2187 | currentNode = this.xref.fetch(currentNode);
|
2188 | } catch (ex) {
|
2189 | if (!(ex instanceof _util.MissingDataException)) {
|
2190 | throw ex;
|
2191 | }
|
2192 |
|
2193 | nodesToRevisit.push(currentNode);
|
2194 | pendingRequests.push({
|
2195 | begin: ex.begin,
|
2196 | end: ex.end
|
2197 | });
|
2198 | }
|
2199 | }
|
2200 |
|
2201 | if (currentNode && currentNode.getBaseStreams) {
|
2202 | var baseStreams = currentNode.getBaseStreams();
|
2203 | var foundMissingData = false;
|
2204 |
|
2205 | for (var i = 0, ii = baseStreams.length; i < ii; i++) {
|
2206 | var stream = baseStreams[i];
|
2207 |
|
2208 | if (stream.getMissingChunks && stream.getMissingChunks().length) {
|
2209 | foundMissingData = true;
|
2210 | pendingRequests.push({
|
2211 | begin: stream.start,
|
2212 | end: stream.end
|
2213 | });
|
2214 | }
|
2215 | }
|
2216 |
|
2217 | if (foundMissingData) {
|
2218 | nodesToRevisit.push(currentNode);
|
2219 | }
|
2220 | }
|
2221 |
|
2222 | addChildren(currentNode, nodesToVisit);
|
2223 | }
|
2224 |
|
2225 | if (pendingRequests.length) {
|
2226 | this.xref.stream.manager.requestRanges(pendingRequests).then(function () {
|
2227 | for (var _i4 = 0, _ii3 = nodesToRevisit.length; _i4 < _ii3; _i4++) {
|
2228 | var node = nodesToRevisit[_i4];
|
2229 |
|
2230 | if ((0, _primitives.isRef)(node)) {
|
2231 | _this2.refSet.remove(node);
|
2232 | }
|
2233 | }
|
2234 |
|
2235 | _this2._walk(nodesToRevisit);
|
2236 | }, this.capability.reject);
|
2237 | return;
|
2238 | }
|
2239 |
|
2240 | this.refSet = null;
|
2241 | this.capability.resolve();
|
2242 | }
|
2243 | };
|
2244 | return ObjectLoader;
|
2245 | }();
|
2246 |
|
2247 | exports.ObjectLoader = ObjectLoader; |
\ | No newline at end of file |