mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-06-23 08:25:48 +02:00
Given that both of these classes are so similar, let's replace them with a single `DataBuilder` class instead to reduce unnecessary code-duplication.
126 lines
3.1 KiB
JavaScript
126 lines
3.1 KiB
JavaScript
/* Copyright 2026 Mozilla Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import { assert } from "../shared/util.js";
|
|
import { MathClamp } from "../shared/math_clamp.js";
|
|
|
|
class DataBuilder {
|
|
#buf;
|
|
|
|
#bufLength = 1024;
|
|
|
|
#hasExactLength = false;
|
|
|
|
#pos = 0;
|
|
|
|
#view;
|
|
|
|
constructor({ exactLength = 0, minLength = 0 }) {
|
|
this.#hasExactLength = !!exactLength;
|
|
this.#initBuf(exactLength || minLength);
|
|
}
|
|
|
|
#initBuf(minLength) {
|
|
if (this.#hasExactLength) {
|
|
this.#bufLength = minLength;
|
|
} else {
|
|
// Compute the first power of two that is as big as the `minLength`.
|
|
while (this.#bufLength < minLength) {
|
|
this.#bufLength *= 2;
|
|
}
|
|
}
|
|
const newBuf = new Uint8Array(this.#bufLength);
|
|
|
|
if (this.#buf) {
|
|
newBuf.set(this.#buf, 0);
|
|
}
|
|
this.#buf = newBuf;
|
|
this.#view = new DataView(newBuf.buffer);
|
|
}
|
|
|
|
get data() {
|
|
return this.#buf.subarray(0, this.#pos);
|
|
}
|
|
|
|
get length() {
|
|
return this.#pos;
|
|
}
|
|
|
|
skip(n) {
|
|
this.#pos += n;
|
|
}
|
|
|
|
setArray(arr) {
|
|
const newPos = this.#pos + arr.length;
|
|
|
|
if (!this.#hasExactLength && newPos > this.#bufLength) {
|
|
this.#initBuf(newPos);
|
|
}
|
|
this.#buf.set(arr, this.#pos);
|
|
this.#pos = newPos;
|
|
}
|
|
|
|
setInt16(val) {
|
|
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
|
assert(
|
|
typeof val === "number" && Math.abs(val) < 2 ** 16,
|
|
`setInt16: Unexpected input "${val}".`
|
|
);
|
|
}
|
|
const newPos = this.#pos + 2;
|
|
|
|
if (!this.#hasExactLength && newPos > this.#bufLength) {
|
|
this.#initBuf(newPos);
|
|
}
|
|
this.#view.setInt16(this.#pos, val);
|
|
this.#pos = newPos;
|
|
}
|
|
|
|
setSafeInt16(val) {
|
|
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
|
assert(
|
|
typeof val === "number" && !Number.isNaN(val),
|
|
`safeString16: Unexpected input "${val}".`
|
|
);
|
|
}
|
|
const newPos = this.#pos + 2;
|
|
|
|
if (!this.#hasExactLength && newPos > this.#bufLength) {
|
|
this.#initBuf(newPos);
|
|
}
|
|
// clamp value to the 16-bit int range
|
|
this.#view.setInt16(this.#pos, MathClamp(val, -0x8000, 0x7fff));
|
|
this.#pos = newPos;
|
|
}
|
|
|
|
setInt32(val) {
|
|
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
|
assert(
|
|
typeof val === "number" && Math.abs(val) < 2 ** 32,
|
|
`setInt32: Unexpected input "${val}".`
|
|
);
|
|
}
|
|
const newPos = this.#pos + 4;
|
|
|
|
if (!this.#hasExactLength && newPos > this.#bufLength) {
|
|
this.#initBuf(newPos);
|
|
}
|
|
this.#view.setInt32(this.#pos, val);
|
|
this.#pos = newPos;
|
|
}
|
|
}
|
|
|
|
export { DataBuilder };
|