Skip to content

Commit 640a310

Browse files
committed
Remove caching/shadowing from the FileSpec getters, and simplify the code
Given that only the `FileSpec.prototype.serializable` getter is ever invoked from "outside" of the class, and only once per `FileSpec`-instance, the caching/shadowing isn't actually necessary. Furthermore the `_contentRef`-caching wasn't actually correct, since it ended up storing a `BaseStream`-instance and those should *generally* never be cached. (Since calling `BaseStream.prototype.getBytes()` more than once, without resetting the stream in between, will return an empty TypedArray after the first time.)
1 parent 84b5866 commit 640a310

3 files changed

Lines changed: 21 additions & 37 deletions

File tree

src/core/annotation.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5290,8 +5290,8 @@ class FileAttachmentAnnotation extends MarkupAnnotation {
52905290
constructor(params) {
52915291
super(params);
52925292

5293-
const { dict, xref } = params;
5294-
const file = new FileSpec(dict.get("FS"), xref);
5293+
const { dict } = params;
5294+
const file = new FileSpec(dict.get("FS"));
52955295

52965296
this.data.annotationType = AnnotationType.FILEATTACHMENT;
52975297
this.data.hasOwnCanvas = this.data.noRotate;

src/core/catalog.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ class Catalog {
10571057
if (obj instanceof Dict && obj.has("EmbeddedFiles")) {
10581058
const nameTree = new NameTree(obj.getRaw("EmbeddedFiles"), this.xref);
10591059
for (const [key, value] of nameTree.getAll()) {
1060-
const fs = new FileSpec(value, this.xref);
1060+
const fs = new FileSpec(value);
10611061
attachments ??= Object.create(null);
10621062
attachments[stringToPDFString(key, /* keepEscapeSequence = */ true)] =
10631063
fs.serializable;
@@ -1623,11 +1623,7 @@ class Catalog {
16231623
case "GoToR":
16241624
const urlDict = action.get("F");
16251625
if (urlDict instanceof Dict) {
1626-
const fs = new FileSpec(
1627-
urlDict,
1628-
/* xref = */ null,
1629-
/* skipContent = */ true
1630-
);
1626+
const fs = new FileSpec(urlDict, /* skipContent = */ true);
16311627
({ rawFilename: url } = fs.serializable);
16321628
} else if (typeof urlDict === "string") {
16331629
url = urlDict;

src/core/file_spec.js

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* limitations under the License.
1414
*/
1515

16-
import { shadow, stringToPDFString, warn } from "../shared/util.js";
16+
import { stringToPDFString, warn } from "../shared/util.js";
1717
import { BaseStream } from "./base_stream.js";
1818
import { Dict } from "./primitives.js";
1919

@@ -43,11 +43,10 @@ function stripPath(str) {
4343
class FileSpec {
4444
#contentAvailable = false;
4545

46-
constructor(root, xref, skipContent = false) {
46+
constructor(root, skipContent = false) {
4747
if (!(root instanceof Dict)) {
4848
return;
4949
}
50-
this.xref = xref;
5150
this.root = root;
5251
if (root.has("FS")) {
5352
this.fs = root.get("FS");
@@ -65,56 +64,45 @@ class FileSpec {
6564
}
6665

6766
get filename() {
68-
let filename = "";
69-
7067
const item = pickPlatformItem(this.root);
68+
let name;
7169
if (item && typeof item === "string") {
72-
filename = stringToPDFString(item, /* keepEscapeSequence = */ true)
70+
name = stringToPDFString(item, /* keepEscapeSequence = */ true)
7371
.replaceAll("\\\\", "\\")
7472
.replaceAll("\\/", "/")
7573
.replaceAll("\\", "/");
7674
}
77-
return shadow(this, "filename", filename || "unnamed");
75+
return name || "unnamed";
7876
}
7977

8078
get content() {
8179
if (!this.#contentAvailable) {
8280
return null;
8381
}
84-
this._contentRef ||= pickPlatformItem(this.root?.get("EF"));
82+
const ef = pickPlatformItem(this.root?.get("EF"));
8583

86-
let content = null;
87-
if (this._contentRef) {
88-
const fileObj = this.xref.fetchIfRef(this._contentRef);
89-
if (fileObj instanceof BaseStream) {
90-
content = fileObj.getBytes();
91-
} else {
92-
warn(
93-
"Embedded file specification points to non-existing/invalid content"
94-
);
95-
}
96-
} else {
97-
warn("Embedded file specification does not have any content");
84+
if (ef instanceof BaseStream) {
85+
return ef.getBytes();
9886
}
99-
return content;
87+
warn("Embedded file specification points to non-existing/invalid content");
88+
return null;
10089
}
10190

10291
get description() {
103-
let description = "";
104-
10592
const desc = this.root?.get("Desc");
10693
if (desc && typeof desc === "string") {
107-
description = stringToPDFString(desc);
94+
return stringToPDFString(desc);
10895
}
109-
return shadow(this, "description", description);
96+
return "";
11097
}
11198

11299
get serializable() {
100+
const { filename, content, description } = this;
113101
return {
114-
rawFilename: this.filename,
115-
filename: stripPath(this.filename),
116-
content: this.content,
117-
description: this.description,
102+
rawFilename: filename,
103+
filename: stripPath(filename),
104+
content,
105+
description,
118106
};
119107
}
120108
}

0 commit comments

Comments
 (0)