@etothepii/satisfactory-file-parser
Version:
A file parser for satisfactory files. Includes save files and blueprint files.
128 lines (127 loc) • 5.04 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ByteReader = void 0;
const alignment_enum_1 = require("./alignment.enum");
class ByteReader {
constructor(fileBuffer, alignment) {
this.debug = false;
this.currentByte = 0;
this.handledByte = 0;
this.maxByte = 0;
this.getAmountAllocatedLeft = () => this.bufferView.byteLength - this.currentByte;
this.getBufferPosition = () => this.currentByte;
this.getBufferSlice = (begin, end) => this.bufferView.buffer.slice(begin, end);
this.getBufferProgress = () => this.currentByte / this.bufferView.buffer.byteLength;
this.getBufferLength = () => this.bufferView.buffer.byteLength;
this.getBuffer = () => this.bufferView.buffer;
this.alignment = alignment;
this.reset(fileBuffer);
}
reset(newFileBuffer) {
this.fileBuffer = newFileBuffer;
this.bufferView = new DataView(newFileBuffer, 0, Math.min(102400, this.fileBuffer.byteLength));
this.maxByte = newFileBuffer.byteLength;
this.currentByte = 0;
this.handledByte = 0;
}
skipBytes(byteLength = 1) {
this.currentByte += byteLength;
return;
}
readByte() {
return parseInt(this.bufferView.getUint8(this.currentByte++).toString());
}
readBytes(count) {
return new Uint8Array(new Array(count).fill(0).map(pl => this.bufferView.getUint8(this.currentByte++)));
}
uint8ToHexRepresentation(byte) {
return ('0' + byte.toString(16)).slice(-2);
}
readHex(byteLength, hexSeparator = '') {
return Array.from(this.readBytes(byteLength)).map(byte => this.uint8ToHexRepresentation(byte)).join(hexSeparator);
}
readInt8() {
let data = this.bufferView.getInt8(this.currentByte++);
return data;
}
readUint8() {
let data = this.bufferView.getUint8(this.currentByte++);
return data;
}
readInt16() {
let data = this.bufferView.getInt16(this.currentByte, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
this.currentByte += 2;
return data;
}
readUint16() {
let data = this.bufferView.getUint16(this.currentByte, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
this.currentByte += 2;
return data;
}
readInt32() {
let data = this.bufferView.getInt32(this.currentByte, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
this.currentByte += 4;
return data;
}
readUint32() {
let data = this.bufferView.getUint32(this.currentByte, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
this.currentByte += 4;
return data;
}
readLong() {
let data = this.bufferView.getBigInt64(this.currentByte, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
this.currentByte += 8;
return data;
}
readInt64() {
return this.readLong();
}
readUint64() {
let data = this.bufferView.getBigUint64(this.currentByte, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
this.currentByte += 8;
return data;
}
readFloat32() {
let data = this.bufferView.getFloat32(this.currentByte, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
this.currentByte += 4;
return data;
}
readDouble() {
let data = this.bufferView.getFloat64(this.currentByte, this.alignment === alignment_enum_1.Alignment.LITTLE_ENDIAN);
this.currentByte += 8;
return data;
}
readString() {
let strLength = this.readInt32();
let startBytes = this.currentByte;
if (strLength === 0) {
return '';
}
if (strLength > (this.bufferView.buffer.byteLength - this.currentByte)) {
let errorMessage = `Cannot read string of length ${strLength} at position ${this.currentByte} as it exceeds the end at ${this.bufferView.buffer.byteLength}`;
throw new Error(errorMessage);
}
if (strLength < 0) {
const string = new Array(-strLength - 1).fill('').map(c => String.fromCharCode(this.readUint16()));
this.currentByte += 2;
return string.join('');
}
try {
const string = new Array(strLength - 1).fill('').map(c => String.fromCharCode(this.readUint8()));
this.currentByte += 1;
return string.join('');
}
catch (error) {
let errorMessage = `Cannot read UTF8 string of length ${strLength} at position ${this.currentByte}.`;
console.log(errorMessage, error);
throw error;
}
}
allocate(count) {
if (this.currentByte + count < this.bufferView.byteLength) {
console.warn('tried to allocate but there is not enough data left.');
}
return Promise.resolve();
}
}
exports.ByteReader = ByteReader;