Re-factor the arraysToBytes helper function (PR 16032 follow-up)

Currently this helper function only has two call-sites, and both of them only pass in `ArrayBuffer` data. Given how it's implemented there's a couple of code-paths that are completely unused (e.g. the "string" one), and in particular the intended fast-paths don't actually work.
This patch re-factors and simplifies the helper function, and it'll no longer accept anything except `ArrayBuffer` data (hence why it's also re-named).

Note that at the time when `arraysToBytes` was added we still supported browsers without TypedArray functionality, and we'd then simulate them using regular Arrays.
This commit is contained in:
Jonas Jenwald 2023-02-09 22:01:23 +01:00
parent 5ba596786c
commit c56f25409d
3 changed files with 34 additions and 46 deletions

View File

@ -14,7 +14,7 @@
*/ */
import { import {
arraysToBytes, arrayBuffersToBytes,
assert, assert,
createPromiseCapability, createPromiseCapability,
} from "../shared/util.js"; } from "../shared/util.js";
@ -294,7 +294,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;

View File

@ -15,7 +15,7 @@
import { import {
AbortException, AbortException,
arraysToBytes, arrayBuffersToBytes,
assert, assert,
createPromiseCapability, createPromiseCapability,
getVerbosityLevel, getVerbosityLevel,
@ -281,7 +281,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");
} }

View File

@ -598,51 +598,39 @@ function stringToBytes(str) {
} }
/** /**
* Gets length of the array (Array, Uint8Array, or string) in bytes. * Combines multiple ArrayBuffers into a single Uint8Array.
* @param {Array<any>|Uint8Array|string} arr * @param {Array<ArrayBuffer>} arr - An array of ArrayBuffers.
* @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} * @returns {Uint8Array}
*/ */
function arraysToBytes(arr) { function arrayBuffersToBytes(arr) {
const length = arr.length; if (
// Shortcut: if first and only item is Uint8Array, return it. typeof PDFJSDev === "undefined" ||
if (length === 1 && arr[0] instanceof Uint8Array) { PDFJSDev.test("!PRODUCTION || TESTING")
return arr[0]; ) {
} for (const item of arr) {
let resultLength = 0; assert(
for (let i = 0; i < length; i++) { item instanceof ArrayBuffer,
resultLength += arrayByteLength(arr[i]); "arrayBuffersToBytes - expected an ArrayBuffer."
} );
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; }
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); data.set(item, pos);
pos += itemLength; pos += item.byteLength;
} }
return data; return data;
} }
@ -1115,7 +1103,7 @@ export {
AnnotationReviewState, AnnotationReviewState,
AnnotationStateModelType, AnnotationStateModelType,
AnnotationType, AnnotationType,
arraysToBytes, arrayBuffersToBytes,
assert, assert,
BaseException, BaseException,
BASELINE_FACTOR, BASELINE_FACTOR,