UNPKG

xcom2charpool

Version:

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

102 lines (101 loc) 5.78 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 _ArrayBufferReader_position, _ArrayBufferReader_length; Object.defineProperty(exports, "__esModule", { value: true }); exports.ArrayBufferReader = void 0; /** Implementation based on browser's DataView */ class ArrayBufferReader { constructor(source, position, length) { this.source = source; _ArrayBufferReader_position.set(this, 0); _ArrayBufferReader_length.set(this, void 0); if (typeof position === 'number') { __classPrivateFieldSet(this, _ArrayBufferReader_position, position, "f"); } __classPrivateFieldSet(this, _ArrayBufferReader_length, typeof length === 'number' ? length : source.byteLength, "f"); } get length() { return __classPrivateFieldGet(this, _ArrayBufferReader_length, "f"); } get position() { return __classPrivateFieldGet(this, _ArrayBufferReader_position, "f"); } rewind(offset) { const newPosition = __classPrivateFieldGet(this, _ArrayBufferReader_position, "f") + offset; if (newPosition < 0 || newPosition > this.length) { throw new Error('Rewind results in invalid position'); } __classPrivateFieldSet(this, _ArrayBufferReader_position, newPosition, "f"); } uint32() { if (__classPrivateFieldGet(this, _ArrayBufferReader_position, "f") + 4 > this.length) { throw new Error('Attempt to read beyond buffer length in uint32'); } const value = this.source.getUint32(__classPrivateFieldGet(this, _ArrayBufferReader_position, "f"), true); __classPrivateFieldSet(this, _ArrayBufferReader_position, __classPrivateFieldGet(this, _ArrayBufferReader_position, "f") + 4, "f"); return value; } int32() { if (__classPrivateFieldGet(this, _ArrayBufferReader_position, "f") + 4 > this.length) { throw new Error('Attempt to read beyond buffer length in int32'); } const value = this.source.getInt32(__classPrivateFieldGet(this, _ArrayBufferReader_position, "f"), true); __classPrivateFieldSet(this, _ArrayBufferReader_position, __classPrivateFieldGet(this, _ArrayBufferReader_position, "f") + 4, "f"); return value; } byte() { if (__classPrivateFieldGet(this, _ArrayBufferReader_position, "f") + 1 > this.length) { throw new Error('Attempt to read beyond buffer length in byte'); } const value = this.source.getUint8(__classPrivateFieldGet(this, _ArrayBufferReader_position, "f")); __classPrivateFieldSet(this, _ArrayBufferReader_position, __classPrivateFieldGet(this, _ArrayBufferReader_position, "f") + 1, "f"); return value; } padding() { const padding = this.uint32(); if (padding) { throw new Error(`Expected empty padding, got ${padding.toString(16).padStart(8, '0')}`); } } subarray(length) { const sub = new ArrayBufferReader(this.source, __classPrivateFieldGet(this, _ArrayBufferReader_position, "f"), __classPrivateFieldGet(this, _ArrayBufferReader_position, "f") + length); __classPrivateFieldSet(this, _ArrayBufferReader_position, __classPrivateFieldGet(this, _ArrayBufferReader_position, "f") + length, "f"); return sub; } string() { let length = this.int32(); if (length === 0) return ''; const isUTF16 = length < 0; // Adjust length for UTF-16 encoding if (isUTF16) length = length * -2; if (__classPrivateFieldGet(this, _ArrayBufferReader_position, "f") + length > this.length) { throw new Error('Attempt to read beyond buffer length in string'); } const start = this.source.byteOffset + __classPrivateFieldGet(this, _ArrayBufferReader_position, "f"); const bytes = new Uint8Array(this.source.buffer, start, length); __classPrivateFieldSet(this, _ArrayBufferReader_position, __classPrivateFieldGet(this, _ArrayBufferReader_position, "f") + length, "f"); if (bytes[bytes.length - 1] !== 0x00) { // Strings are expected to be null-terminated throw new Error(`Incorrect string size ${length}`); } const decoder = isUTF16 ? ArrayBufferReader.utf16Decoder : ArrayBufferReader.ASCIIDecoder; // Exclude the null terminator return decoder.decode(bytes.subarray(0, bytes.length - (isUTF16 ? 2 : 1))); } } exports.ArrayBufferReader = ArrayBufferReader; _ArrayBufferReader_position = new WeakMap(), _ArrayBufferReader_length = new WeakMap(); ArrayBufferReader.ASCIIDecoder = new TextDecoder('windows-1252'); ArrayBufferReader.utf16Decoder = new TextDecoder('utf-16le');