UNPKG

arx-convert

Version:

Converts various Arx Fatalis formats to JSON or YAML and back

311 lines 9.1 kB
import { LITTLE_ENDIAN, TRUNCATE_ZERO_BYTES, KEEP_ZERO_BYTES, BYTE_OF_AN_UNKNOWN_CHAR } from './constants.js'; import { decodeText, encodeText, repeat } from './helpers.js'; export class BinaryIO extends DataView { static sizeOfFloat32() { return 4; } static sizeOfFloat32Array(length) { return length * BinaryIO.sizeOfFloat32(); } static sizeOfInt8() { return 1; } static sizeOfInt8Array(length) { return length * BinaryIO.sizeOfInt8(); } static sizeOfInt16() { return 2; } static sizeOfInt16Array(length) { return length * BinaryIO.sizeOfInt16(); } static sizeOfInt32() { return 4; } static sizeOfInt32Array(length) { return length * BinaryIO.sizeOfInt32(); } static sizeOfUint8() { return 1; } static sizeOfUint8Array(length) { return length * BinaryIO.sizeOfUint8(); } static sizeOfUint16() { return 2; } static sizeOfUint16Array(length) { return length * BinaryIO.sizeOfUint16(); } static sizeOfUint32() { return 4; } static sizeOfUint32Array(length) { return length * BinaryIO.sizeOfUint32(); } static sizeOfString(length) { return length; } static sizeOfNullTerminatedString(str) { return str.length + 1; } static sizeOfVector3() { return BinaryIO.sizeOfFloat32Array(3); } static sizeOfVector3Array(length) { return length * BinaryIO.sizeOfVector3(); } static sizeOfRotation() { return BinaryIO.sizeOfFloat32Array(3); } static sizeOfQuat() { return BinaryIO.sizeOfFloat32Array(4); } position; // TODO: make this private - this needs to be public because of TEA constructor(buffer, byteOffset, byteLength) { super(buffer, byteOffset, byteLength); this.position = 0; } readFloat32() { const val = this.getFloat32(this.position, LITTLE_ENDIAN); this.position = this.position + BinaryIO.sizeOfFloat32(); return val; } readFloat32Array(length) { const arr = []; for (let i = 0; i < length; i++) { arr.push(this.readFloat32()); } return arr; } readInt8() { const val = this.getInt8(this.position); this.position = this.position + BinaryIO.sizeOfInt8(); return val; } readInt8Array(length) { const arr = []; for (let i = 0; i < length; i++) { arr.push(this.readInt8()); } return arr; } readInt16() { const val = this.getInt16(this.position, LITTLE_ENDIAN); this.position = this.position + BinaryIO.sizeOfInt16(); return val; } readInt16Array(length) { const arr = []; for (let i = 0; i < length; i++) { arr.push(this.readInt16()); } return arr; } readInt32() { const val = this.getInt32(this.position, LITTLE_ENDIAN); this.position = this.position + BinaryIO.sizeOfInt32(); return val; } readInt32Array(length) { const arr = []; for (let i = 0; i < length; i++) { arr.push(this.readInt32()); } return arr; } readUint8() { const val = this.getUint8(this.position); this.position = this.position + BinaryIO.sizeOfUint8(); return val; } readUint8Array(length) { const arr = []; for (let i = 0; i < length; i++) { arr.push(this.readUint8()); } return arr; } readUint16() { const val = this.getUint16(this.position, LITTLE_ENDIAN); this.position = this.position + BinaryIO.sizeOfUint16(); return val; } readUint16Array(length) { const arr = []; for (let i = 0; i < length; i++) { arr.push(this.readUint16()); } return arr; } readUint32() { const val = this.getUint32(this.position, LITTLE_ENDIAN); this.position = this.position + BinaryIO.sizeOfUint32(); return val; } readUint32Array(length) { const arr = []; for (let i = 0; i < length; i++) { arr.push(this.readUint32()); } return arr; } writeFloat32(value) { this.setFloat32(this.position, value, LITTLE_ENDIAN); this.position = this.position + BinaryIO.sizeOfFloat32(); } writeFloat32Array(values) { values.forEach((value) => { this.writeFloat32(value); }); } writeInt8(value) { this.setInt8(this.position, value); this.position = this.position + BinaryIO.sizeOfInt8(); } writeInt8Array(values) { values.forEach((value) => { this.writeInt8(value); }); } writeInt16(value) { this.setInt16(this.position, value, LITTLE_ENDIAN); this.position = this.position + BinaryIO.sizeOfInt16(); } writeInt16Array(values) { values.forEach((value) => { this.writeInt16(value); }); } writeInt32(value) { this.setInt32(this.position, value, LITTLE_ENDIAN); this.position = this.position + BinaryIO.sizeOfInt32(); } writeInt32Array(values) { values.forEach((value) => { this.writeInt32(value); }); } writeUint8(value) { this.setUint8(this.position, value); this.position = this.position + BinaryIO.sizeOfUint8(); } writeUint8Array(values) { if (Array.isArray(values)) { values.forEach((value) => { this.writeUint8(value); }); } else { new Uint8Array(values).forEach((value) => { this.writeUint8(value); }); } } writeUint16(value) { this.setUint16(this.position, value, LITTLE_ENDIAN); this.position = this.position + BinaryIO.sizeOfUint16(); } writeUint16Array(values) { values.forEach((value) => { this.writeUint16(value); }); } writeUint32(value) { this.setUint32(this.position, value, LITTLE_ENDIAN); this.position = this.position + BinaryIO.sizeOfUint32(); } writeUint32Array(values) { values.forEach((value) => { this.writeUint32(value); }); } readString(length, truncateZeroBytes = TRUNCATE_ZERO_BYTES) { const codes = []; if (length === undefined) { let c = this.readUint8(); while (c !== 0) { codes.push(c); c = this.readUint8(); } } else { let gotNil = false; for (let i = 0; i < length; i++) { const c = this.readUint8(); if (gotNil && truncateZeroBytes === TRUNCATE_ZERO_BYTES) { continue; } if (c === 0) { gotNil = true; } if (c !== 0 || truncateZeroBytes === KEEP_ZERO_BYTES) { if (c === 0) { codes.push(BYTE_OF_AN_UNKNOWN_CHAR); } else { codes.push(c); } } } } return decodeText(codes); } writeString(str, length) { // if length is given we assume a fixed length string if (length === undefined) { // otherwise its a 0 terminated c string encodeText(str).forEach((charCode) => { this.writeUint8(charCode); }); this.writeUint8(0); } else { const charCodes = repeat(0, length); // replacing 0s in charCodes one by one from left to right encodeText(str).forEach((charCode, index) => { charCodes[index] = charCode; }); charCodes.forEach((charCode) => { this.writeUint8(charCode); }); } } readVector3() { const [x, y, z] = this.readFloat32Array(3); return { x, y, z }; } readVector3Array(length) { const arr = []; for (let i = 0; i < length; i++) { arr.push(this.readVector3()); } return arr; } writeVector3({ x, y, z }) { this.writeFloat32Array([x, y, z]); } writeVector3Array(values) { values.forEach((value) => { this.writeVector3(value); }); } readRotation() { const [a, b, g] = this.readFloat32Array(3); return { a, b, g }; } writeRotation({ a, b, g }) { this.writeFloat32Array([a, b, g]); } readQuat() { const [w, x, y, z] = this.readFloat32Array(4); return { x, y, z, w }; } writeQuat({ x, y, z, w }) { this.writeFloat32Array([w, x, y, z]); } writeBuffer(buffer) { this.writeUint8Array(buffer); } } //# sourceMappingURL=BinaryIO.js.map