This commit is contained in:
Reece Wilson 2019-07-10 17:03:46 +01:00
parent 962e09843a
commit c20e9de42a
7 changed files with 513 additions and 512 deletions

View File

@ -9,11 +9,11 @@ function parseLine(line) {
line = line.substring(0, line.indexOf(';'));
var objs = line.split("\t").join(" ") // convert tabs into spaces
.split(",").join(" ") // convert ,'s into spaces
.split(",").join(" ") // convert ,'s into spaces
.split(":").join("") // get rid of optional :'s
.split("(").join("") // get rid of optional brackets
.split(")").join("") // get rid of optional brackets
.split(" "); // split
.split(" "); // split
var hack = false;

View File

@ -104,10 +104,10 @@ function dmpHeader(_, level, header) {
append(_, level, fmt("LENDIAN\t%s", header.isLE ? "true" : "false"));
append(_, level, "START_NUMBER_SIZES");
level++;
append(_, level, fmt("NUMBER %i", header.numberSize));
append(_, level, fmt("INTEGER %i", header.intSize));
append(_, level, fmt("NUMBER %i", header.numberSize));
append(_, level, fmt("INTEGER %i", header.intSize));
append(_, level, fmt("INSTRUCTION %i", header.instructionSize));
append(_, level, fmt("SIZE_T %i", header.machineSize));
append(_, level, fmt("SIZE_T %i", header.machineSize));
level--;
append(_, level, "END_NUMBER_SIZES");
append(_, level, fmt("FLAGS\t%i", header.platformFlags));

View File

@ -118,7 +118,7 @@ function TypeTUSERDATA() {
}
TypeTUSERDATA.id = 7;
TypeTUSERDATA.tname = "TUSERDATA"; // userdata = unstructured native buffer
TypeTUSERDATA.tname = "TUSERDATA"; // userdata = unstructured native buffer
TypeTUSERDATA.prototype.dump = notImpl; // userdata = unstructured native buffer
TypeTUSERDATA.prototype.undump = notImpl; // userdata = unstructured native buffer

504
index.js
View File

@ -1,325 +1,325 @@
const StreamReader = require("./streamReader.js");
const StreamWriter = require("./streamWriter.js");
const fio = require("fs");
const consts = require("./constants.js");
const insts = require("./instructions.js");
const fmt = require("util").format;
const process = require("process");
const dasm = require("./asm/disassembler.js");
const asm = require("./asm/assembler.js");
const StreamReader = require("./streamReader.js");
const StreamWriter = require("./streamWriter.js");
const fio = require("fs");
const consts = require("./constants.js");
const insts = require("./instructions.js");
const fmt = require("util").format;
const process = require("process");
const dasm = require("./asm/disassembler.js");
const asm = require("./asm/assembler.js");
function Header(ctx) {
this.magic = undefined;
this.version = 0;
//this.nonCompliant = true;
this.isLE = true;
this.intSize = 4;
this.instructionSize = 4;
this.machineSize = 4;
this.numberSize = 4;
this.platformFlags = 0;
this.numOfTypes = 13;
this.sharingMode = 0; // sharing mode (0 - none, 1 - shared, 2 - secure) ? 1 : 0
this.ctx = ctx;
this.magic = undefined;
this.version = 0;
//this.nonCompliant = true;
this.isLE = true;
this.intSize = 4;
this.instructionSize = 4;
this.machineSize = 4;
this.numberSize = 4;
this.platformFlags = 0;
this.numOfTypes = 13;
this.sharingMode = 0; // sharing mode (0 - none, 1 - shared, 2 - secure) ? 1 : 0
this.ctx = ctx;
}
Header.prototype.read = function() {
var buffer = this.ctx.reader.readBytes(false, 14);
this.magic = buffer.readUInt32LE();
this.version = buffer.readUInt8(4);
this.platformFlags = buffer.readUInt8(12); // extensions etc
this.intSize = buffer.readUInt8(7); // sizeOfInt
this.machineSize = buffer.readUInt8(8); // sizeOfSize
this.instructionSize = buffer.readUInt8(9); // sizeOfLuaN
this.numberSize = buffer.readUInt8(10); // sizeOfNumber
var idk = buffer.readUInt8(5); //??
this.isLE = buffer.readUInt8(6) ? true : false;
this.sharingMode = buffer.readUInt8(13) ? true : false;
this.numOfTypes = this.ctx.reader.readInteger();
if (this.numOfTypes != 13) {
console.log("There should only be 13 types");
return false;
}
for (var i in consts.list) {
var type = consts.list[i];
var id = this.ctx.reader.readInteger();
if (id != type.id)
{
console.log(fmt("illegal type index %i expected: %s (%i)", id, type.id, type.name));
return false;
}
var str = this.ctx.reader.readCString();
if (str != type.tname)
{
console.log(fmt("illegal type name %s expected: %s", str, type.tname));
return false;
}
}
return true;
var buffer = this.ctx.reader.readBytes(false, 14);
this.magic = buffer.readUInt32LE();
this.version = buffer.readUInt8(4);
this.platformFlags = buffer.readUInt8(12); // extensions etc
this.intSize = buffer.readUInt8(7); // sizeOfInt
this.machineSize = buffer.readUInt8(8); // sizeOfSize
this.instructionSize = buffer.readUInt8(9); // sizeOfLuaN
this.numberSize = buffer.readUInt8(10); // sizeOfNumber
var idk = buffer.readUInt8(5); //??
this.isLE = buffer.readUInt8(6) ? true : false;
this.sharingMode = buffer.readUInt8(13) ? true : false;
this.numOfTypes = this.ctx.reader.readInteger();
if (this.numOfTypes != 13) {
console.log("There should only be 13 types");
return false;
}
for (var i in consts.list) {
var type = consts.list[i];
var id = this.ctx.reader.readInteger();
if (id != type.id)
{
console.log(fmt("illegal type index %i expected: %s (%i)", id, type.id, type.name));
return false;
}
var str = this.ctx.reader.readCString();
if (str != type.tname)
{
console.log(fmt("illegal type name %s expected: %s", str, type.tname));
return false;
}
}
return true;
}
Header.prototype.write = function(ctx) {
this.ctx.writer.writeUByte(0x1B);
this.ctx.writer.writeUByte(0x4C); //L
this.ctx.writer.writeUByte(0x75); //U
this.ctx.writer.writeUByte(0x61); //A
this.ctx.writer.writeUByte(0x1B);
this.ctx.writer.writeUByte(0x4C); //L
this.ctx.writer.writeUByte(0x75); //U
this.ctx.writer.writeUByte(0x61); //A
this.ctx.writer.writeUByte(this.version);
this.ctx.writer.writeUByte(13); // ???
this.ctx.writer.writeUByte(this.isLE ? 1 : 0);
this.ctx.writer.writeUByte(this.version);
this.ctx.writer.writeUByte(13); // ???
this.ctx.writer.writeUByte(this.isLE ? 1 : 0);
this.ctx.writer.writeUByte(this.intSize);
this.ctx.writer.writeUByte(this.machineSize);
this.ctx.writer.writeUByte(this.instructionSize);
this.ctx.writer.writeUByte(this.numberSize);
this.ctx.writer.writeUByte(this.intSize);
this.ctx.writer.writeUByte(this.machineSize);
this.ctx.writer.writeUByte(this.instructionSize);
this.ctx.writer.writeUByte(this.numberSize);
this.ctx.writer.writeUByte(0); //TODO
this.ctx.writer.writeUByte(this.platformFlags);
this.ctx.writer.writeUByte(this.sharingMode ? 1 : 0);
this.ctx.writer.writeInteger(this.numOfTypes);
consts.list.forEach((type) => {
this.ctx.writer.writeInteger(type.id);
this.ctx.writer.writeCString(type.tname);
});
this.ctx.writer.writeUByte(0); //TODO
this.ctx.writer.writeUByte(this.platformFlags);
this.ctx.writer.writeUByte(this.sharingMode ? 1 : 0);
this.ctx.writer.writeInteger(this.numOfTypes);
consts.list.forEach((type) => {
this.ctx.writer.writeInteger(type.id);
this.ctx.writer.writeCString(type.tname);
});
}
function Debug(ctx, method) {
this.ctx = ctx;
this.method = method;
this.type = 0;
this.data = {};
this.ctx = ctx;
this.method = method;
this.type = 0;
this.data = {};
}
Debug.prototype.read = function() {
this.type = this.ctx.reader.readInteger();
if (this.type == 1) {
this.data["unknown"] = this.ctx.reader.readInteger();
} else if (this.type == 0) {
return;
} else if (this.type == 40) { //implemented in t6
//TODO:
} else if (this.type == 0x48) {
/*
hks::BytecodeWriter::dumpInt(this, 0x48);
hks::BytecodeWriter::dumpInt(v6, v5->m_debug->line_defined);
hks::BytecodeWriter::dumpInt(v6, v5->m_debug->last_line_defined);
if ( v4 )
v8 = 0i64;
else
v8 = v5->m_debug->source;
hks::BytecodeWriter::dumpString(v6, v8);
hks::BytecodeWriter::dumpString(v6, v5->m_debug->name);
hks::BytecodeWriter::dumpVector<hksInstruction>(v6, 0i64, 0i64, 0);
hks::BytecodeWriter::dumpInt(v6, 0);
hks::BytecodeWriter::dumpInt(v6, 0);
*/
}
this.type = this.ctx.reader.readInteger();
if (this.type == 1) {
this.data["unknown"] = this.ctx.reader.readInteger();
} else if (this.type == 0) {
} else if (this.type == 40) { //implemented in t6
//TODO:
} else if (this.type == 0x48) {
/*
hks::BytecodeWriter::dumpInt(this, 0x48);
hks::BytecodeWriter::dumpInt(v6, v5->m_debug->line_defined);
hks::BytecodeWriter::dumpInt(v6, v5->m_debug->last_line_defined);
if ( v4 )
v8 = 0i64;
else
v8 = v5->m_debug->source;
hks::BytecodeWriter::dumpString(v6, v8);
hks::BytecodeWriter::dumpString(v6, v5->m_debug->name);
hks::BytecodeWriter::dumpVector<hksInstruction>(v6, 0i64, 0i64, 0);
hks::BytecodeWriter::dumpInt(v6, 0);
hks::BytecodeWriter::dumpInt(v6, 0);
*/
}
}
Debug.prototype.write = function() {
this.ctx.writer.writeInteger(this.type);
if (this.type == 1) {
this.ctx.writer.writeInteger(this.data["unknown"]);
} else if (this.type == 0) {
return;
} else if (this.type == 40) { //implemented in t6 - but seemingly unused
//TODO:
} else if (this.type == 0x48) {
//TODO:
}
this.ctx.writer.writeInteger(this.type);
if (this.type == 1) {
this.ctx.writer.writeInteger(this.data["unknown"]);
} else if (this.type == 0) {
return;
} else if (this.type == 40) { //implemented in t6 - but seemingly unused
//TODO:
} else if (this.type == 0x48) {
//TODO:
}
}
function Constants(ctx, method) {
this.ctx = ctx;
this.method = method;
this.objs = [];
this.ctx = ctx;
this.method = method;
this.objs = [];
}
Constants.prototype.read = function() {
var size = this.ctx.reader.readMachine();
for (var i = 0; i < size; i++) {
//console.log("reading constant at " + this.ctx.reader.index);
var id = this.ctx.reader.readUByte();
var type = consts.byId[id];
if (!type) {
console.log("illegal constant type " + id);
return false;
}
var inst = new type();
inst.undump(this.ctx.reader, this.ctx);
this.objs.push(inst);
}
return true;
var size = this.ctx.reader.readMachine();
for (var i = 0; i < size; i++) {
//console.log("reading constant at " + this.ctx.reader.index);
var id = this.ctx.reader.readUByte();
var type = consts.byId[id];
if (!type) {
console.log("illegal constant type " + id);
return false;
}
var inst = new type();
inst.undump(this.ctx.reader, this.ctx);
this.objs.push(inst);
}
return true;
}
Constants.prototype.write = function() {
this.ctx.writer.writeMachine(this.objs.length);
this.objs.forEach((obj) => {
this.ctx.writer.writeUByte(obj.id);
obj.dump(this.ctx.writer, this.ctx);
});
this.ctx.writer.writeMachine(this.objs.length);
this.objs.forEach((obj) => {
this.ctx.writer.writeUByte(obj.id);
obj.dump(this.ctx.writer, this.ctx);
});
}
function Method(ctx) {
this.ctx = ctx;
this.debug = new Debug(ctx, this);
this.constants = new Constants(ctx, this);
this.upvals = 0;
this.params = 0;
this.flags = 0;
this.registers = 0;
this.code = [];
this.decoded = [];
this.closures = [];
this.ctx = ctx;
this.debug = new Debug(ctx, this);
this.constants = new Constants(ctx, this);
this.upvals = 0;
this.params = 0;
this.flags = 0;
this.registers = 0;
this.code = [];
this.decoded = [];
this.closures = [];
}
Method.prototype.read = function() {
this.upvals = this.ctx.reader.readInteger();
this.params = this.ctx.reader.readInteger();
this.flags = this.ctx.reader.readUByte();
this.registers = this.ctx.reader.readInteger();
if (this.ctx.header.sharingMode) {
console.log("illegal sharing mode");
return;
}
this.code = this.ctx.reader.readVectorDWORD();
this.parseInstructions();
this.upvals = this.ctx.reader.readInteger();
this.params = this.ctx.reader.readInteger();
this.flags = this.ctx.reader.readUByte();
this.registers = this.ctx.reader.readInteger();
if (this.ctx.header.sharingMode) {
console.log("illegal sharing mode");
return;
}
this.code = this.ctx.reader.readVectorDWORD();
this.parseInstructions();
this.constants.read();
this.debug.read();
this.constants.read();
this.debug.read();
var items = this.ctx.reader.readInteger();
var items = this.ctx.reader.readInteger();
for (var i = 0; i < items; i++){
var methods = new Method(this.ctx);
this.closures.push(methods);
methods.read();
}
for (var i = 0; i < items; i++){
var methods = new Method(this.ctx);
this.closures.push(methods);
methods.read();
}
}
Method.prototype.write = function() {
this.ctx.writer.writeInteger(this.upvals);
this.ctx.writer.writeInteger(this.params);
this.ctx.writer.writeUByte(this.flags);
this.ctx.writer.writeInteger(this.registers);
if (this.ctx.header.sharingMode) {
console.log("illegal sharing mode");
return;
}
this.ctx.writer.writeVectorDWORD(this.code);
this.constants.write();
this.debug.write();
this.ctx.writer.writeInteger(this.upvals);
this.ctx.writer.writeInteger(this.params);
this.ctx.writer.writeUByte(this.flags);
this.ctx.writer.writeInteger(this.registers);
if (this.ctx.header.sharingMode) {
console.log("illegal sharing mode");
return;
}
this.ctx.writer.writeVectorDWORD(this.code);
this.constants.write();
this.debug.write();
this.ctx.writer.writeInteger(this.closures.length);
this.closures.forEach((closure) => {
closure.write();
});
this.ctx.writer.writeInteger(this.closures.length);
this.closures.forEach((closure) => {
closure.write();
});
}
Method.prototype.parseInstructions = function() {
this.code.forEach((code) => {
var data = {};
var I = insts.getOp(code);
var instruction = insts.instructionById[I];
if (!instruction) {
console.log(fmt("WTF... ILLEGAL INSTRUCTION [index: %i]", I));
return;
}
data.I = I;
data.instruction = instruction;
if (instruction.type == insts.instructionTypes.iABC) {
var temp = insts.decodeABC(code);
data.a = temp.a;
data.b = temp.b;
data.c = temp.c;
} else if (instruction.type == insts.instructionTypes.iABx) {
var temp = insts.decodeABx(code);
data.a = temp.a;
data.b = temp.b;
} else if (instruction.type == insts.instructionTypes.iAsBx) {
var temp = insts.decodeAsBx(code);
data.a = temp.a;
data.b = temp.b;
} else {
console.log("WTF... ILLEGAL INSTRUCTION");
}
this.decoded.push(data);
});
this.code.forEach((code) => {
var data = {};
var I = insts.getOp(code);
var instruction = insts.instructionById[I];
if (!instruction) {
console.log(fmt("WTF... ILLEGAL INSTRUCTION [index: %i]", I));
return;
}
data.I = I;
data.instruction = instruction;
if (instruction.type == insts.instructionTypes.iABC) {
var temp = insts.decodeABC(code);
data.a = temp.a;
data.b = temp.b;
data.c = temp.c;
} else if (instruction.type == insts.instructionTypes.iABx) {
var temp = insts.decodeABx(code);
data.a = temp.a;
data.b = temp.b;
} else if (instruction.type == insts.instructionTypes.iAsBx) {
var temp = insts.decodeAsBx(code);
data.a = temp.a;
data.b = temp.b;
} else {
console.log("WTF... ILLEGAL INSTRUCTION");
}
this.decoded.push(data);
});
}
function Context() {
this.types = consts;
this.header = new Header(this);
this.mainMethod = new Method(this);
this.reader = undefined;
this.writer = undefined;
this.types = consts;
this.header = new Header(this);
this.mainMethod = new Method(this);
this.reader = undefined;
this.writer = undefined;
}
Context.prototype.fromBuffer = function(buf) {
this.reader = new StreamReader(buf, this);
this.header.read();
this.mainMethod.read();
this.reader = new StreamReader(buf, this);
this.header.read();
this.mainMethod.read();
}
Context.prototype.fromFile = function(file) {
this.fromBuffer(fio.readFileSync(file));
this.fromBuffer(fio.readFileSync(file));
}
Context.prototype.save = function(file) {
this.writer = new StreamWriter(this);
this.header.write();
this.mainMethod.write();
this.writer.shrink();
if (file)
fio.writeFileSync(file, this.writer.buffer);
this.writer = new StreamWriter(this);
this.header.write();
this.mainMethod.write();
this.writer.shrink();
if (file)
fio.writeFileSync(file, this.writer.buffer);
}
Context.prototype.disassembleStdout = function() {
var buffer = {msg: ""};
dasm.dsmContext(buffer, this);
process.stdout.write(buffer.msg);
var buffer = {msg: ""};
dasm.dsmContext(buffer, this);
process.stdout.write(buffer.msg);
}
Context.prototype.disassembleFile = function(file) {
var buffer = {msg: ""};
dasm.dsmContext(buffer, this);
fio.writeFileSync(file, buffer.msg);
var buffer = {msg: ""};
dasm.dsmContext(buffer, this);
fio.writeFileSync(file, buffer.msg);
}
Context.prototype.assemble = function(str) {
asm.asmContext(str, this);
asm.asmContext(str, this);
}
Context.prototype.assembleFile = function(file) {
this.assemble(fio.readFileSync(file, "utf8"));
this.assemble(fio.readFileSync(file, "utf8"));
}
module.exports = {
Context: Context,
Method: Method,
Constants: Constants,
Debug: Debug,
Header: Header,
constants: consts,
instructions: insts
Context: Context,
Method: Method,
Constants: Constants,
Debug: Debug,
Header: Header,
constants: consts,
instructions: insts
}

View File

@ -1,79 +1,80 @@
const opcodes = require("./instructions_a.js");
var instructionById = {};
var instructionByName = {};
const opcodes = require("./instructions_a.js");
const e_iABC = 0;
const e_iABx = 1;
const e_iAsBx = 2;
const e_iABC = 0;
const e_iABx = 1;
const e_iAsBx = 2;
const itypes = { "iABC": e_iABC,
"iABx": e_iABx,
"iAsBx": e_iAsBx };
const itypes = { "iABC": e_iABC,
"iABx": e_iABx,
"iAsBx": e_iAsBx };
var instructionById = {};
var instructionByName = {};
opcodes.forEach((obj) => {
instructionById[obj.opcode] = obj;
instructionById[obj.opcode] = obj;
});
opcodes.forEach((obj) => {
instructionByName[obj.name] = obj;
instructionByName[obj.name] = obj;
});
function getOp(code) {
return (code >>> 25) & 0x7f;
return (code >>> 25) & 0x7f;
}
function encodeABC(I, a, b, c) {
var code = 0;
code |= ((a & 0xFF ) << 0 ) & 0x000000FF;
code |= ((b & 0xFF ) << 17) & 0x03FE0000; // havok script: b = 8 bits? uh okay
code |= ((c & 0x1FF) << 8 ) & 0x0001FF00;
code |= ((I & 0x7f ) << 25) & 0xFE000000;
return code;
var code = 0;
code |= ((a & 0xFF ) << 0 ) & 0x000000FF;
code |= ((b & 0xFF ) << 17) & 0x03FE0000; // havok script: b = 8 bits? uh okay
code |= ((c & 0x1FF) << 8 ) & 0x0001FF00;
code |= ((I & 0x7f ) << 25) & 0xFE000000;
return code;
}
function decodeABC(code) {
var I = (code >>> 25) & 0x3F;
var a = (code ) & 0xFF;
var b = (code >>> 17) & 0xFF;
var c = (code >>> 8 ) & 0x1FF;
return {I: I, a: a, b: b, c: c};
var I = (code >>> 25) & 0x3F;
var a = (code ) & 0xFF;
var b = (code >>> 17) & 0xFF;
var c = (code >>> 8 ) & 0x1FF;
return {I: I, a: a, b: b, c: c};
}
function encodeABx(I, a, b) {
var code = 0;
code |= ((I & 0x7f ) << 25) & 0xFE000000;
code |= ((b & 0x1FFFF) << 8) & 0x01FFFF00; // havok script: b = 17 bits? uh okay
code |= ((a & 0xFF ) << 0) & 0x000000FF;
return code;
var code = 0;
code |= ((I & 0x7f ) << 25) & 0xFE000000;
code |= ((b & 0x1FFFF) << 8) & 0x01FFFF00; // havok script: b = 17 bits? uh okay
code |= ((a & 0xFF ) << 0) & 0x000000FF;
return code;
}
function decodeABx(code) {
var I = (code >>> 25) & 0x7f;
var a = (code ) & 0xFF;
var b = (code >>> 8 ) & 0x1FFFF;
return {I: I, a: a, b: b};
var I = (code >>> 25) & 0x7f;
var a = (code ) & 0xFF;
var b = (code >>> 8 ) & 0x1FFFF;
return {I: I, a: a, b: b};
}
function encodeAsBx(I, a, b) {
return encodeABx(I, a, b + 65535);
return encodeABx(I, a, b + 65535);
}
function decodeAsBx(code) {
var ah = decodeABx(code);
ah.b = ah.b - 65535;
return ah;
var ah = decodeABx(code);
ah.b = ah.b - 65535;
return ah;
}
module.exports = {
getOp: getOp,
encodeABC: encodeABC,
decodeABC: decodeABC,
encodeABx: encodeABx,
decodeABx: decodeABx,
encodeAsBx: encodeAsBx,
decodeAsBx: decodeAsBx,
instructions: opcodes,
instructionById: instructionById,
instructionByName: instructionByName,
instructionTypes: itypes
getOp: getOp,
encodeABC: encodeABC,
decodeABC: decodeABC,
encodeABx: encodeABx,
decodeABx: decodeABx,
encodeAsBx: encodeAsBx,
decodeAsBx: decodeAsBx,
instructions: opcodes,
instructionById: instructionById,
instructionByName: instructionByName,
instructionTypes: itypes
};

View File

@ -1,117 +1,117 @@
const iset = require("./instructions.js");
function Reader(buffer, ctx) {
this.buffer = buffer;
this.index = 0;
this.ctx = ctx;
this.buffer = buffer;
this.index = 0;
this.ctx = ctx;
}
Reader.prototype.readBytes = function(peak, length){
var buf = this.buffer.slice(this.index, this.index + length);
if (peak)
return buf;
this.index += length;
return buf;
var buf = this.buffer.slice(this.index, this.index + length);
if (peak)
return buf;
this.index += length;
return buf;
}
Reader.prototype.readCString = function() {
var length = undefined;
var str = undefined;
length = this.buffer.readUInt32LE(this.index);
this.index += 4;
if (!length) return "";
str = this.buffer.slice(this.index, this.index + length - 1).toString('utf8');
this.index += length;
return str;
Reader.prototype.readCString = function() {
var length = undefined;
var str = undefined;
length = this.buffer.readUInt32LE(this.index);
this.index += 4;
if (!length) return "";
str = this.buffer.slice(this.index, this.index + length - 1).toString('utf8');
this.index += length;
return str;
}
Reader.prototype.readUByte = function(peak) {
var i = this.buffer.readUInt8(this.index);
if (peak)
return i;
this.index += 1;
return i;
Reader.prototype.readUByte = function(peak) {
var i = this.buffer.readUInt8(this.index);
if (peak)
return i;
this.index += 1;
return i;
}
Reader.prototype.readByte = function(peak) {
var i = this.buffer.readInt8(this.index);
if (peak)
return i;
this.index += 1;
return i;
Reader.prototype.readByte = function(peak) {
var i = this.buffer.readInt8(this.index);
if (peak)
return i;
this.index += 1;
return i;
}
Reader.prototype.readNumber = function(peak) {
if (this.ctx.header.numberSize == 4) {
var i = this.ctx.header.isLE ? this.buffer.readFloatLE(this.index) : this.buffer.readFloatBE(this.index);
if (peak)
return i;
this.index += 4;
return i;
}
if (this.ctx.header.numberSize == 8) {
var i = this.ctx.header.isLE ? this.buffer.readDoubleLE(this.index) : this.buffer.readDoubleBE(this.index);
if (peak)
return i;
this.index += 8;
return i;
}
//TODO:
console.log("illegal number size");
return -203;
Reader.prototype.readNumber = function(peak) {
if (this.ctx.header.numberSize == 4) {
var i = this.ctx.header.isLE ? this.buffer.readFloatLE(this.index) : this.buffer.readFloatBE(this.index);
if (peak)
return i;
this.index += 4;
return i;
}
if (this.ctx.header.numberSize == 8) {
var i = this.ctx.header.isLE ? this.buffer.readDoubleLE(this.index) : this.buffer.readDoubleBE(this.index);
if (peak)
return i;
this.index += 8;
return i;
}
//TODO:
console.log("illegal number size");
return -203;
}
Reader.prototype.readMachine = function(peak) {
if (this.ctx.header.machineSize == 4) {
var i = this.ctx.header.isLE ? this.buffer.readUInt32LE(this.index) : this.buffer.readUInt32BE(this.index);
if (peak)
return i;
this.index += 4;
return i;
}
//TODO:
console.log("int64 not supported");
return -203;
Reader.prototype.readMachine = function(peak) {
if (this.ctx.header.machineSize == 4) {
var i = this.ctx.header.isLE ? this.buffer.readUInt32LE(this.index) : this.buffer.readUInt32BE(this.index);
if (peak)
return i;
this.index += 4;
return i;
}
//TODO:
console.log("int64 not supported");
return -203;
}
Reader.prototype.readInstruction = function(peak) {
if (this.ctx.header.instructionSize == 4) {
var i = this.ctx.header.isLE ? this.buffer.readUInt32LE(this.index) : this.buffer.readUInt32BE(this.index);
if (peak)
return i;
this.index += 4;
return i;
}
//TODO:
console.log("int64 not supported");
return -203;
Reader.prototype.readInstruction = function(peak) {
if (this.ctx.header.instructionSize == 4) {
var i = this.ctx.header.isLE ? this.buffer.readUInt32LE(this.index) : this.buffer.readUInt32BE(this.index);
if (peak)
return i;
this.index += 4;
return i;
}
//TODO:
console.log("int64 not supported");
return -203;
}
Reader.prototype.readInteger = function(peak) {
if (this.ctx.header.intSize == 4) {
var i = this.ctx.header.isLE ? this.buffer.readInt32LE(this.index) : this.buffer.readInt32BE(this.index);
if (peak)
return i;
this.index += 4;
return i;
}
//TODO:
console.log("int64 not supported");
return -203;
Reader.prototype.readInteger = function(peak) {
if (this.ctx.header.intSize == 4) {
var i = this.ctx.header.isLE ? this.buffer.readInt32LE(this.index) : this.buffer.readInt32BE(this.index);
if (peak)
return i;
this.index += 4;
return i;
}
//TODO:
console.log("int64 not supported");
return -203;
}
Reader.prototype.readVectorDWORD = function(peak) {
var buffer = [];
var length = this.readMachine();
this.index += ((this.index + 3) & 0xFFFFFFFC) - this.index;
for (var i = 0; i < length; i ++)
buffer[i] = this.readInstruction();
return buffer;
Reader.prototype.readVectorDWORD = function(peak) {
var buffer = [];
var length = this.readMachine();
this.index += ((this.index + 3) & 0xFFFFFFFC) - this.index;
for (var i = 0; i < length; i ++)
buffer[i] = this.readInstruction();
return buffer;
}

View File

@ -1,142 +1,142 @@
const PAGE_SIZE = 1024;
function Writer(ctx) {
this.buffer = Buffer.alloc(1);
this.index = 0;
this.ctx = ctx;
this.buffer = Buffer.alloc(1);
this.index = 0;
this.ctx = ctx;
}
Writer.prototype.expand = function(length) {
var old = this.buffer;
if (!(this.index + length > old.length)) return;
old.copy(this.buffer = Buffer.alloc(this.buffer.length + PAGE_SIZE));
Writer.prototype.expand = function(length) {
var old = this.buffer;
if (!(this.index + length > old.length)) return;
old.copy(this.buffer = Buffer.alloc(this.buffer.length + PAGE_SIZE));
}
Writer.prototype.shrink = function() {
var old = this.buffer;
old.copy(this.buffer = Buffer.alloc(this.index));
Writer.prototype.shrink = function() {
var old = this.buffer;
old.copy(this.buffer = Buffer.alloc(this.index));
}
Writer.prototype.writeCString = function(str) {
this.expand(str.length + 5);
this.buffer.writeUInt32LE(str.length + 1, this.index);
this.index += 4;
Buffer.from(str).copy(this.buffer, this.index);
this.index += str.length;
this.writeUByte(0);
return str;
Writer.prototype.writeCString = function(str) {
this.expand(str.length + 5);
this.buffer.writeUInt32LE(str.length + 1, this.index);
this.index += 4;
Buffer.from(str).copy(this.buffer, this.index);
this.index += str.length;
this.writeUByte(0);
return str;
}
Writer.prototype.writeUByte = function(data) {
this.expand(1);
this.buffer.writeUInt8(data, this.index);
this.index += 1;
Writer.prototype.writeUByte = function(data) {
this.expand(1);
this.buffer.writeUInt8(data, this.index);
this.index += 1;
}
Writer.prototype.writeByte = function(data) {
this.expand(1);
this.buffer.writeInt8(data, this.index);
this.index += 1;
Writer.prototype.writeByte = function(data) {
this.expand(1);
this.buffer.writeInt8(data, this.index);
this.index += 1;
}
Writer.prototype.writeNumber = function(data) {
this.expand(this.ctx.header.numberSize);
if (this.ctx.header.numberSize == 4) {
if (this.ctx.header.isLE)
this.buffer.writeFloatLE(data, this.index);
else
this.buffer.writeFloatBE(data, this.index);
this.index += 4;
return;
}
Writer.prototype.writeNumber = function(data) {
this.expand(this.ctx.header.numberSize);
if (this.ctx.header.numberSize == 4) {
if (this.ctx.header.isLE)
this.buffer.writeFloatLE(data, this.index);
else
this.buffer.writeFloatBE(data, this.index);
this.index += 4;
return;
}
if (this.ctx.header.numberSize == 8) {
if (this.ctx.header.isLE)
this.buffer.writeDoubleLE(data, this.index);
else
this.buffer.writeDoubleBE(data, this.index);
this.index += 8;
return;
}
//TODO:
console.log("illegal number size");
if (this.ctx.header.numberSize == 8) {
if (this.ctx.header.isLE)
this.buffer.writeDoubleLE(data, this.index);
else
this.buffer.writeDoubleBE(data, this.index);
this.index += 8;
return;
}
//TODO:
console.log("illegal number size");
}
Writer.prototype.writeMachine = function(data) {
this.expand(this.ctx.header.machineSize);
if (this.ctx.header.machineSize == 4) {
if (this.ctx.header.isLE)
this.buffer.writeUInt32LE(data, this.index);
else
this.buffer.writeUInt32BE(data, this.index);
this.index += 4;
return;
}
//TODO:
console.log("int64 not supported");
return -203;
Writer.prototype.writeMachine = function(data) {
this.expand(this.ctx.header.machineSize);
if (this.ctx.header.machineSize == 4) {
if (this.ctx.header.isLE)
this.buffer.writeUInt32LE(data, this.index);
else
this.buffer.writeUInt32BE(data, this.index);
this.index += 4;
return;
}
//TODO:
console.log("int64 not supported");
return -203;
}
Writer.prototype.writeInstruction = function(int) {
this.expand(this.ctx.header.instructionSize);
if (this.ctx.header.instructionSize == 4) {
// TODO: reece
// while encoding, our javascript impl may return negative numbers
// this is because javascript wants to read the result as a signed integer rather than our preferred unsigned variant
if (int < 0) {
if (this.ctx.header.isLE)
this.buffer.writeInt32LE(int, this.index);
else
this.buffer.writeInt32BE(int, this.index);
} else {
if (this.ctx.header.isLE)
this.buffer.writeUInt32LE(int, this.index);
else
this.buffer.writeUInt32BE(int, this.index);
}
this.index += 4;
return;
}
//TODO:
console.log("int64 not supported");
return -203;
Writer.prototype.writeInstruction = function(int) {
this.expand(this.ctx.header.instructionSize);
if (this.ctx.header.instructionSize == 4) {
// TODO: reece
// while encoding, our javascript impl may return negative numbers
// this is because javascript wants to read the result as a signed integer rather than our preferred unsigned variant
if (int < 0) {
if (this.ctx.header.isLE)
this.buffer.writeInt32LE(int, this.index);
else
this.buffer.writeInt32BE(int, this.index);
} else {
if (this.ctx.header.isLE)
this.buffer.writeUInt32LE(int, this.index);
else
this.buffer.writeUInt32BE(int, this.index);
}
this.index += 4;
return;
}
//TODO:
console.log("int64 not supported");
return -203;
}
Writer.prototype.writeInteger = function(int) {
this.expand(this.ctx.header.intSize);
if (this.ctx.header.intSize == 4) {
if (this.ctx.header.isLE)
this.buffer.writeInt32LE(int, this.index);
else
this.buffer.writeInt32BE(int, this.index);
this.index += 4;
return;
}
//TODO:
console.log("int64 not supported");
return -203;
Writer.prototype.writeInteger = function(int) {
this.expand(this.ctx.header.intSize);
if (this.ctx.header.intSize == 4) {
if (this.ctx.header.isLE)
this.buffer.writeInt32LE(int, this.index);
else
this.buffer.writeInt32BE(int, this.index);
this.index += 4;
return;
}
//TODO:
console.log("int64 not supported");
return -203;
}
Writer.prototype.writeVectorDWORD = function(array) {
var junk = ((this.index + 3) & 0xFFFFFFFC) - this.index;
this.writeMachine(array.length);
for (var i = 0; i < junk; i ++)
this.writeUByte(0x5F);
for (var i = 0; i < array.length; i ++)
this.writeInstruction(array[i]);
Writer.prototype.writeVectorDWORD = function(array) {
var junk = ((this.index + 3) & 0xFFFFFFFC) - this.index;
this.writeMachine(array.length);
for (var i = 0; i < junk; i ++)
this.writeUByte(0x5F);
for (var i = 0; i < array.length; i ++)
this.writeInstruction(array[i]);
}
module.exports = Writer;