Merge pull request #16040 from Snuffleupagus/arrayBuffersToBytes
Re-factor the `arraysToBytes` helper function (PR 16032 follow-up)
This commit is contained in:
commit
22618213c7
@ -13,12 +13,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import { arrayBuffersToBytes, MissingDataException } from "./core_utils.js";
|
||||||
arraysToBytes,
|
import { assert, createPromiseCapability } from "../shared/util.js";
|
||||||
assert,
|
|
||||||
createPromiseCapability,
|
|
||||||
} from "../shared/util.js";
|
|
||||||
import { MissingDataException } from "./core_utils.js";
|
|
||||||
import { Stream } from "./stream.js";
|
import { Stream } from "./stream.js";
|
||||||
|
|
||||||
class ChunkedStream extends Stream {
|
class ChunkedStream extends Stream {
|
||||||
@ -294,7 +290,7 @@ class ChunkedStreamManager {
|
|||||||
const readChunk = ({ value, done }) => {
|
const readChunk = ({ value, done }) => {
|
||||||
try {
|
try {
|
||||||
if (done) {
|
if (done) {
|
||||||
const chunkData = arraysToBytes(chunks);
|
const chunkData = arrayBuffersToBytes(chunks);
|
||||||
chunks = null;
|
chunks = null;
|
||||||
resolve(chunkData);
|
resolve(chunkData);
|
||||||
return;
|
return;
|
||||||
|
@ -80,6 +80,44 @@ class XRefParseException extends BaseException {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combines multiple ArrayBuffers into a single Uint8Array.
|
||||||
|
* @param {Array<ArrayBuffer>} arr - An array of ArrayBuffers.
|
||||||
|
* @returns {Uint8Array}
|
||||||
|
*/
|
||||||
|
function arrayBuffersToBytes(arr) {
|
||||||
|
if (
|
||||||
|
typeof PDFJSDev === "undefined" ||
|
||||||
|
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||||
|
) {
|
||||||
|
for (const item of arr) {
|
||||||
|
assert(
|
||||||
|
item instanceof ArrayBuffer,
|
||||||
|
"arrayBuffersToBytes - expected an ArrayBuffer."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const length = arr.length;
|
||||||
|
if (length === 0) {
|
||||||
|
return new Uint8Array(0);
|
||||||
|
}
|
||||||
|
if (length === 1) {
|
||||||
|
return new Uint8Array(arr[0]);
|
||||||
|
}
|
||||||
|
let dataLength = 0;
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
dataLength += arr[i].byteLength;
|
||||||
|
}
|
||||||
|
const data = new Uint8Array(dataLength);
|
||||||
|
let pos = 0;
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
const item = new Uint8Array(arr[i]);
|
||||||
|
data.set(item, pos);
|
||||||
|
pos += item.byteLength;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of an inheritable property.
|
* Get the value of an inheritable property.
|
||||||
*
|
*
|
||||||
@ -579,6 +617,7 @@ function getRotationMatrix(rotation, width, height) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
arrayBuffersToBytes,
|
||||||
collectActions,
|
collectActions,
|
||||||
encodeToXmlString,
|
encodeToXmlString,
|
||||||
escapePDFName,
|
escapePDFName,
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
AbortException,
|
AbortException,
|
||||||
arraysToBytes,
|
|
||||||
assert,
|
assert,
|
||||||
createPromiseCapability,
|
createPromiseCapability,
|
||||||
getVerbosityLevel,
|
getVerbosityLevel,
|
||||||
@ -30,8 +29,12 @@ import {
|
|||||||
VerbosityLevel,
|
VerbosityLevel,
|
||||||
warn,
|
warn,
|
||||||
} from "../shared/util.js";
|
} from "../shared/util.js";
|
||||||
|
import {
|
||||||
|
arrayBuffersToBytes,
|
||||||
|
getNewAnnotationsMap,
|
||||||
|
XRefParseException,
|
||||||
|
} from "./core_utils.js";
|
||||||
import { Dict, Ref } from "./primitives.js";
|
import { Dict, Ref } from "./primitives.js";
|
||||||
import { getNewAnnotationsMap, XRefParseException } from "./core_utils.js";
|
|
||||||
import { LocalPdfManager, NetworkPdfManager } from "./pdf_manager.js";
|
import { LocalPdfManager, NetworkPdfManager } from "./pdf_manager.js";
|
||||||
import { clearGlobalCaches } from "./cleanup_helper.js";
|
import { clearGlobalCaches } from "./cleanup_helper.js";
|
||||||
import { incrementalUpdate } from "./writer.js";
|
import { incrementalUpdate } from "./writer.js";
|
||||||
@ -93,7 +96,7 @@ class WorkerMessageHandler {
|
|||||||
let pdfManager;
|
let pdfManager;
|
||||||
let terminated = false;
|
let terminated = false;
|
||||||
let cancelXHRs = null;
|
let cancelXHRs = null;
|
||||||
const WorkerTasks = [];
|
const WorkerTasks = new Set();
|
||||||
const verbosity = getVerbosityLevel();
|
const verbosity = getVerbosityLevel();
|
||||||
|
|
||||||
const { docId, apiVersion } = docParams;
|
const { docId, apiVersion } = docParams;
|
||||||
@ -151,13 +154,12 @@ class WorkerMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function startWorkerTask(task) {
|
function startWorkerTask(task) {
|
||||||
WorkerTasks.push(task);
|
WorkerTasks.add(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishWorkerTask(task) {
|
function finishWorkerTask(task) {
|
||||||
task.finish();
|
task.finish();
|
||||||
const i = WorkerTasks.indexOf(task);
|
WorkerTasks.delete(task);
|
||||||
WorkerTasks.splice(i, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadDocument(recoveryMode) {
|
async function loadDocument(recoveryMode) {
|
||||||
@ -277,7 +279,7 @@ class WorkerMessageHandler {
|
|||||||
|
|
||||||
let loaded = 0;
|
let loaded = 0;
|
||||||
const flushChunks = function () {
|
const flushChunks = function () {
|
||||||
const pdfFile = arraysToBytes(cachedChunks);
|
const pdfFile = arrayBuffersToBytes(cachedChunks);
|
||||||
if (length && pdfFile.length !== length) {
|
if (length && pdfFile.length !== length) {
|
||||||
warn("reported HTTP length is different from actual");
|
warn("reported HTTP length is different from actual");
|
||||||
}
|
}
|
||||||
|
@ -597,56 +597,6 @@ function stringToBytes(str) {
|
|||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets length of the array (Array, Uint8Array, or string) in bytes.
|
|
||||||
* @param {Array<any>|Uint8Array|string} arr
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
// eslint-disable-next-line consistent-return
|
|
||||||
function arrayByteLength(arr) {
|
|
||||||
if (arr.length !== undefined) {
|
|
||||||
return arr.length;
|
|
||||||
}
|
|
||||||
if (arr.byteLength !== undefined) {
|
|
||||||
return arr.byteLength;
|
|
||||||
}
|
|
||||||
unreachable("Invalid argument for arrayByteLength");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combines array items (arrays) into single Uint8Array object.
|
|
||||||
* @param {Array<Array<any>|Uint8Array|string>} arr - the array of the arrays
|
|
||||||
* (Array, Uint8Array, or string).
|
|
||||||
* @returns {Uint8Array}
|
|
||||||
*/
|
|
||||||
function arraysToBytes(arr) {
|
|
||||||
const length = arr.length;
|
|
||||||
// Shortcut: if first and only item is Uint8Array, return it.
|
|
||||||
if (length === 1 && arr[0] instanceof Uint8Array) {
|
|
||||||
return arr[0];
|
|
||||||
}
|
|
||||||
let resultLength = 0;
|
|
||||||
for (let i = 0; i < length; i++) {
|
|
||||||
resultLength += arrayByteLength(arr[i]);
|
|
||||||
}
|
|
||||||
let pos = 0;
|
|
||||||
const data = new Uint8Array(resultLength);
|
|
||||||
for (let i = 0; i < length; i++) {
|
|
||||||
let item = arr[i];
|
|
||||||
if (!(item instanceof Uint8Array)) {
|
|
||||||
if (typeof item === "string") {
|
|
||||||
item = stringToBytes(item);
|
|
||||||
} else {
|
|
||||||
item = new Uint8Array(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const itemLength = item.byteLength;
|
|
||||||
data.set(item, pos);
|
|
||||||
pos += itemLength;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
function string32(value) {
|
function string32(value) {
|
||||||
if (
|
if (
|
||||||
typeof PDFJSDev === "undefined" ||
|
typeof PDFJSDev === "undefined" ||
|
||||||
@ -1115,7 +1065,6 @@ export {
|
|||||||
AnnotationReviewState,
|
AnnotationReviewState,
|
||||||
AnnotationStateModelType,
|
AnnotationStateModelType,
|
||||||
AnnotationType,
|
AnnotationType,
|
||||||
arraysToBytes,
|
|
||||||
assert,
|
assert,
|
||||||
BaseException,
|
BaseException,
|
||||||
BASELINE_FACTOR,
|
BASELINE_FACTOR,
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Dict, Ref } from "../../src/core/primitives.js";
|
|
||||||
import {
|
import {
|
||||||
|
arrayBuffersToBytes,
|
||||||
encodeToXmlString,
|
encodeToXmlString,
|
||||||
escapePDFName,
|
escapePDFName,
|
||||||
escapeString,
|
escapeString,
|
||||||
@ -30,9 +30,36 @@ import {
|
|||||||
toRomanNumerals,
|
toRomanNumerals,
|
||||||
validateCSSFont,
|
validateCSSFont,
|
||||||
} from "../../src/core/core_utils.js";
|
} from "../../src/core/core_utils.js";
|
||||||
|
import { Dict, Ref } from "../../src/core/primitives.js";
|
||||||
import { XRefMock } from "./test_utils.js";
|
import { XRefMock } from "./test_utils.js";
|
||||||
|
|
||||||
describe("core_utils", function () {
|
describe("core_utils", function () {
|
||||||
|
describe("arrayBuffersToBytes", function () {
|
||||||
|
it("handles zero ArrayBuffers", function () {
|
||||||
|
const bytes = arrayBuffersToBytes([]);
|
||||||
|
|
||||||
|
expect(bytes).toEqual(new Uint8Array(0));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("handles one ArrayBuffer", function () {
|
||||||
|
const buffer = new Uint8Array([1, 2, 3]).buffer;
|
||||||
|
const bytes = arrayBuffersToBytes([buffer]);
|
||||||
|
|
||||||
|
expect(bytes).toEqual(new Uint8Array([1, 2, 3]));
|
||||||
|
// Ensure that the fast-path works correctly.
|
||||||
|
expect(bytes.buffer).toBe(buffer);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("handles multiple ArrayBuffers", function () {
|
||||||
|
const buffer1 = new Uint8Array([1, 2, 3]).buffer,
|
||||||
|
buffer2 = new Uint8Array(0).buffer,
|
||||||
|
buffer3 = new Uint8Array([4, 5]).buffer;
|
||||||
|
const bytes = arrayBuffersToBytes([buffer1, buffer2, buffer3]);
|
||||||
|
|
||||||
|
expect(bytes).toEqual(new Uint8Array([1, 2, 3, 4, 5]));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("getInheritableProperty", function () {
|
describe("getInheritableProperty", function () {
|
||||||
it("handles non-dictionary arguments", function () {
|
it("handles non-dictionary arguments", function () {
|
||||||
expect(getInheritableProperty({ dict: null, key: "foo" })).toEqual(
|
expect(getInheritableProperty({ dict: null, key: "foo" })).toEqual(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user