Merge pull request #19051 from Snuffleupagus/Dict-Map
Convert the `Dict`-implementation to use a `Map` internally
This commit is contained in:
commit
bc91985941
@ -6,6 +6,7 @@ external/bcmaps/
|
|||||||
external/builder/fixtures/
|
external/builder/fixtures/
|
||||||
external/builder/fixtures_babel/
|
external/builder/fixtures_babel/
|
||||||
external/quickjs/
|
external/quickjs/
|
||||||
|
test/stats/results/
|
||||||
test/tmp/
|
test/tmp/
|
||||||
test/pdfs/
|
test/pdfs/
|
||||||
web/locale/
|
web/locale/
|
||||||
|
|||||||
@ -6,6 +6,7 @@ external/bcmaps/
|
|||||||
external/builder/fixtures/
|
external/builder/fixtures/
|
||||||
external/builder/fixtures_babel/
|
external/builder/fixtures_babel/
|
||||||
external/quickjs/
|
external/quickjs/
|
||||||
|
test/stats/results/
|
||||||
test/tmp/
|
test/tmp/
|
||||||
test/pdfs/
|
test/pdfs/
|
||||||
web/locale/
|
web/locale/
|
||||||
|
|||||||
@ -35,6 +35,7 @@ export default [
|
|||||||
"external/builder/fixtures_babel/",
|
"external/builder/fixtures_babel/",
|
||||||
"external/quickjs/",
|
"external/quickjs/",
|
||||||
"external/openjpeg/",
|
"external/openjpeg/",
|
||||||
|
"test/stats/results/",
|
||||||
"test/tmp/",
|
"test/tmp/",
|
||||||
"test/pdfs/",
|
"test/pdfs/",
|
||||||
"web/locale/",
|
"web/locale/",
|
||||||
|
|||||||
@ -720,12 +720,12 @@ class Catalog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (obj instanceof Dict) {
|
} else if (obj instanceof Dict) {
|
||||||
obj.forEach(function (key, value) {
|
for (const [key, value] of obj) {
|
||||||
const dest = fetchDest(value);
|
const dest = fetchDest(value);
|
||||||
if (dest) {
|
if (dest) {
|
||||||
dests[key] = dest;
|
dests[key] = dest;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
return shadow(this, "destinations", dests);
|
return shadow(this, "destinations", dests);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1282,13 +1282,8 @@ class PDFDocument {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const fonts = new Map();
|
|
||||||
fontRes.forEach((fontName, font) => {
|
|
||||||
fonts.set(fontName, font);
|
|
||||||
});
|
|
||||||
const promises = [];
|
const promises = [];
|
||||||
|
for (const [fontName, font] of fontRes) {
|
||||||
for (const [fontName, font] of fonts) {
|
|
||||||
const descriptor = font.get("FontDescriptor");
|
const descriptor = font.get("FontDescriptor");
|
||||||
if (!(descriptor instanceof Dict)) {
|
if (!(descriptor instanceof Dict)) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@ -69,7 +69,7 @@ const nonSerializable = function nonSerializableClosure() {
|
|||||||
class Dict {
|
class Dict {
|
||||||
constructor(xref = null) {
|
constructor(xref = null) {
|
||||||
// Map should only be used internally, use functions below to access.
|
// Map should only be used internally, use functions below to access.
|
||||||
this._map = Object.create(null);
|
this._map = new Map();
|
||||||
this.xref = xref;
|
this.xref = xref;
|
||||||
this.objId = null;
|
this.objId = null;
|
||||||
this.suppressEncryption = false;
|
this.suppressEncryption = false;
|
||||||
@ -81,12 +81,12 @@ class Dict {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get size() {
|
get size() {
|
||||||
return Object.keys(this._map).length;
|
return this._map.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automatically dereferences Ref objects.
|
// Automatically dereferences Ref objects.
|
||||||
get(key1, key2, key3) {
|
get(key1, key2, key3) {
|
||||||
let value = this._map[key1];
|
let value = this._map.get(key1);
|
||||||
if (value === undefined && key2 !== undefined) {
|
if (value === undefined && key2 !== undefined) {
|
||||||
if (
|
if (
|
||||||
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
||||||
@ -94,7 +94,7 @@ class Dict {
|
|||||||
) {
|
) {
|
||||||
unreachable("Dict.get: Expected keys to be ordered by length.");
|
unreachable("Dict.get: Expected keys to be ordered by length.");
|
||||||
}
|
}
|
||||||
value = this._map[key2];
|
value = this._map.get(key2);
|
||||||
if (value === undefined && key3 !== undefined) {
|
if (value === undefined && key3 !== undefined) {
|
||||||
if (
|
if (
|
||||||
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
||||||
@ -102,7 +102,7 @@ class Dict {
|
|||||||
) {
|
) {
|
||||||
unreachable("Dict.get: Expected keys to be ordered by length.");
|
unreachable("Dict.get: Expected keys to be ordered by length.");
|
||||||
}
|
}
|
||||||
value = this._map[key3];
|
value = this._map.get(key3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (value instanceof Ref && this.xref) {
|
if (value instanceof Ref && this.xref) {
|
||||||
@ -113,7 +113,7 @@ class Dict {
|
|||||||
|
|
||||||
// Same as get(), but returns a promise and uses fetchIfRefAsync().
|
// Same as get(), but returns a promise and uses fetchIfRefAsync().
|
||||||
async getAsync(key1, key2, key3) {
|
async getAsync(key1, key2, key3) {
|
||||||
let value = this._map[key1];
|
let value = this._map.get(key1);
|
||||||
if (value === undefined && key2 !== undefined) {
|
if (value === undefined && key2 !== undefined) {
|
||||||
if (
|
if (
|
||||||
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
||||||
@ -121,7 +121,7 @@ class Dict {
|
|||||||
) {
|
) {
|
||||||
unreachable("Dict.getAsync: Expected keys to be ordered by length.");
|
unreachable("Dict.getAsync: Expected keys to be ordered by length.");
|
||||||
}
|
}
|
||||||
value = this._map[key2];
|
value = this._map.get(key2);
|
||||||
if (value === undefined && key3 !== undefined) {
|
if (value === undefined && key3 !== undefined) {
|
||||||
if (
|
if (
|
||||||
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
||||||
@ -129,7 +129,7 @@ class Dict {
|
|||||||
) {
|
) {
|
||||||
unreachable("Dict.getAsync: Expected keys to be ordered by length.");
|
unreachable("Dict.getAsync: Expected keys to be ordered by length.");
|
||||||
}
|
}
|
||||||
value = this._map[key3];
|
value = this._map.get(key3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (value instanceof Ref && this.xref) {
|
if (value instanceof Ref && this.xref) {
|
||||||
@ -140,7 +140,7 @@ class Dict {
|
|||||||
|
|
||||||
// Same as get(), but dereferences all elements if the result is an Array.
|
// Same as get(), but dereferences all elements if the result is an Array.
|
||||||
getArray(key1, key2, key3) {
|
getArray(key1, key2, key3) {
|
||||||
let value = this._map[key1];
|
let value = this._map.get(key1);
|
||||||
if (value === undefined && key2 !== undefined) {
|
if (value === undefined && key2 !== undefined) {
|
||||||
if (
|
if (
|
||||||
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
||||||
@ -148,7 +148,7 @@ class Dict {
|
|||||||
) {
|
) {
|
||||||
unreachable("Dict.getArray: Expected keys to be ordered by length.");
|
unreachable("Dict.getArray: Expected keys to be ordered by length.");
|
||||||
}
|
}
|
||||||
value = this._map[key2];
|
value = this._map.get(key2);
|
||||||
if (value === undefined && key3 !== undefined) {
|
if (value === undefined && key3 !== undefined) {
|
||||||
if (
|
if (
|
||||||
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
||||||
@ -156,7 +156,7 @@ class Dict {
|
|||||||
) {
|
) {
|
||||||
unreachable("Dict.getArray: Expected keys to be ordered by length.");
|
unreachable("Dict.getArray: Expected keys to be ordered by length.");
|
||||||
}
|
}
|
||||||
value = this._map[key3];
|
value = this._map.get(key3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (value instanceof Ref && this.xref) {
|
if (value instanceof Ref && this.xref) {
|
||||||
@ -176,16 +176,16 @@ class Dict {
|
|||||||
|
|
||||||
// No dereferencing.
|
// No dereferencing.
|
||||||
getRaw(key) {
|
getRaw(key) {
|
||||||
return this._map[key];
|
return this._map.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
getKeys() {
|
getKeys() {
|
||||||
return Object.keys(this._map);
|
return [...this._map.keys()];
|
||||||
}
|
}
|
||||||
|
|
||||||
// No dereferencing.
|
// No dereferencing.
|
||||||
getRawValues() {
|
getRawValues() {
|
||||||
return Object.values(this._map);
|
return [...this._map.values()];
|
||||||
}
|
}
|
||||||
|
|
||||||
set(key, value) {
|
set(key, value) {
|
||||||
@ -196,16 +196,21 @@ class Dict {
|
|||||||
unreachable('Dict.set: The "value" cannot be undefined.');
|
unreachable('Dict.set: The "value" cannot be undefined.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._map[key] = value;
|
this._map.set(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
has(key) {
|
has(key) {
|
||||||
return this._map[key] !== undefined;
|
return this._map.has(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
forEach(callback) {
|
*[Symbol.iterator]() {
|
||||||
for (const key in this._map) {
|
for (const [key, value] of this._map) {
|
||||||
callback(key, this.get(key));
|
yield [
|
||||||
|
key,
|
||||||
|
value instanceof Ref && this.xref
|
||||||
|
? this.xref.fetch(value, this.suppressEncryption)
|
||||||
|
: value,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +231,7 @@ class Dict {
|
|||||||
if (!(dict instanceof Dict)) {
|
if (!(dict instanceof Dict)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (const [key, value] of Object.entries(dict._map)) {
|
for (const [key, value] of dict._map) {
|
||||||
let property = properties.get(key);
|
let property = properties.get(key);
|
||||||
if (property === undefined) {
|
if (property === undefined) {
|
||||||
property = [];
|
property = [];
|
||||||
@ -242,20 +247,20 @@ class Dict {
|
|||||||
}
|
}
|
||||||
for (const [name, values] of properties) {
|
for (const [name, values] of properties) {
|
||||||
if (values.length === 1 || !(values[0] instanceof Dict)) {
|
if (values.length === 1 || !(values[0] instanceof Dict)) {
|
||||||
mergedDict._map[name] = values[0];
|
mergedDict._map.set(name, values[0]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const subDict = new Dict(xref);
|
const subDict = new Dict(xref);
|
||||||
|
|
||||||
for (const dict of values) {
|
for (const dict of values) {
|
||||||
for (const [key, value] of Object.entries(dict._map)) {
|
for (const [key, value] of dict._map) {
|
||||||
if (subDict._map[key] === undefined) {
|
if (!subDict._map.has(key)) {
|
||||||
subDict._map[key] = value;
|
subDict._map.set(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (subDict.size > 0) {
|
if (subDict.size > 0) {
|
||||||
mergedDict._map[name] = subDict;
|
mergedDict._map.set(name, subDict);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
properties.clear();
|
properties.clear();
|
||||||
|
|||||||
@ -62,12 +62,11 @@ class StructTreeRoot {
|
|||||||
if (!(roleMapDict instanceof Dict)) {
|
if (!(roleMapDict instanceof Dict)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
roleMapDict.forEach((key, value) => {
|
for (const [key, value] of roleMapDict) {
|
||||||
if (!(value instanceof Name)) {
|
if (value instanceof Name) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.roleMap.set(key, value.name);
|
this.roleMap.set(key, value.name);
|
||||||
});
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async canCreateStructureTree({
|
static async canCreateStructureTree({
|
||||||
|
|||||||
@ -688,11 +688,11 @@ class WorkerMessageHandler {
|
|||||||
const infoObj = Object.create(null);
|
const infoObj = Object.create(null);
|
||||||
const xrefInfo = xref.trailer.get("Info") || null;
|
const xrefInfo = xref.trailer.get("Info") || null;
|
||||||
if (xrefInfo instanceof Dict) {
|
if (xrefInfo instanceof Dict) {
|
||||||
xrefInfo.forEach((key, value) => {
|
for (const [key, value] of xrefInfo) {
|
||||||
if (typeof value === "string") {
|
if (typeof value === "string") {
|
||||||
infoObj[key] = stringToPDFString(value);
|
infoObj[key] = stringToPDFString(value);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newXrefInfo = {
|
newXrefInfo = {
|
||||||
|
|||||||
@ -80,7 +80,7 @@ const pdfjsVersion =
|
|||||||
const pdfjsBuild =
|
const pdfjsBuild =
|
||||||
typeof PDFJSDev !== "undefined" ? PDFJSDev.eval("BUNDLE_BUILD") : void 0;
|
typeof PDFJSDev !== "undefined" ? PDFJSDev.eval("BUNDLE_BUILD") : void 0;
|
||||||
|
|
||||||
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING")) {
|
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING || GENERIC")) {
|
||||||
globalThis.pdfjsTestingUtils = {
|
globalThis.pdfjsTestingUtils = {
|
||||||
HighlightOutliner,
|
HighlightOutliner,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -221,17 +221,12 @@ describe("primitives", function () {
|
|||||||
expect(values[2]).toEqual(testFontFile);
|
expect(values[2]).toEqual(testFontFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should callback for each stored key", function () {
|
it("should iterate through each stored key", function () {
|
||||||
const callbackSpy = jasmine.createSpy("spy on callback in dictionary");
|
expect([...dictWithManyKeys]).toEqual([
|
||||||
|
["FontFile", testFontFile],
|
||||||
dictWithManyKeys.forEach(callbackSpy);
|
["FontFile2", testFontFile2],
|
||||||
|
["FontFile3", testFontFile3],
|
||||||
expect(callbackSpy).toHaveBeenCalled();
|
]);
|
||||||
const callbackSpyCalls = callbackSpy.calls;
|
|
||||||
expect(callbackSpyCalls.argsFor(0)).toEqual(["FontFile", testFontFile]);
|
|
||||||
expect(callbackSpyCalls.argsFor(1)).toEqual(["FontFile2", testFontFile2]);
|
|
||||||
expect(callbackSpyCalls.argsFor(2)).toEqual(["FontFile3", testFontFile3]);
|
|
||||||
expect(callbackSpyCalls.count()).toEqual(3);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should handle keys pointing to indirect objects, both sync and async", async function () {
|
it("should handle keys pointing to indirect objects, both sync and async", async function () {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user