UNPKG

xcom2charpool

Version:

Library for reading, manipulating, and managing XCOM 2 character pool binary files, supporting both browser and Node.js environments.

153 lines (152 loc) 7.7 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _ArrayBufferWriter_length, _ArrayBufferWriter_buffer, _ArrayBufferWriter_dataView; Object.defineProperty(exports, "__esModule", { value: true }); exports.ArrayBufferWriter = void 0; /** Implementation based on browser's DataView */ class ArrayBufferWriter { constructor(initialSize = 1024) { this.position = 0; _ArrayBufferWriter_length.set(this, 0); // Actual length of data written _ArrayBufferWriter_buffer.set(this, void 0); _ArrayBufferWriter_dataView.set(this, void 0); __classPrivateFieldSet(this, _ArrayBufferWriter_buffer, new ArrayBuffer(initialSize), "f"); __classPrivateFieldSet(this, _ArrayBufferWriter_dataView, new DataView(__classPrivateFieldGet(this, _ArrayBufferWriter_buffer, "f")), "f"); } /** * Ensures the internal buffer has enough capacity to write additional bytes. */ ensureCapacity(additionalBytes) { const requiredLength = this.position + additionalBytes; if (requiredLength > __classPrivateFieldGet(this, _ArrayBufferWriter_buffer, "f").byteLength) { // Need to resize buffer let newBufferLength = __classPrivateFieldGet(this, _ArrayBufferWriter_buffer, "f").byteLength * 2; while (newBufferLength < requiredLength) { newBufferLength *= 2; } const newBuffer = new ArrayBuffer(newBufferLength); new Uint8Array(newBuffer).set(new Uint8Array(__classPrivateFieldGet(this, _ArrayBufferWriter_buffer, "f"))); __classPrivateFieldSet(this, _ArrayBufferWriter_buffer, newBuffer, "f"); __classPrivateFieldSet(this, _ArrayBufferWriter_dataView, new DataView(__classPrivateFieldGet(this, _ArrayBufferWriter_buffer, "f")), "f"); } } /** * Writes a 32-bit unsigned integer at the current position. */ uint32(value) { this.ensureCapacity(4); __classPrivateFieldGet(this, _ArrayBufferWriter_dataView, "f").setUint32(this.position, value, true); this.position += 4; __classPrivateFieldSet(this, _ArrayBufferWriter_length, Math.max(__classPrivateFieldGet(this, _ArrayBufferWriter_length, "f"), this.position), "f"); return this; } /** * Writes a 32-bit signed integer at the current position. */ int32(value) { this.ensureCapacity(4); __classPrivateFieldGet(this, _ArrayBufferWriter_dataView, "f").setInt32(this.position, value, true); this.position += 4; __classPrivateFieldSet(this, _ArrayBufferWriter_length, Math.max(__classPrivateFieldGet(this, _ArrayBufferWriter_length, "f"), this.position), "f"); return this; } /** * Writes a byte at the current position. */ byte(value) { this.ensureCapacity(1); __classPrivateFieldGet(this, _ArrayBufferWriter_dataView, "f").setUint8(this.position, value); this.position += 1; __classPrivateFieldSet(this, _ArrayBufferWriter_length, Math.max(__classPrivateFieldGet(this, _ArrayBufferWriter_length, "f"), this.position), "f"); return this; } /** * Writes padding (4 zero bytes) at the current position. */ padding() { this.uint32(0); return this; } /** * Encodes a string into a Uint8Array using UTF-16LE encoding. */ encodeUTF16LE(str) { const buf = new ArrayBuffer(str.length * 2); const bufView = new Uint16Array(buf); for (let i = 0; i < str.length; i++) { bufView[i] = str.charCodeAt(i); } return new Uint8Array(buf); } encodeASCII(str) { const buf = new ArrayBuffer(str.length); const bufView = new Uint8Array(buf); for (let i = 0; i < str.length; i++) { bufView[i] = str.charCodeAt(i); } return bufView; } /** * Writes a string with a length prefix and null-termination. * Automatically detects the encoding based on the characters used. * Uses UTF-8 for ASCII strings and UTF-16LE for strings with non-ASCII characters. */ string(value) { if (value === '') { this.int32(0); return this; } // Detect if the string contains any non-ASCII characters // eslint-disable-next-line no-control-regex const isAscii = /^[\x00-\xFF]*$/.test(value); let encoded; if (isAscii) { // Use UTF-8 encoding encoded = this.encodeASCII(value); // Add null terminator const totalLength = encoded.length + 1; this.int32(totalLength); this.ensureCapacity(totalLength); const targetArray = new Uint8Array(__classPrivateFieldGet(this, _ArrayBufferWriter_buffer, "f"), this.position, totalLength); targetArray.set(encoded); targetArray[encoded.length] = 0x00; // null terminator this.position += totalLength; __classPrivateFieldSet(this, _ArrayBufferWriter_length, Math.max(__classPrivateFieldGet(this, _ArrayBufferWriter_length, "f"), this.position), "f"); } else { // Use UTF-16LE encoding encoded = this.encodeUTF16LE(value); // Add null terminator (two bytes) const totalLength = encoded.length + 2; const lengthPrefix = -((encoded.length + 2) / 2); // Negative length in number of 16-bit code units this.int32(lengthPrefix); this.ensureCapacity(totalLength); const targetArray = new Uint8Array(__classPrivateFieldGet(this, _ArrayBufferWriter_buffer, "f"), this.position, totalLength); targetArray.set(encoded); targetArray[encoded.length] = 0x00; // null terminator (low byte) targetArray[encoded.length + 1] = 0x00; // null terminator (high byte) this.position += totalLength; __classPrivateFieldSet(this, _ArrayBufferWriter_length, Math.max(__classPrivateFieldGet(this, _ArrayBufferWriter_length, "f"), this.position), "f"); } return this; } /** * Retrieves the underlying buffer up to the current length of data written. * @returns A sliced ArrayBuffer containing the written data. */ getBuffer() { return __classPrivateFieldGet(this, _ArrayBufferWriter_buffer, "f").slice(0, __classPrivateFieldGet(this, _ArrayBufferWriter_length, "f")); } } exports.ArrayBufferWriter = ArrayBufferWriter; _ArrayBufferWriter_length = new WeakMap(), _ArrayBufferWriter_buffer = new WeakMap(), _ArrayBufferWriter_dataView = new WeakMap();