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
JavaScript
"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');